@meimu/mutracer 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +3 -0
  2. package/dist/assets/bvh.worker.js +1 -1
  3. package/dist/mutracer.umd.js +8949 -7915
  4. package/docs/api.md +42 -21
  5. package/docs/caustics.md +80 -0
  6. package/docs/materials.md +5 -4
  7. package/docs/progressive-rendering.md +50 -9
  8. package/docs/technical/continuous-spectrum.md +93 -0
  9. package/docs/updates.md +3 -1
  10. package/docs/viewer-checklist.md +65 -0
  11. package/docs/viewer.md +7 -5
  12. package/lib/Display.js +1 -1
  13. package/lib/Display.js.map +1 -1
  14. package/lib/Engine.d.ts +2 -0
  15. package/lib/Engine.js +47 -12
  16. package/lib/Engine.js.map +1 -1
  17. package/lib/Render.d.ts +61 -13
  18. package/lib/Render.js +169 -19
  19. package/lib/Render.js.map +1 -1
  20. package/lib/RenderLoop.d.ts +7 -3
  21. package/lib/RenderLoop.js +68 -44
  22. package/lib/RenderLoop.js.map +1 -1
  23. package/lib/main.d.ts +1 -1
  24. package/lib/main.js.map +1 -1
  25. package/lib/oidn.d.ts +1 -1
  26. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  27. package/lib/renderer/GPUTraceQueue.d.ts +2 -1
  28. package/lib/renderer/GPUTraceQueue.js +3 -1
  29. package/lib/renderer/GPUTraceQueue.js.map +1 -1
  30. package/lib/renderer/RenderingPipeline.d.ts +4 -0
  31. package/lib/renderer/RenderingPipeline.js.map +1 -1
  32. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  33. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  34. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  35. package/lib/renderer/WGPUEnvMapDistribution.js +18 -18
  36. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  37. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  38. package/lib/renderer/WGPUPhotonMap.js +191 -0
  39. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  40. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  41. package/lib/renderer/WGPURayTraceOutput.js +122 -28
  42. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  43. package/lib/renderer/WGPURayTracePass.d.ts +48 -17
  44. package/lib/renderer/WGPURayTracePass.js +538 -340
  45. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  46. package/lib/renderer/WGPURenderingPipeline.js +83 -47
  47. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  48. package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
  49. package/lib/renderer/WebGLFullQuadPass.js +4 -0
  50. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  51. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  52. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  53. package/lib/renderer/WebGLRayTracePass.d.ts +6 -1
  54. package/lib/renderer/WebGLRayTracePass.js +43 -6
  55. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  56. package/lib/renderer/WebGLRenderingPipeline.js +10 -14
  57. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  58. package/lib/renderer/WebGLSkyBaker.js +60 -60
  59. package/lib/renderer/accumulationTarget.d.ts +2 -1
  60. package/lib/renderer/accumulationTarget.js.map +1 -1
  61. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  62. package/lib/renderer/causticDiagnostics.js +5 -0
  63. package/lib/renderer/causticDiagnostics.js.map +1 -0
  64. package/lib/renderer/causticEmission.d.ts +10 -0
  65. package/lib/renderer/causticEmission.js +40 -0
  66. package/lib/renderer/causticEmission.js.map +1 -0
  67. package/lib/renderer/causticUniform.d.ts +12 -0
  68. package/lib/renderer/causticUniform.js +22 -0
  69. package/lib/renderer/causticUniform.js.map +1 -0
  70. package/lib/renderer/caustics.d.ts +16 -0
  71. package/lib/renderer/caustics.js +93 -0
  72. package/lib/renderer/caustics.js.map +1 -0
  73. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  74. package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
  75. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  76. package/lib/renderer/glsl/aovTrace.frag.js +33 -33
  77. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
  78. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  79. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  80. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  81. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
  82. package/lib/renderer/glsl/chunks/intersect.glsl.js +426 -428
  83. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  84. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  85. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
  86. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  87. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
  88. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  89. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  90. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  91. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +68 -63
  92. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  93. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
  94. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  95. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  96. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +140 -117
  97. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  98. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
  99. package/lib/renderer/glsl/chunks/sampling.glsl.js +89 -92
  100. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  101. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  102. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  103. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  104. package/lib/renderer/glsl/depthQuery.frag.js +2 -2
  105. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  106. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  107. package/lib/renderer/glsl/rayTrace.frag.js +260 -237
  108. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  109. package/lib/renderer/glsl/shadowCatcher.frag.js +26 -26
  110. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  111. package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
  112. package/lib/renderer/lightSampling.d.ts +3 -2
  113. package/lib/renderer/lightSampling.js +14 -8
  114. package/lib/renderer/lightSampling.js.map +1 -1
  115. package/lib/renderer/progressiveScheduler.js +4 -3
  116. package/lib/renderer/progressiveScheduler.js.map +1 -1
  117. package/lib/renderer/renderPipeline.d.ts +1 -0
  118. package/lib/renderer/renderPipeline.js.map +1 -1
  119. package/lib/renderer/researchTransport.d.ts +31 -0
  120. package/lib/renderer/researchTransport.js +5 -0
  121. package/lib/renderer/researchTransport.js.map +1 -0
  122. package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
  123. package/lib/renderer/sceneLayoutSchema.js +2 -2
  124. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  125. package/lib/renderer/scratchSampling.js +6 -6
  126. package/lib/renderer/spectrum.d.ts +21 -0
  127. package/lib/renderer/spectrum.js +154 -0
  128. package/lib/renderer/spectrum.js.map +1 -0
  129. package/lib/renderer/webglLightSampling.d.ts +39 -0
  130. package/lib/renderer/webglLightSampling.js +15 -0
  131. package/lib/renderer/webglLightSampling.js.map +1 -0
  132. package/lib/renderer/wgpuBindlessSource.js +3 -3
  133. package/lib/renderer/wgpuShaderSource.d.ts +7 -0
  134. package/lib/renderer/wgpuShaderSource.js +2 -0
  135. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  136. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  137. package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
  138. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  139. package/lib/renderer/wgsl/aovResolve.wgsl.js +2 -2
  140. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +1 -1
  141. package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
  142. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  143. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  144. package/lib/renderer/wgsl/causticLight.compute.js +537 -0
  145. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  146. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  147. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  148. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  149. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  150. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  151. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  152. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  153. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  154. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  155. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  156. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  157. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  158. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  159. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
  160. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +598 -592
  161. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  162. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +14 -14
  163. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
  164. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +75 -73
  165. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  166. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +794 -794
  167. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
  168. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  169. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
  170. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +35 -25
  171. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  172. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  173. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
  174. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  175. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  176. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +204 -187
  177. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  178. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  179. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
  180. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  181. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  182. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +89 -93
  183. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  184. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  185. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  186. package/lib/renderer/wgsl/compose.frag.wgsl.js +98 -98
  187. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  188. package/lib/renderer/wgsl/depthQuery.wgsl.js +2 -2
  189. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  190. package/lib/renderer/wgsl/offlineAdaptive.compute.js +25 -25
  191. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  192. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  193. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  194. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  195. package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
  196. package/lib/renderer/wgsl/rayTrace.compute.d.ts +9 -1
  197. package/lib/renderer/wgsl/rayTrace.compute.js +448 -522
  198. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  199. package/lib/scene/MaterialState.d.ts +2 -2
  200. package/lib/scene/MaterialState.js +2 -2
  201. package/lib/scene/MaterialState.js.map +1 -1
  202. package/lib/settings/render.d.ts +11 -0
  203. package/lib/settings/render.js +1 -0
  204. package/lib/settings/render.js.map +1 -1
  205. package/lib/util/fromTHREE.js +2 -2
  206. package/lib/util/fromTHREE.js.map +1 -1
  207. package/lib/version.d.ts +1 -1
  208. package/lib/version.js +1 -1
  209. package/lib/version.js.map +1 -1
  210. package/llms.txt +2 -1
  211. package/package.json +3 -3
