VolumetricLightmap.hx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package hrt.shader;
  2. class VolumetricLightmap extends hxsl.Shader {
  3. static var SRC =
  4. {
  5. function getCoef(shCoords : Vec3, band : Int) : Vec3 {
  6. var u = (shCoords.x + band * lightmapSize.x ) * texelSize.x + texelSize.x / 2.0;
  7. var v = (shCoords.y + shCoords.z * lightmapSize.y) * texelSize.y + texelSize.y / 2.0;
  8. return lightProbeTexture.get(vec2(u, v)).rgb;
  9. }
  10. function getCoefFinal(band : Int) : Vec3 {
  11. var p00 = mix(getCoef(p000, band), getCoef(p100, band), dist.x);
  12. var p01 = mix(getCoef(p001, band), getCoef(p101, band), dist.x);
  13. var p10 = mix(getCoef(p010, band), getCoef(p110, band), dist.x);
  14. var p11 = mix(getCoef(p011, band), getCoef(p111, band), dist.x);
  15. var p0 = mix(p00, p10 , dist.y);
  16. var p1 = mix(p01, p11 , dist.y);
  17. var p = mix(p0, p1 , dist.z);
  18. return p;
  19. }
  20. function computeIrradiance(norm : Vec3) : Vec3 {
  21. // An Efficient Representation for Irradiance Environment Maps
  22. // Ravi Ramamoorthi Pat Hanrahan
  23. var c1 = 0.429043;
  24. var c2 = 0.511664;
  25. var c3 = 0.743125;
  26. var c4 = 0.886227;
  27. var c5 = 0.247708;
  28. var irradiance = vec3(0,0,0);
  29. if (ORDER >= 1){
  30. var L00 = getCoefFinal(0);
  31. irradiance += c4 * L00;
  32. }
  33. if (ORDER >= 2){
  34. var L1n1 = getCoefFinal(1);
  35. var L10 = getCoefFinal(2);
  36. var L11 = getCoefFinal(3);
  37. irradiance += 2 * c2 * (L11 * norm.x + L1n1 * norm.y + L10 * norm.z);
  38. }
  39. if(ORDER >= 3){
  40. var L2n2 = getCoefFinal(4);
  41. var L2n1 = getCoefFinal(5);
  42. var L20 = getCoefFinal(6);
  43. var L21 = getCoefFinal(7);
  44. var L22 = getCoefFinal(8);
  45. irradiance += c1 * L22 * (norm.x*norm.x - norm.y*norm.y) + c3 * L20 * (norm.z * norm.z) - c5 * L20 +
  46. 2 * c1 * (L2n2 * (norm.x*norm.y) + L21 * (norm.x*norm.z) + L2n1 * (norm.y*norm.z));
  47. }
  48. return irradiance / 3.14;
  49. }
  50. function getLightProbeIndex( coords : Vec3 ) : Int {
  51. return int(floor(coords.x + lightmapSize.x * coords.y + lightmapSize.y * lightmapSize.x * coords.z));
  52. }
  53. function getVoxelCoords(pos : Vec3 ) : Vec3 {
  54. posLightmapSpace = (vec4(pos, 1) * lightmapInvPos).xyz;
  55. return floor(posLightmapSpace * (lightmapSize - vec3(1,1,1)));
  56. }
  57. function getLightProbePosition( coords : Vec3 ) : Vec3 {
  58. return coords * voxelSize;
  59. }
  60. function getPixelPosition() : Vec3 {
  61. var uv2 = (screenUV - 0.5) * vec2(2, -2);
  62. var temp = vec4(uv2, depth, 1) * cameraInverseViewProj;
  63. var originWS = temp.xyz / temp.w;
  64. return originWS;
  65. }
  66. function getClampedCoords(coords : Vec3) : Vec3{
  67. return min(lightmapSize - vec3(1,1,1), max( vec3(0,0,0), coords));
  68. }
  69. @const var ORDER : Int;
  70. @param var lightProbeTexture : Sampler2D;
  71. @param var lightmapInvPos : Mat4;
  72. @param var lightmapSize : Vec3;
  73. @param var voxelSize : Vec3;
  74. @param var strength : Float;
  75. @param var cameraInverseViewProj : Mat4;
  76. @param var cameraPos : Vec3;
  77. var transformedPosition : Vec3;
  78. var screenUV : Vec2;
  79. var depth : Float;
  80. var normal : Vec3;
  81. var position : Vec3;
  82. var posLightmapSpace : Vec3;
  83. var voxelCoords : Vec3;
  84. var albedo : Vec3;
  85. var occlusion : Float;
  86. var roughness : Float;
  87. var metalness : Float;
  88. var probeCount : Float;
  89. var coefCount : Float;
  90. var texelSize : Vec2;
  91. var dist : Vec3;
  92. var p000 : Vec3;
  93. var p100 : Vec3;
  94. var p010 : Vec3;
  95. var p001 : Vec3;
  96. var p110 : Vec3;
  97. var p101 : Vec3;
  98. var p011 : Vec3;
  99. var p111 : Vec3;
  100. var output : {
  101. color : Vec4
  102. };
  103. function fragment(){
  104. position = getPixelPosition();
  105. voxelCoords = getVoxelCoords(position);
  106. probeCount = lightmapSize.x * lightmapSize.y * lightmapSize.z;
  107. coefCount = float(ORDER * ORDER);
  108. texelSize = vec2(1/(lightmapSize.x * coefCount), 1/(lightmapSize.y * lightmapSize.z));
  109. if(posLightmapSpace.x < 0 || posLightmapSpace.y < 0 || posLightmapSpace.z < 0 ||
  110. posLightmapSpace.x > 1 || posLightmapSpace.y > 1 || posLightmapSpace.z > 1)
  111. discard;
  112. p000 = getClampedCoords(voxelCoords + vec3(0,0,0));
  113. p100 = getClampedCoords(voxelCoords + vec3(1,0,0));
  114. p010 = getClampedCoords(voxelCoords + vec3(0,1,0));
  115. p001 = getClampedCoords(voxelCoords + vec3(0,0,1));
  116. p110 = getClampedCoords(voxelCoords + vec3(1,1,0));
  117. p101 = getClampedCoords(voxelCoords + vec3(1,0,1));
  118. p011 = getClampedCoords(voxelCoords + vec3(0,1,1));
  119. p111 = getClampedCoords(voxelCoords + vec3(1,1,1));
  120. var voxelPos = (voxelCoords) / (lightmapSize - vec3(1,1,1));
  121. dist = (posLightmapSpace - voxelPos) * (lightmapSize - vec3(1,1,1));
  122. var irradiance : Vec3 = computeIrradiance(normal) * min(vec3(1),albedo) * occlusion;
  123. var NdV = dot(normal, normalize(cameraPos - position));
  124. var F0 = mix(vec3(0.04), albedo, metalness);
  125. var F = F0 + (max(vec3(1 - roughness), F0) - F0) * exp2( ( -5.55473 * NdV - 6.98316) * NdV );
  126. var indirect = (irradiance * (1 - metalness) * (1 - F) ) * strength;
  127. output.color.rgb += indirect;
  128. }
  129. }
  130. }