@@ -0,0 +1,102 @@
1
+ export default /* wgsl */ `fn di(point: vec3f, height: f32, radius: f32) -> f32 {
2
+ let fQ = length(point);
3
+ if (fQ < 0.00001) {
4
+ return -radius;
5
+ }
6
+
7
+ let iG = radius * point.y / fQ;
8
+ let iq = -1.5 * height;
9
+ var eq: f32;
10
+ if (iG >= 0.0) {
11
+ eq = radius;
12
+ }
13
+ else if (iG < iq) {
14
+ eq = -height * fQ / point.y;
15
+ }
16
+ else {
17
+ let cv = 1.0
18
+ - iG * iG / (3.0 * iq * iq);
19
+ eq = radius * cv;
20
+ }
21
+ return fQ - eq;
22
+ }
23
+
24
+ fn eM(origin: vec3f, direction: vec3f) -> vec3f {
25
+ if (!USE_GROUNDED_BACKGROUND) {
26
+ return direction;
27
+ }
28
+ let params = rtUniform.groundedBackgroundParams;
29
+ let bS = normalize(direction);
30
+ let center = vec3f(
31
+ rtUniform.groundedBackgroundCenter.x,
32
+ params.z + params.x,
33
+ rtUniform.groundedBackgroundCenter.y
34
+ );
35
+ let bs = origin - center;
36
+ let eE = dot(bs, bS);
37
+ let bj = eE * eE
38
+ - dot(bs, bs) + params.y * params.y;
39
+ if (
40
+ bj <= 0.0
41
+ || di(bs, params.x, params.y) > 0.0
42
+ ) {
43
+ return direction;
44
+ }
45
+
46
+ var cw = -eE + sqrt(bj);
47
+ if (cw <= 0.0) {
48
+ return direction;
49
+ }
50
+
51
+ let oA = bs + bS * cw;
52
+ if (oA.y >= 0.0) {
53
+ return normalize(oA);
54
+ }
55
+
56
+ if (bS.y < -0.00001 && params.y > 1.5 * params.x) {
57
+ let hP = (-params.x - bs.y) / bS.y;
58
+ let ot = bs + bS * hP;
59
+ let oT = (2.0 / 3.0)
60
+ * sqrt(params.y * params.y - 2.25 * params.x * params.x);
61
+ if (hP > 0.0 && length(ot.xz) <= oT) {
62
+ return normalize(ot);
63
+ }
64
+ }
65
+
66
+ var cI = 0.0;
67
+ for (var i = 0; i < 14; i++) {
68
+ let fd = (cI + cw) * 0.5;
69
+ let qq = bs + bS * fd;
70
+ if (di(qq, params.x, params.y) > 0.0) {
71
+ cw = fd;
72
+ }
73
+ else {
74
+ cI = fd;
75
+ }
76
+ }
77
+ let hit = bs + bS * ((cI + cw) * 0.5);
78
+ return normalize(hit);
79
+ }
80
+
81
+ fn ft(ray: Ray) -> vec4f {
82
+ var bg = vec4f(0.0);
83
+ if (USE_BACKGROUND_MAP) {
84
+ let d = eM(ray.o, ray.d);
85
+ let t = rtUniform.backgroundMapTransform;
86
+ let qS = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);
87
+ let rotation = rtUniform.backgroundMapRotation;
88
+ let gU = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * qS;
89
+ let aW = textureLinear(backgroundMap, eF(gU));
90
+ bg = vec4f(aW.rgb * t.z, aW.a);
91
+ }
92
+ else if (USE_BACKGROUND) {
93
+ bg = rtUniform.backgroundColor;
94
+ }
95
+ else if (USE_ENVMAP) {
96
+ bg = textureLinear(envMap, cT(ray.d));
97
+ }
98
+ return bg;
99
+ }
100
+
101
+ `;
102
+ //# sourceMappingURL=background.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/background.wgsl.ts"],"names":[],"mappings":"AAAA,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGzB,CAAC","sourcesContent":["export default /* wgsl */ `fn groundedSurfaceDistance(point: vec3f, height: f32, radius: f32) -> f32 {\n let pointLength = length(point);\n if (pointLength < 0.00001) {\n return -radius;\n }\n\n let originalY = radius * point.y / pointLength;\n let transitionY = -1.5 * height;\n var surfaceRadius: f32;\n if (originalY >= 0.0) {\n surfaceRadius = radius;\n }\n else if (originalY < transitionY) {\n surfaceRadius = -height * pointLength / point.y;\n }\n else {\n let factor = 1.0\n - originalY * originalY / (3.0 * transitionY * transitionY);\n surfaceRadius = radius * factor;\n }\n return pointLength - surfaceRadius;\n}\n\nfn groundedBackgroundDirection(origin: vec3f, direction: vec3f) -> vec3f {\n if (!USE_GROUNDED_BACKGROUND) {\n return direction;\n }\n let params = rtUniform.groundedBackgroundParams;\n let rayDirection = normalize(direction);\n let center = vec3f(\n rtUniform.groundedBackgroundCenter.x,\n params.z + params.x,\n rtUniform.groundedBackgroundCenter.y\n );\n let localOrigin = origin - center;\n let projectedOrigin = dot(localOrigin, rayDirection);\n let discriminant = projectedOrigin * projectedOrigin\n - dot(localOrigin, localOrigin) + params.y * params.y;\n if (\n discriminant <= 0.0\n || groundedSurfaceDistance(localOrigin, params.x, params.y) > 0.0\n ) {\n return direction;\n }\n\n var farDistance = -projectedOrigin + sqrt(discriminant);\n if (farDistance <= 0.0) {\n return direction;\n }\n\n let sphereHit = localOrigin + rayDirection * farDistance;\n if (sphereHit.y >= 0.0) {\n return normalize(sphereHit);\n }\n\n if (rayDirection.y < -0.00001 && params.y > 1.5 * params.x) {\n let groundDistance = (-params.x - localOrigin.y) / rayDirection.y;\n let groundHit = localOrigin + rayDirection * groundDistance;\n let groundRadius = (2.0 / 3.0)\n * sqrt(params.y * params.y - 2.25 * params.x * params.x);\n if (groundDistance > 0.0 && length(groundHit.xz) <= groundRadius) {\n return normalize(groundHit);\n }\n }\n\n var nearDistance = 0.0;\n for (var i = 0; i < 14; i++) {\n let middleDistance = (nearDistance + farDistance) * 0.5;\n let middlePoint = localOrigin + rayDirection * middleDistance;\n if (groundedSurfaceDistance(middlePoint, params.x, params.y) > 0.0) {\n farDistance = middleDistance;\n }\n else {\n nearDistance = middleDistance;\n }\n }\n let hit = localOrigin + rayDirection * ((nearDistance + farDistance) * 0.5);\n return normalize(hit);\n}\n\nfn sampleSceneBackground(ray: Ray) -> vec4f {\n var bg = vec4f(0.0);\n if (USE_BACKGROUND_MAP) {\n let d = groundedBackgroundDirection(ray.o, ray.d);\n let t = rtUniform.backgroundMapTransform;\n let backgroundDirection = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);\n let rotation = rtUniform.backgroundMapRotation;\n let mapDirection = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * backgroundDirection;\n let backgroundSample = textureLinear(backgroundMap, cartesianToEquirect(mapDirection));\n bg = vec4f(backgroundSample.rgb * t.z, backgroundSample.a);\n }\n else if (USE_BACKGROUND) {\n bg = rtUniform.backgroundColor;\n }\n else if (USE_ENVMAP) {\n bg = textureLinear(envMap, environmentUv(ray.d));\n }\n return bg;\n}\n\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const _default: "\nfn causticAdjoint(view:vec3f,outgoing:vec3f,shading:vec3f,geometric:vec3f)->f32 {\n let numerator=abs(dot(view,shading)*dot(outgoing,geometric));\n let denominator=abs(dot(view,geometric)*dot(outgoing,shading));\n if(denominator==0.0){return 0.0;}\n return numerator/denominator;\n}\n";
2
+ export default _default;
@@ -0,0 +1,12 @@
1
+ // Veach's adjoint shading-normal ratio. Directions point away from the vertex;
2
+ // view is toward the preceding light vertex, outgoing toward the camera.
3
+ // Reference: Veach 1997, thesis section 5.3 (mathematical formula, no copied code).
4
+ export default /* wgsl */ `
5
+ fn causticAdjoint(view:vec3f,vJ:vec3f,shading:vec3f,geometric:vec3f)->f32 {
6
+ let iF=abs(dot(view,shading)*dot(vJ,geometric));
7
+ let ah=abs(dot(view,geometric)*dot(vJ,shading));
8
+ if(ah==0.0){return 0.0;}
9
+ return iF/ah;
10
+ }
11
+ `;
12
+ //# sourceMappingURL=causticAdjoint.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticAdjoint.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/causticAdjoint.wgsl.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,yEAAyE;AACzE,oFAAoF;AACpF,eAAe,UAAU,CAAC;;;;;;;CAOzB,CAAC","sourcesContent":["// Veach's adjoint shading-normal ratio. Directions point away from the vertex;\n// view is toward the preceding light vertex, outgoing toward the camera.\n// Reference: Veach 1997, thesis section 5.3 (mathematical formula, no copied code).\nexport default /* wgsl */ `\nfn causticAdjoint(view:vec3f,outgoing:vec3f,shading:vec3f,geometric:vec3f)->f32 {\n let numerator=abs(dot(view,shading)*dot(outgoing,geometric));\n let denominator=abs(dot(view,geometric)*dot(outgoing,shading));\n if(denominator==0.0){return 0.0;}\n return numerator/denominator;\n}\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const _default: "\nfn causticAtomicAdd(index:u32,value:f32) {\n if(!(value>0.0)||!(value<3.402823e38)){return;}\n var previous=atomicLoad(&splats[index]);\n loop {\n let sum=bitcast<f32>(previous)+value;\n let replacement=bitcast<u32>(sum);\n let result=atomicCompareExchangeWeak(&splats[index],previous,replacement);\n if(result.exchanged){break;}\n previous=result.old_value;\n }\n}\n";
2
+ export default _default;
@@ -0,0 +1,16 @@
1
+ // Float32 addition implemented with u32 compare/exchange works on baseline
2
+ // WebGPU, without a fixed radiance quantum or the Q16.16 saturation ceiling.
3
+ export default /* wgsl */ `
4
+ fn kM(index:u32,value:f32) {
5
+ if(!(value>0.0)||!(value<3.402823e38)){return;}
6
+ var previous=atomicLoad(&splats[index]);
7
+ loop {
8
+ let sum=bitcast<f32>(previous)+value;
9
+ let vN=bitcast<u32>(sum);
10
+ let result=atomicCompareExchangeWeak(&splats[index],previous,vN);
11
+ if(result.exchanged){break;}
12
+ previous=result.old_value;
13
+ }
14
+ }
15
+ `;
16
+ //# sourceMappingURL=causticAtomic.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticAtomic.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/causticAtomic.wgsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,eAAe,UAAU,CAAC;;;;;;;;;;;;CAYzB,CAAC","sourcesContent":["// Float32 addition implemented with u32 compare/exchange works on baseline\n// WebGPU, without a fixed radiance quantum or the Q16.16 saturation ceiling.\nexport default /* wgsl */ `\nfn causticAtomicAdd(index:u32,value:f32) {\n if(!(value>0.0)||!(value<3.402823e38)){return;}\n var previous=atomicLoad(&splats[index]);\n loop {\n let sum=bitcast<f32>(previous)+value;\n let replacement=bitcast<u32>(sum);\n let result=atomicCompareExchangeWeak(&splats[index],previous,replacement);\n if(result.exchanged){break;}\n previous=result.old_value;\n }\n}\n`;\n"]}
@@ -0,0 +1 @@
1
+ export declare function causticPartitionWGSL(mnee: boolean, lightTracing: boolean, photonMapping?: boolean, mneeMaxDepth?: number, hot?: boolean, photonMaxDepth?: number): string;
@@ -0,0 +1,62 @@
1
+ // Smooth classification is independent of the sampled lobe. The single-vertex
2
+ // marker records either an eligible delta transmission or a smooth reflection.
3
+ export function causticPartitionWGSL(mnee, lightTracing, photonMapping = false, mneeMaxDepth = 20, hot = false, photonMaxDepth = 20) {
4
+ return /* wgsl */ `
5
+ fn causticDim(slot:u32)->u32{return 1048576u+samplingBounce*4096u+slot;}
6
+ fn isCausticSpecular(m: OpenPbrResolvedMaterial) -> bool {
7
+ return m.baseWeight * (1.0 - m.baseMetalness) * (1.0 - m.transmissionWeight) <= 1e-6 &&
8
+ m.subsurfaceWeight <= 0.0 && m.fuzzWeight <= 0.0 && m.coatWeight <= 0.0 && m.causticRoughness <= 0.1;
9
+ }
10
+ fn isCausticT(m: OpenPbrResolvedMaterial) -> bool {
11
+ return isCausticSpecular(m) && m.transmissionWeight == 1.0 && m.causticRoughness == 0.0 && !m.thinWalled && !m.causticNormalMapped && m.alpha>=1.0;
12
+ }
13
+ fn isCausticR(m:OpenPbrResolvedMaterial)->bool{
14
+ return isCausticSpecular(m)&&m.causticRoughness==0.0&&!m.causticNormalMapped&&m.alpha>=1.0;
15
+ }
16
+ fn causticHitOwned(path: Path, xd: bool, vl: bool) -> bool {
17
+ let r1 = ${mnee} && xd && path.causticMneeReceiver && path.causticK == 1u && path.causticSingleT;
18
+ let r2 = ${lightTracing} && vl && path.causticK > 0u && path.causticReceiverPrimary;
19
+ let r3=${photonMapping}&&path.causticPhotonReceiver&&path.causticK>0u;
20
+ return path.causticHasReceiver && (r1 || r2 || r3);
21
+ }
22
+
23
+ var<private> causticHot:array<vec3f,15>;
24
+ fn causticHotRecord(path:Path,emission:vec3f,kind:u32){
25
+ if(!${hot}){return;}
26
+ let value=max(max(path.beta.x*emission.x,path.beta.y*emission.y),path.beta.z*emission.z);
27
+ if(value<=100.0){return;}
28
+ causticHot[9][kind]+=1.0;
29
+ causticHot[0]+=vec3f(1.0,f32(samplingBounce),f32(path.causticK));
30
+ causticHot[1]+=vec3f(select(0.0,1.0,path.causticHasReceiver),select(0.0,1.0,path.causticSingleT),select(0.0,1.0,path.causticReceiverPrimary));
31
+ causticHot[2]+=vec3f(select(0.0,1.0,path.causticMneeReceiver),select(0.0,1.0,path.causticPhotonReceiver),value);
32
+ if(samplingBounce>=3u&&samplingBounce<=8u){causticHot[samplingBounce]+=vec3f(1.0,f32(path.causticK),value);}
33
+ }
34
+ fn causticEstimateRecord(value:vec3f,kind:u32){
35
+ if(!${hot}){return;}
36
+ let peak=max(max(value.x,value.y),value.z);if(peak>100.0){causticHot[10u+kind]+=vec3f(1.0,f32(samplingBounce),peak);}
37
+ }
38
+ fn causticEmitterRecord(si:SurfaceInteraction,path:Path,weight:f32,emission:vec3f){
39
+ if(!${hot}){return;}
40
+ let value=path.beta*weight*emission;if(max(max(value.x,value.y),value.z)<=100.0){return;}
41
+ let material=materialsBuffer[si.materialIndex];
42
+ causticHot[12]+=vec3f(1.0+dot(si.faceNormal,-path.ray.d),select(0.0,1.0,path.fromEye),material.doubleSided);
43
+ causticHot[13]+=vec3f(weight,material.matType,rtUniform.lightWeightTotal);
44
+ causticHot[14]+=vec3f(path.scatteringPdf,dot(material.emission,luminance),max(max(path.beta.x,path.beta.y),path.beta.z));
45
+ }
46
+ fn causticAdvance(path: ptr<function, Path>, m: OpenPbrResolvedMaterial, transmission: bool, surface: bool) {
47
+ if (surface && isCausticSpecular(m)) {
48
+ (*path).causticK++;
49
+ (*path).causticSingleT = (*path).causticK == 1u && ((isCausticT(m) && transmission)||(isCausticR(m)&&!transmission));
50
+ } else {
51
+ (*path).causticK = 0u;
52
+ (*path).causticSingleT = false;
53
+ (*path).causticPhotonReceiver=surface&&samplingBounce<=${photonMaxDepth}u&&m.materialType!=SHADOW_CATCHER;
54
+ (*path).causticHasReceiver = m.materialType != SHADOW_CATCHER;
55
+ (*path).causticMneeReceiver = surface && samplingBounce<=${mneeMaxDepth}u &&
56
+ m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0 && m.subsurfaceWeight==0.0;
57
+ (*path).causticReceiverPrimary = (*path).fromEye && surface;
58
+ }
59
+ }
60
+ `;
61
+ }
62
+ //# sourceMappingURL=caustics.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caustics.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/caustics.wgsl.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,IAAa,EAAE,YAAqB,EAAC,aAAa,GAAC,KAAK,EAAC,YAAY,GAAC,EAAE,EAAC,GAAG,GAAC,KAAK,EAAC,cAAc,GAAC,EAAE;IACvI,OAAO,UAAU,CAAC;;;;;;;;;;;;;WAaP,IAAI;WACJ,YAAY;SACd,aAAa;;;;;;MAMjB,GAAG;;;;;;;;;;MAUH,GAAG;;;;MAIH,GAAG;;;;;;;;;;;;;;yDAcmD,cAAc;;2DAEZ,YAAY;;;;;CAK1E,CAAC;AACF,CAAC","sourcesContent":["// Smooth classification is independent of the sampled lobe. The single-vertex\n// marker records either an eligible delta transmission or a smooth reflection.\nexport function causticPartitionWGSL(mnee: boolean, lightTracing: boolean,photonMapping=false,mneeMaxDepth=20,hot=false,photonMaxDepth=20) {\n return /* wgsl */ `\nfn causticDim(slot:u32)->u32{return 1048576u+samplingBounce*4096u+slot;}\nfn isCausticSpecular(m: OpenPbrResolvedMaterial) -> bool {\n return m.baseWeight * (1.0 - m.baseMetalness) * (1.0 - m.transmissionWeight) <= 1e-6 &&\n m.subsurfaceWeight <= 0.0 && m.fuzzWeight <= 0.0 && m.coatWeight <= 0.0 && m.causticRoughness <= 0.1;\n}\nfn isCausticT(m: OpenPbrResolvedMaterial) -> bool {\n return isCausticSpecular(m) && m.transmissionWeight == 1.0 && m.causticRoughness == 0.0 && !m.thinWalled && !m.causticNormalMapped && m.alpha>=1.0;\n}\nfn isCausticR(m:OpenPbrResolvedMaterial)->bool{\n return isCausticSpecular(m)&&m.causticRoughness==0.0&&!m.causticNormalMapped&&m.alpha>=1.0;\n}\nfn causticHitOwned(path: Path, mneeLight: bool, tracingLight: bool) -> bool {\n let r1 = ${mnee} && mneeLight && path.causticMneeReceiver && path.causticK == 1u && path.causticSingleT;\n let r2 = ${lightTracing} && tracingLight && path.causticK > 0u && path.causticReceiverPrimary;\n let r3=${photonMapping}&&path.causticPhotonReceiver&&path.causticK>0u;\n return path.causticHasReceiver && (r1 || r2 || r3);\n}\n// Private evidence images count only unsuppressed PT contributions above 100 after MIS.\nvar<private> causticHot:array<vec3f,15>;\nfn causticHotRecord(path:Path,emission:vec3f,kind:u32){\n if(!${hot}){return;}\n let value=max(max(path.beta.x*emission.x,path.beta.y*emission.y),path.beta.z*emission.z);\n if(value<=100.0){return;}\n causticHot[9][kind]+=1.0;\n causticHot[0]+=vec3f(1.0,f32(samplingBounce),f32(path.causticK));\n causticHot[1]+=vec3f(select(0.0,1.0,path.causticHasReceiver),select(0.0,1.0,path.causticSingleT),select(0.0,1.0,path.causticReceiverPrimary));\n causticHot[2]+=vec3f(select(0.0,1.0,path.causticMneeReceiver),select(0.0,1.0,path.causticPhotonReceiver),value);\n if(samplingBounce>=3u&&samplingBounce<=8u){causticHot[samplingBounce]+=vec3f(1.0,f32(path.causticK),value);}\n}\nfn causticEstimateRecord(value:vec3f,kind:u32){\n if(!${hot}){return;}\n let peak=max(max(value.x,value.y),value.z);if(peak>100.0){causticHot[10u+kind]+=vec3f(1.0,f32(samplingBounce),peak);}\n}\nfn causticEmitterRecord(si:SurfaceInteraction,path:Path,weight:f32,emission:vec3f){\n if(!${hot}){return;}\n let value=path.beta*weight*emission;if(max(max(value.x,value.y),value.z)<=100.0){return;}\n let material=materialsBuffer[si.materialIndex];\n causticHot[12]+=vec3f(1.0+dot(si.faceNormal,-path.ray.d),select(0.0,1.0,path.fromEye),material.doubleSided);\n causticHot[13]+=vec3f(weight,material.matType,rtUniform.lightWeightTotal);\n causticHot[14]+=vec3f(path.scatteringPdf,dot(material.emission,luminance),max(max(path.beta.x,path.beta.y),path.beta.z));\n}\nfn causticAdvance(path: ptr<function, Path>, m: OpenPbrResolvedMaterial, transmission: bool, surface: bool) {\n if (surface && isCausticSpecular(m)) {\n (*path).causticK++;\n (*path).causticSingleT = (*path).causticK == 1u && ((isCausticT(m) && transmission)||(isCausticR(m)&&!transmission));\n } else {\n (*path).causticK = 0u;\n (*path).causticSingleT = false;\n (*path).causticPhotonReceiver=surface&&samplingBounce<=${photonMaxDepth}u&&m.materialType!=SHADOW_CATCHER;\n (*path).causticHasReceiver = m.materialType != SHADOW_CATCHER;\n (*path).causticMneeReceiver = surface && samplingBounce<=${mneeMaxDepth}u &&\n m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0 && m.subsurfaceWeight==0.0;\n (*path).causticReceiverPrimary = (*path).fromEye && surface;\n }\n}\n`;\n}\n"]}
@@ -11,12 +11,12 @@ const ROUGHNESS_MIN = 0.001;
11
11
 
12
12
 
13
13
 
14
- fn sR(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
14
+ fn sO(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
15
15
  let normal = select(-geometricNormal, geometricNormal, dot(geometricNormal, direction) >= 0.0);
16
- let rm = vec3i(256.0 * normal);
16
+ let rb = vec3i(256.0 * normal);
17
17
  let bits = bitcast<vec3i>(position);
18
- let xC = bitcast<vec3f>(bits + select(rm, -rm, position < vec3f(0.0)));
19
- return select(xC, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
18
+ let ye = bitcast<vec3f>(bits + select(rb, -rb, position < vec3f(0.0)));
19
+ return select(ye, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
20
20
  }
21
21
 
22
22
  `;
@@ -11,40 +11,40 @@ fn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {
11
11
 
12
12
  let size = vec2f(textureDimensions(tex, 0));
13
13
 
14
- let yq = _uv * size - vec2f(0.5);
15
- let xI = floor(yq);
16
- let f = fract(yq);
17
- let xH = vec2i(xI);
14
+ let uv2f = _uv * size - vec2f(0.5);
15
+ let yj = floor(uv2f);
16
+ let f = fract(uv2f);
17
+ let yi = vec2i(yj);
18
18
  let maximum = vec2i(size) - vec2i(1);
19
19
 
20
20
 
21
- let s1 = textureLoad(tex, clamp(xH + vec2i(0, 0), vec2i(0), maximum), 0);
22
- let s2 = textureLoad(tex, clamp(xH + vec2i(1, 0), vec2i(0), maximum), 0);
23
- let s3 = textureLoad(tex, clamp(xH + vec2i(0, 1), vec2i(0), maximum), 0);
24
- let s4 = textureLoad(tex, clamp(xH + vec2i(1, 1), vec2i(0), maximum), 0);
21
+ let s1 = textureLoad(tex, clamp(yi + vec2i(0, 0), vec2i(0), maximum), 0);
22
+ let s2 = textureLoad(tex, clamp(yi + vec2i(1, 0), vec2i(0), maximum), 0);
23
+ let s3 = textureLoad(tex, clamp(yi + vec2i(0, 1), vec2i(0), maximum), 0);
24
+ let s4 = textureLoad(tex, clamp(yi + vec2i(1, 1), vec2i(0), maximum), 0);
25
25
 
26
26
  return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);
27
27
 
28
28
  }
29
29
 
30
- fn eV(gx: vec3f) -> vec2f {
31
- var phi = atan2(-gx.z, -gx.x);
30
+ fn eF(gh: vec3f) -> vec2f {
31
+ var phi = atan2(-gh.z, -gh.x);
32
32
  if (phi < 0.0) {
33
33
  phi += TWOPI;
34
34
  }
35
- let theta = acos(clamp(gx.y, -1.0, 1.0));
35
+ let theta = acos(clamp(gh.y, -1.0, 1.0));
36
36
  return vec2f(phi * 0.5 * INVPI, theta * INVPI);
37
37
  }
38
38
 
39
- fn ko() -> mat3x3f {
39
+ fn jS() -> mat3x3f {
40
40
  return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);
41
41
  }
42
42
 
43
- fn dm(nO: vec3f) -> vec2f {
44
- return eV(transpose(ko()) * nO);
43
+ fn cT(nD: vec3f) -> vec2f {
44
+ return eF(transpose(jS()) * nD);
45
45
  }
46
46
 
47
- fn rE(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
47
+ fn rv(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
48
48
  let size = vec2i(textureDimensions(envMap, 0));
49
49
 
50
50
  var left = 0;
@@ -70,7 +70,7 @@ let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;
70
70
  return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);
71
71
  }
72
72
 
73
- fn rD(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
73
+ fn ru(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
74
74
  let size = vec2i(textureDimensions(envMap, 0));
75
75
 
76
76
  var left = 0;
@@ -84,57 +84,57 @@ left = mid + 1;
84
84
  right = mid;
85
85
  }
86
86
  }
87
- let pO = left - 1;
87
+ let pw = left - 1;
88
88
 
89
89
 
90
90
 
91
- let s0 = textureLoad(envMapDistribution, vec2i(1 + pO, vOffset), 0).xy;
92
- let s1 = textureLoad(envMapDistribution, vec2i(1 + pO + 1, vOffset), 0).xy;
91
+ let s0 = textureLoad(envMapDistribution, vec2i(1 + pw, vOffset), 0).xy;
92
+ let s1 = textureLoad(envMapDistribution, vec2i(1 + pw + 1, vOffset), 0).xy;
93
93
 
94
94
  (*pdf).x = s0.y;
95
95
 
96
- return (f32(pO) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
96
+ return (f32(pw) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
97
97
  }
98
98
 
99
99
 
100
100
 
101
- fn eW(ew: vec2f, v: f32) -> f32 {
101
+ fn envMapSolidAnglePdf(partialPdf: vec2f, v: f32) -> f32 {
102
102
  if (!(v > 0.0 && v < 1.0)) { return 0.0; }
103
103
  let sinTheta = sin(min(v, 1.0 - v) * PI);
104
- return ew.x * ew.y * INVPI2 / (2.0 * sinTheta);
104
+ return partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);
105
105
  }
106
106
 
107
107
 
108
- fn pI(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
109
- var ew: vec2f;
108
+ fn pn(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
109
+ var partialPdf: vec2f;
110
110
  var vOffset: i32;
111
111
 
112
- (*uv).y = rE(random.x, &vOffset, &ew);
113
- (*uv).x = rD(random.y, vOffset, &ew);
112
+ (*uv).y = rv(random.x, &vOffset, &partialPdf);
113
+ (*uv).x = ru(random.y, vOffset, &partialPdf);
114
114
 
115
115
  let phi = (*uv).x * TWOPI;
116
116
  let theta = (*uv).y * PI;
117
- let ci = cos(theta);
117
+ let ct = cos(theta);
118
118
  let sinTheta = sin(theta);
119
- let vM = cos(phi);
120
- let vX = sin(phi);
119
+ let vZ = cos(phi);
120
+ let wr = sin(phi);
121
121
 
122
- let dir = vec3f(-sinTheta * vM, ci, -sinTheta * vX);
122
+ let dir = vec3f(-sinTheta * vZ, ct, -sinTheta * wr);
123
123
 
124
- *pdf = eW(ew, (*uv).y);
124
+ *pdf = envMapSolidAnglePdf(partialPdf, (*uv).y);
125
125
 
126
- return ko() * dir;
126
+ return jS() * dir;
127
127
  }
128
128
 
129
- fn iT(_uv: vec2f) -> f32 {
129
+ fn envMapPdf(_uv: vec2f) -> f32 {
130
130
  let size = vec2f(textureDimensions(envMap, 0));
131
131
 
132
- let xO = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));
132
+ let yn = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));
133
133
 
134
- let ub = textureLoad(envMapDistribution, vec2i(1 + xO.x, xO.y), 0).y;
135
- let uc = textureLoad(envMapDistribution, vec2i(0, xO.y), 0).y;
134
+ let ue = textureLoad(envMapDistribution, vec2i(1 + yn.x, yn.y), 0).y;
135
+ let uf = textureLoad(envMapDistribution, vec2i(0, yn.y), 0).y;
136
136
 
137
- return eW(vec2f(ub, uc), _uv.y);
137
+ return envMapSolidAnglePdf(vec2f(ue, uf), _uv.y);
138
138
  }
139
139
 
140
140