@meimu/mutracer 0.3.0 → 0.3.1

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 (304) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/LICENSES/FidelityFX-FSR.txt +19 -0
  3. package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
  4. package/THIRD_PARTY_NOTICES.md +18 -4
  5. package/dist/assets/bvh.worker.js +1 -1
  6. package/dist/mutracer.umd.js +6260 -5580
  7. package/docs/api.md +45 -18
  8. package/docs/materials.md +4 -2
  9. package/docs/performance.md +7 -0
  10. package/docs/post-processing.md +62 -9
  11. package/docs/progressive-rendering.md +3 -0
  12. package/docs/sampling.md +4 -0
  13. package/docs/technical/acceleration.md +52 -0
  14. package/docs/technical/aovs.md +79 -0
  15. package/docs/technical/caustics.md +109 -0
  16. package/docs/technical/continuous-spectrum.md +29 -0
  17. package/docs/technical/display-upscale.md +82 -0
  18. package/docs/technical/openpbr.md +99 -0
  19. package/docs/technical/pbrt-import.md +168 -0
  20. package/docs/technical/tiling.md +74 -0
  21. package/docs/technical/webgl.md +53 -0
  22. package/docs/viewer.md +11 -1
  23. package/lib/Display.d.ts +19 -5
  24. package/lib/Display.js +10 -7
  25. package/lib/Display.js.map +1 -1
  26. package/lib/Engine.d.ts +2 -1
  27. package/lib/Engine.js +30 -2
  28. package/lib/Engine.js.map +1 -1
  29. package/lib/Render.d.ts +20 -11
  30. package/lib/Render.js +32 -7
  31. package/lib/Render.js.map +1 -1
  32. package/lib/main.d.ts +3 -1
  33. package/lib/main.js +1 -0
  34. package/lib/main.js.map +1 -1
  35. package/lib/oidn.d.ts +1 -1
  36. package/lib/renderer/AovPrimitiveCache.js +39 -8
  37. package/lib/renderer/AovPrimitiveCache.js.map +1 -1
  38. package/lib/renderer/DisplayPostProcess.d.ts +8 -3
  39. package/lib/renderer/DisplayPostProcess.js +51 -18
  40. package/lib/renderer/DisplayPostProcess.js.map +1 -1
  41. package/lib/renderer/MaterialData.js +7 -2
  42. package/lib/renderer/MaterialData.js.map +1 -1
  43. package/lib/renderer/RenderingPipeline.d.ts +7 -1
  44. package/lib/renderer/RenderingPipeline.js.map +1 -1
  45. package/lib/renderer/TileRender.d.ts +2 -2
  46. package/lib/renderer/TileRender.js +128 -7
  47. package/lib/renderer/TileRender.js.map +1 -1
  48. package/lib/renderer/WGPUAov.d.ts +6 -1
  49. package/lib/renderer/WGPUAov.js +108 -14
  50. package/lib/renderer/WGPUAov.js.map +1 -1
  51. package/lib/renderer/WGPUCanvasSurface.js +12 -1
  52. package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
  53. package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
  54. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  55. package/lib/renderer/WGPURayTraceOutput.js +12 -12
  56. package/lib/renderer/WGPURayTracePass.d.ts +17 -4
  57. package/lib/renderer/WGPURayTracePass.js +194 -71
  58. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  59. package/lib/renderer/WGPURenderingPipeline.js +46 -40
  60. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  61. package/lib/renderer/WebGLAov.js +3 -3
  62. package/lib/renderer/WebGLAov.js.map +1 -1
  63. package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
  64. package/lib/renderer/WebGLFullQuadPass.js +8 -2
  65. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  66. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  67. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  68. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  69. package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
  70. package/lib/renderer/WebGLRayTracePass.js +115 -111
  71. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  72. package/lib/renderer/WebGLRenderingPipeline.js +10 -3
  73. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  74. package/lib/renderer/WebGLSkyBaker.js +57 -57
  75. package/lib/renderer/aov.d.ts +13 -1
  76. package/lib/renderer/aov.js +21 -2
  77. package/lib/renderer/aov.js.map +1 -1
  78. package/lib/renderer/aovDisplay.js +2 -2
  79. package/lib/renderer/aovDisplay.js.map +1 -1
  80. package/lib/renderer/binnedSahBvh.d.ts +2 -1
  81. package/lib/renderer/binnedSahBvh.js +24 -17
  82. package/lib/renderer/binnedSahBvh.js.map +1 -1
  83. package/lib/renderer/bvhAccel.d.ts +3 -1
  84. package/lib/renderer/bvhAccel.js +36 -6
  85. package/lib/renderer/bvhAccel.js.map +1 -1
  86. package/lib/renderer/cameraUniform.d.ts +1 -1
  87. package/lib/renderer/cameraUniform.js +6 -2
  88. package/lib/renderer/cameraUniform.js.map +1 -1
  89. package/lib/renderer/compactVertices.d.ts +14 -0
  90. package/lib/renderer/compactVertices.js +124 -0
  91. package/lib/renderer/compactVertices.js.map +1 -0
  92. package/lib/renderer/easu.d.ts +11 -0
  93. package/lib/renderer/easu.js +156 -0
  94. package/lib/renderer/easu.js.map +1 -0
  95. package/lib/renderer/geometryUpdateState.d.ts +1 -0
  96. package/lib/renderer/geometryUpdateState.js.map +1 -1
  97. package/lib/renderer/geometryUpdates.js +3 -2
  98. package/lib/renderer/geometryUpdates.js.map +1 -1
  99. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  100. package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
  101. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  102. package/lib/renderer/glsl/aovTrace.frag.js +44 -36
  103. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
  104. package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
  105. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
  106. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
  107. package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
  108. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
  109. package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
  110. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
  111. package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
  112. package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
  113. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  114. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
  115. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
  116. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  117. package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
  118. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
  119. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  120. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
  121. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  122. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
  123. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
  124. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  125. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
  126. package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
  127. package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
  128. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
  129. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
  130. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
  131. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  132. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  133. package/lib/renderer/glsl/depthQuery.frag.js +12 -6
  134. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  135. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  136. package/lib/renderer/glsl/rayTrace.frag.js +233 -170
  137. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  138. package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
  139. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  140. package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
  141. package/lib/renderer/gpuMemory.js +1 -1
  142. package/lib/renderer/gpuMemory.js.map +1 -1
  143. package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
  144. package/lib/renderer/openPbrEnergyLut.js +18 -1
  145. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  146. package/lib/renderer/pathLimits.d.ts +5 -4
  147. package/lib/renderer/pathLimits.js +6 -5
  148. package/lib/renderer/pathLimits.js.map +1 -1
  149. package/lib/renderer/prepareMeshBVH.d.ts +2 -0
  150. package/lib/renderer/prepareMeshBVH.js +5 -3
  151. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  152. package/lib/renderer/progressiveScheduler.js +1 -1
  153. package/lib/renderer/progressiveScheduler.js.map +1 -1
  154. package/lib/renderer/renderPipeline.d.ts +4 -0
  155. package/lib/renderer/renderPipeline.js +1 -0
  156. package/lib/renderer/renderPipeline.js.map +1 -1
  157. package/lib/renderer/researchTransport.d.ts +1 -1
  158. package/lib/renderer/researchTransport.js.map +1 -1
  159. package/lib/renderer/sceneAssembly.d.ts +1 -1
  160. package/lib/renderer/sceneAssembly.js +4 -3
  161. package/lib/renderer/sceneAssembly.js.map +1 -1
  162. package/lib/renderer/sceneChangeDetector.d.ts +1 -1
  163. package/lib/renderer/sceneChangeDetector.js +3 -1
  164. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  165. package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
  166. package/lib/renderer/sceneLayoutSchema.js +2 -2
  167. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  168. package/lib/renderer/scenePreparation.d.ts +3 -2
  169. package/lib/renderer/scenePreparation.js +18 -2
  170. package/lib/renderer/scenePreparation.js.map +1 -1
  171. package/lib/renderer/scratchSampling.js +6 -6
  172. package/lib/renderer/spectrum.js +2 -2
  173. package/lib/renderer/staticBvhPreparation.d.ts +9 -0
  174. package/lib/renderer/staticBvhPreparation.js +8 -2
  175. package/lib/renderer/staticBvhPreparation.js.map +1 -1
  176. package/lib/renderer/surfaceHit.d.ts +10 -0
  177. package/lib/renderer/surfaceHit.js +22 -0
  178. package/lib/renderer/surfaceHit.js.map +1 -0
  179. package/lib/renderer/tangentRequirements.d.ts +2 -0
  180. package/lib/renderer/tangentRequirements.js +7 -0
  181. package/lib/renderer/tangentRequirements.js.map +1 -0
  182. package/lib/renderer/textureAtlas.d.ts +4 -0
  183. package/lib/renderer/textureAtlas.js +48 -2
  184. package/lib/renderer/textureAtlas.js.map +1 -1
  185. package/lib/renderer/webgl.js +4 -0
  186. package/lib/renderer/webgl.js.map +1 -1
  187. package/lib/renderer/webglVertexAttributes.d.ts +17 -0
  188. package/lib/renderer/webglVertexAttributes.js +44 -0
  189. package/lib/renderer/webglVertexAttributes.js.map +1 -0
  190. package/lib/renderer/wgpuBindlessSource.js +2 -2
  191. package/lib/renderer/wgpuMaterialConstants.js +4 -3
  192. package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
  193. package/lib/renderer/wgpuSceneUniform.js +2 -2
  194. package/lib/renderer/wgpuSceneUniform.js.map +1 -1
  195. package/lib/renderer/wgpuShaderSource.d.ts +15 -0
  196. package/lib/renderer/wgpuShaderSource.js +1 -1
  197. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  198. package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
  199. package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
  200. package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
  201. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  202. package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
  203. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  204. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
  205. package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
  206. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
  207. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
  208. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
  209. package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
  210. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
  211. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
  212. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
  213. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  214. package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
  215. package/lib/renderer/wgsl/causticLight.compute.js +121 -119
  216. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
  217. package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
  218. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
  219. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
  220. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
  221. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  222. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
  223. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
  224. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
  225. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  226. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
  227. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
  228. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  229. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
  230. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
  231. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  232. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
  233. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
  234. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  235. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
  236. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
  237. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  238. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
  239. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  240. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
  241. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  242. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
  243. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
  244. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
  245. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
  246. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
  247. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
  248. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  249. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
  250. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
  251. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
  252. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
  253. package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
  254. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  255. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  256. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  257. package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
  258. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  259. package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
  260. package/lib/renderer/wgsl/easu.wgsl.js +80 -0
  261. package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
  262. package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
  263. package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
  264. package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
  265. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  266. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
  267. package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
  268. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  269. package/lib/renderer/wgsl/photonMap.compute.js +89 -89
  270. package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
  271. package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
  272. package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
  273. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  274. package/lib/scene/Scene.js.map +1 -1
  275. package/lib/settings/render.d.ts +11 -0
  276. package/lib/settings/render.js +1 -0
  277. package/lib/settings/render.js.map +1 -1
  278. package/lib/util/fromTHREE.js +21 -14
  279. package/lib/util/fromTHREE.js.map +1 -1
  280. package/lib/version.d.ts +1 -1
  281. package/lib/version.js +1 -1
  282. package/lib/version.js.map +1 -1
  283. package/package.json +5 -2
  284. package/lib/oidnBundledWeights.cdn.d.ts +0 -2
  285. package/lib/oidnBundledWeights.cdn.js +0 -5
  286. package/lib/oidnBundledWeights.cdn.js.map +0 -1
  287. package/lib/renderer/bvh.worker.d.ts +0 -1
  288. package/lib/renderer/bvh.worker.js +0 -16
  289. package/lib/renderer/bvh.worker.js.map +0 -1
  290. package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
  291. package/lib/renderer/bvhWorkerBuild.js +0 -17
  292. package/lib/renderer/bvhWorkerBuild.js.map +0 -1
  293. package/lib/renderer/lightCore.d.ts +0 -12
  294. package/lib/renderer/lightCore.js +0 -13
  295. package/lib/renderer/lightCore.js.map +0 -1
  296. package/lib/renderer/materialCore.d.ts +0 -8
  297. package/lib/renderer/materialCore.js +0 -9
  298. package/lib/renderer/materialCore.js.map +0 -1
  299. package/lib/scene/PixelTexture.d.ts +0 -6
  300. package/lib/scene/PixelTexture.js +0 -10
  301. package/lib/scene/PixelTexture.js.map +0 -1
  302. package/lib/util/studioLighting.d.ts +0 -18
  303. package/lib/util/studioLighting.js +0 -36
  304. package/lib/util/studioLighting.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  // Next-event estimation with resampled importance sampling over the light
2
2
  // candidates, followed by BSDF (or phase function) sampling, as described in
3
3
  // http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral
4
- export function createSampleMaterialWgsl(hasAnisotropyDirections = true, hasCoatNormals = false, caustics = false, researchContribution = '', photonMapping = false) {
4
+ export function createSampleMaterialWgsl(hasAnisotropyDirections = true, hasCoatNormals = false, caustics = false, researchContribution = '', photonMapping = false, channelIndependentRis = false) {
5
5
  return /* wgsl */ `
6
6
 
7
- struct nR {
7
+ struct oQ {
8
8
  ray: Ray,
9
9
  maxDistance: f32,
10
10
  triangleIndex: i32,
@@ -16,7 +16,7 @@ lightSelectionPmf: f32,
16
16
  valid: bool,
17
17
  }
18
18
 
19
- fn rZ(
19
+ fn tw(
20
20
  si: ptr<function, SurfaceInteraction>,
21
21
  ma: OpenPbrResolvedMaterial,
22
22
  path: ptr<function, Path>,
@@ -25,11 +25,11 @@ isSurface: bool,
25
25
  lightSample: LightSampleRec,
26
26
  f: vec3f,
27
27
  scatteringPdf: f32,
28
- gj: ptr<function, nR>
28
+ eO: ptr<function, oQ>
29
29
  ) -> bool {
30
- (*gj).valid = false;
31
- (*gj).lightSelectionPmf = 0.0;
32
- (*gj).risTarget = 0.0;
30
+ (*eO).valid = false;
31
+ (*eO).lightSelectionPmf = 0.0;
32
+ (*eO).risTarget = 0.0;
33
33
  var Li = lightSample.emission;
34
34
 
35
35
  let lightDir = lightSample.direction;${caustics ? /* wgsl */ `
@@ -38,7 +38,7 @@ var connection=*path;
38
38
  causticAdvance(&connection,ma,dot(ffnormal,lightDir)<0.0,true);
39
39
  if(causticHitOwned(connection,lightSample.sourceType!=0u,true)){return false;}
40
40
  }` : ''}
41
- let qR = -(*path).ray.d;
41
+ let sg = -(*path).ray.d;
42
42
  let lightPdf = lightSample.pdf;
43
43
  let lightSelectionPmf = lightSample.selectionPmf;
44
44
 
@@ -55,103 +55,109 @@ if ((scatteringPdf <= 0.0) | (max(max(f.x, f.y), f.z) <= 0.0)) {
55
55
  return false;
56
56
  }
57
57
 
58
- var mY: Ray;
59
- var eO = (*si).position + EPS * lightDir;
58
+ var oa: Ray;
59
+ var eY = (*si).position + EPS * lightDir;
60
60
  if (isSurface) {
61
- eO = sO((*si).position, (*si).faceNormal, lightDir);
61
+ eY = un((*si).position, (*si).faceNormal, lightDir);
62
62
  let shadowTerminatorCutoff = 0.1;
63
- var dj = dot((*si).normal, lightDir);
64
- ${hasCoatNormals ? /* wgsl */ ` if (ma.coatNormalEnabled) { dj = dot((*si).faceNormal, lightDir); }` : ''}
63
+ var dl = dot((*si).normal, lightDir);
64
+ ${hasCoatNormals ? /* wgsl */ ` if (ma.coatNormalEnabled) { dl = dot((*si).faceNormal, lightDir); }` : ''}
65
65
  let geometricNormal = select(
66
66
  (*si).faceNormal,
67
67
  -(*si).faceNormal,
68
- dj < 0.0
68
+ dl < 0.0
69
69
  );
70
- dj = abs(dj);
71
- let hO = dot(geometricNormal, lightDir);
72
- let pf = select(
73
- clamp(1.0 - hO / shadowTerminatorCutoff, 0.0, 1.0),
70
+ dl = abs(dl);
71
+ let iw = dot(geometricNormal, lightDir);
72
+ let qo = select(
73
+ clamp(1.0 - iw / shadowTerminatorCutoff, 0.0, 1.0),
74
74
  clamp(
75
- 2.0 - (hO + dj) / shadowTerminatorCutoff,
75
+ 2.0 - (iw + dl) / shadowTerminatorCutoff,
76
76
  0.0,
77
77
  1.0
78
78
  ),
79
- dj < shadowTerminatorCutoff
79
+ dl < shadowTerminatorCutoff
80
80
  );
81
- eO += (*si).shadowOffset * pf;
81
+ eY += (*si).shadowOffset * qo;
82
82
  }
83
83
 
84
84
 
85
85
 
86
86
 
87
- var mh = lightDir;
88
- var nC = lightSample.dist - EPS;
87
+ var mZ = lightDir;
88
+ var oy = lightSample.dist - EPS;
89
89
  if (lightSample.sourceType == 1u) {
90
- let us =
90
+ let wc =
91
91
  (*si).position + lightSample.direction * lightSample.dist;
92
- let qU = us + EPS * lightSample.normal;
93
- let rk = qU - eO;
94
- nC = length(rk);
95
- mh = normalize(rk);
92
+ let sk = wc + EPS * lightSample.normal;
93
+ let sB = sk - eY;
94
+ oy = length(sB);
95
+ mZ = normalize(sB);
96
96
  }
97
- initRay(&mY, eO, mh);
97
+ initRay(&oa, eY, mZ);
98
98
 
99
99
 
100
100
 
101
101
 
102
102
  if (isSurface & (cosThetaL < 0.0) & (lightSample.sourceType == 0u)) {
103
- let background = ft(mY);
103
+ let background = fI(oa);
104
104
  Li = background.rgb * background.a;
105
105
  }
106
- if (SPECTRAL) {
106
+ if (SPECTRAL${channelIndependentRis ? ' && rtUniform.dispersionWavelengths == 1' : ''}) {
107
107
  Li = sampling_spectral_rgb_filter(Li, (*si).spectralChannel);
108
108
  }
109
109
 
110
110
 
111
111
 
112
112
  let misWeight = select(
113
- uY(lightPdf, scatteringPdf),
113
+ wM(lightPdf, scatteringPdf),
114
114
  1.0,
115
115
  lightSample.isDelta
116
116
  );
117
117
  if (misWeight > 0.0) {
118
- let kB = Li * f / lightPdf * (*path).beta;
119
- (*gj).risTarget = max(
120
- dot(max(kB * lightSelectionPmf, vec3f(0.0)), luminance),
118
+ let ll = Li * f / lightPdf * (*path).beta;
119
+ (*eO).risTarget = max(
120
+ dot(max(ll * lightSelectionPmf, vec3f(0.0)), ${channelIndependentRis ? 'select(luminance, vec3f(1.0 / 3.0), SPECTRAL && rtUniform.dispersionWavelengths != 1)' : 'luminance'}),
121
121
  0.0
122
122
  );
123
- (*gj).ray = mY;
124
- (*gj).maxDistance = nC;
125
- (*gj).triangleIndex = (*si).triangleIndex;
126
- (*gj).contribution = misWeight * kB;
127
- (*gj).lightSelectionPmf = lightSelectionPmf;
128
- (*gj).valid = true;
123
+ (*eO).ray = oa;
124
+ (*eO).maxDistance = oy;
125
+ (*eO).triangleIndex = (*si).triangleIndex;
126
+ (*eO).contribution = misWeight * ll;${channelIndependentRis ? /* wgsl */ `
127
+
128
+
129
+
130
+ if (SPECTRAL && rtUniform.dispersionWavelengths != 1) {
131
+ (*eO).contribution = sampling_spectral_rgb_filter((*eO).contribution, (*si).spectralChannel);
132
+ }` : ''}
133
+ (*eO).lightSelectionPmf = lightSelectionPmf;
134
+ (*eO).valid = true;
129
135
  return true;
130
136
  }
131
137
  return false;
132
138
  }
133
139
 
134
- struct pX {
140
+ struct rb {
135
141
  direction: vec3f,
136
142
  response: vec3f,
137
143
  pdf: f32,
138
144
  transmission: bool,
139
145
  }
140
146
 
141
- fn sV(
147
+ fn ps(
142
148
  si: ptr<function, SurfaceInteraction>,
143
149
  ma: OpenPbrResolvedMaterial,
144
150
  prepared: OpenPbrPreparedBsdf,
145
151
  path: ptr<function, Path>,
146
152
  ffnormal: vec3f,
147
153
  isSurface: bool
148
- ) -> pX {
149
- let candidateCount = ke();
150
- var selected: nR;
154
+ ) -> rb {
155
+ let candidateCount = kL();
156
+ var selected: oQ;
151
157
  selected.valid = false;
152
- var nq = 0.0;
153
- var lW = 0.0;
154
- var result: pX;
158
+ var oo = 0.0;
159
+ var mQ = 0.0;
160
+ var result: rb;
155
161
 
156
162
 
157
163
 
@@ -162,37 +168,37 @@ var lightSample: LightSampleRec;
162
168
  var lightDir: vec3f;
163
169
  var scatteringPdf = 0.0;
164
170
  var response = vec3f(0.0);
165
- var tF = false;
171
+ var vg = false;
166
172
  if (continuation) {
167
- var oI = 1.0;
173
+ var pP = 1.0;
168
174
  var valid = selected.valid;
169
175
  if (candidateCount > 1u) {
170
- valid = valid & (nq > 0.0);
176
+ valid = valid & (oo > 0.0);
171
177
  if (valid) {
172
- oI = selected.lightSelectionPmf * lW /
173
- (f32(candidateCount) * nq);
178
+ pP = selected.lightSelectionPmf * mQ /
179
+ (f32(candidateCount) * oo);
174
180
  }
175
181
  }
176
182
  if (valid && !intersectSceneShadow(selected.ray, selected.maxDistance, selected.triangleIndex, (*si).instanceIndex)) {
177
183
  ${caustics ? ` var connection=*path;
178
184
  if(isSurface&&isCausticSpecular(ma)){causticAdvance(&connection,ma,dot(ffnormal,selected.ray.d)<0.0,true);}
179
- connection.beta=vec3f(1.0);causticHotRecord(connection,selected.contribution*oI,0u);
180
- ` : ''} (*path).li += selected.contribution * oI;
185
+ connection.beta=vec3f(1.0);causticHotRecord(connection,selected.contribution*pP,0u);
186
+ ` : ''} (*path).li += selected.contribution * pP;
181
187
  }
182
188
  if (!isSurface) {
183
- result.direction = fj(-(*path).ray.d,
184
- (*si).mediumAnisotropy, sample2D(bE(PHASE_DIRECTION)));
185
- result.pdf = bB(
189
+ result.direction = dQ(-(*path).ray.d,
190
+ (*si).mediumAnisotropy, sample2D(aX(PHASE_DIRECTION)));
191
+ result.pdf = ba(
186
192
  dot(result.direction, -(*path).ray.d), (*si).mediumAnisotropy);
187
193
  return result;
188
194
  }
189
- let wh = vec3f(sample2D(bE(BSDF_DIRECTION)), sample1D(bE(BSDF_LOBE)));
190
- tF = !prepared.material.thinWalled &
195
+ let yh = vec3f(sample2D(aX(BSDF_DIRECTION)), sample1D(aX(BSDF_LOBE)));
196
+ vg = !prepared.material.thinWalled &
191
197
  (abs(prepared.material.relativeIor - 1.0) <= 1e-6) &
192
198
  (prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6);
193
- if (tF) {
199
+ if (vg) {
194
200
  lightDir = openpbr_to_world(prepared.basis, -prepared.viewLocal);
195
- response = ba(prepared.material) * cm(prepared,
201
+ response = bb(prepared.material) * cp(prepared,
196
202
  ${hasCoatNormals ? 'select(-prepared.viewLocal.z, dot(prepared.coatBasis.normal, lightDir), prepared.material.coatNormalEnabled)' : '-prepared.viewLocal.z'});
197
203
  scatteringPdf = 1.0;
198
204
  result.transmission = true;
@@ -201,13 +207,13 @@ var roughness = 1.0; var specular = false; var diffuse = true;
201
207
  var lobe = u32(OPENPBR_LOBE_DIFFUSE);
202
208
 
203
209
  var transmission = false;
204
- if (!iW(prepared, wh, &lightDir, &transmission,
210
+ if (!jC(prepared, yh, &lightDir, &transmission,
205
211
  &roughness, &specular, &diffuse, &lobe)) { return result; }
206
212
  result.transmission = transmission;
207
213
  }
208
214
  } else {
209
- let mZ = vec3f(sample2D(sf(event, 1u)), sample1D(sf(event, 0u)));
210
- nk((*si).position, mZ, event, candidateCount, &lightSample);
215
+ let ob = vec3f(sample2D(tF(event, 1u)), sample1D(tF(event, 0u)));
216
+ oj((*si).position, ob, event, candidateCount, &lightSample);
211
217
  lightDir = lightSample.direction;
212
218
  if ((lightSample.pdf <= 0.0) | (lightSample.selectionPmf <= 0.0) |
213
219
  (max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0)) { continue; }
@@ -215,11 +221,11 @@ ${hasCoatNormals ? /* wgsl */ `var cosThetaL = dot(ffnormal, lightDir);
215
221
  if (isSurface & ma.coatNormalEnabled) { cosThetaL = dot(ma.geometricNormal, lightDir); }` : /* wgsl */ `let cosThetaL = dot(ffnormal, lightDir);`}
216
222
  if (isSurface & (cosThetaL <= 0.0) & (ma.transmissionWeight <= 0.0) & (ma.subsurfaceWeight <= 0.0)) { continue; }
217
223
  }
218
- if (!tF) {
224
+ if (!vg) {
219
225
  if (isSurface) {
220
226
  response = openpbr_eval_prepared(prepared, lightDir, &scatteringPdf);
221
227
  } else {
222
- scatteringPdf = bB(
228
+ scatteringPdf = ba(
223
229
  dot(-(*path).ray.d, lightDir), (*si).mediumAnisotropy);
224
230
  response = vec3f(scatteringPdf);
225
231
  }
@@ -228,21 +234,21 @@ if (continuation) {
228
234
  result.direction = lightDir; result.response = response; result.pdf = scatteringPdf;
229
235
  return result;
230
236
  }
231
- var candidate: nR;
232
- let tv = rZ(si, ma, path, ffnormal, isSurface,
237
+ var candidate: oQ;
238
+ let uY = tw(si, ma, path, ffnormal, isSurface,
233
239
  lightSample, response, scatteringPdf, &candidate);
234
- if (!tv) { continue; }
240
+ if (!uY) { continue; }
235
241
  if (candidateCount == 1u) {
236
242
  selected = candidate;
237
243
  continue;
238
244
  }
239
- let kt = candidate.risTarget / max(candidate.lightSelectionPmf, 1e-20);
240
- if (!(kt > 0.0) | (kt != kt)) { continue; }
241
- lW += kt;
245
+ let kZ = candidate.risTarget / max(candidate.lightSelectionPmf, 1e-20);
246
+ if (!(kZ > 0.0) | (kZ != kZ)) { continue; }
247
+ mQ += kZ;
242
248
  if (!selected.valid ||
243
- qp(event) * lW <= kt) {
249
+ rA(event) * mQ <= kZ) {
244
250
  selected = candidate;
245
- nq = candidate.risTarget;
251
+ oo = candidate.risTarget;
246
252
  }
247
253
  }
248
254
  return result;
@@ -255,8 +261,8 @@ path: ptr<function, Path>
255
261
  if (causticHitOwned(*path, true, true)) { return 0.0; }` : ''}
256
262
 
257
263
 
258
- let om = dot((*si).faceNormal, -(*path).ray.d);
259
- if (om <= 0.0 && materialsBuffer[(*si).materialIndex].doubleSided < 0.5) { return 0.0; }
264
+ let pi = dot((*si).faceNormal, -(*path).ray.d);
265
+ if (pi <= 0.0 && materialsBuffer[(*si).materialIndex].doubleSided < 0.5) { return 0.0; }
260
266
  if ((*path).fromEye | (rtUniform.lightWeightTotal <= 0.0) |
261
267
  (i32(materialsBuffer[(*si).materialIndex].matType) == UNLIT)) {
262
268
  return 1.0;
@@ -265,53 +271,53 @@ let samplingLuminance = dot(
265
271
  materialsBuffer[(*si).materialIndex].emission,
266
272
  luminance
267
273
  );
268
- if ((samplingLuminance <= 0.0) | (om <= 0.0)) {
274
+ if ((samplingLuminance <= 0.0) | (pi <= 0.0)) {
269
275
  return 1.0;
270
276
  }
271
- let tc = distance((*si).position, (*path).ray.o);
277
+ let uF = distance((*si).position, (*path).ray.o);
272
278
  let lightPdf = samplingLuminance / rtUniform.lightWeightTotal *
273
- tc * tc / max(om, 1e-8);
274
- return fV((*path).scatteringPdf, lightPdf);
279
+ uF * uF / max(pi, 1e-8);
280
+ return gm((*path).scatteringPdf, lightPdf);
275
281
  }
276
282
 
277
283
  ${hasCoatNormals ? /* wgsl */ `
278
284
 
279
285
 
280
- fn fE(input: vec3f, face: vec3f, view: vec3f) -> vec3f {
286
+ fn fQ(input: vec3f, face: vec3f, view: vec3f) -> vec3f {
281
287
  let front = dot(face, view) >= 0.0;
282
- let wd = select(-face, face, front);
283
- let rY = select(-input, input, front);
284
- if ((dot(input, face) <= 0.0) | (dot(rY, view) <= 1e-6)) { return wd; }
285
- return rY;
288
+ let yc = select(-face, face, front);
289
+ let tv = select(-input, input, front);
290
+ if ((dot(input, face) <= 0.0) | (dot(tv, view) <= 1e-6)) { return yc; }
291
+ return tv;
286
292
  }
287
293
  ` : ''}
288
- fn mx(
294
+ fn nB(
289
295
  si: ptr<function, SurfaceInteraction>,
290
296
  ma: ptr<function, OpenPbrResolvedMaterial>,
291
297
  path: ptr<function, Path>
292
298
  ) {
293
299
  ${hasCoatNormals ? /* wgsl */ `
294
- let bA = (*si).faceNormal;
295
- let ni = (*si).normal;
300
+ let bC = (*si).faceNormal;
301
+ let oh = (*si).normal;
296
302
  ` : ''}
297
- var sL: f32 = -dot((*si).faceNormal, (*path).ray.d);
298
- var tY: f32 = -dot((*si).normal, (*path).ray.d);
303
+ var uk: f32 = -dot((*si).faceNormal, (*path).ray.d);
304
+ var vH: f32 = -dot((*si).normal, (*path).ray.d);
299
305
  if ((((*ma).transmissionWeight > 0.0) | ((*ma).subsurfaceWeight > 0.0)) & (*ma).thinWalled) {
300
306
 
301
- if (sL < 0.0) {
307
+ if (uk < 0.0) {
302
308
  (*si).faceNormal = -(*si).faceNormal;
303
- sL = -sL;
309
+ uk = -uk;
304
310
  }
305
- if (tY < 0.0) {
311
+ if (vH < 0.0) {
306
312
  (*si).normal = -(*si).normal;
307
- tY = -tY;
313
+ vH = -vH;
308
314
  }
309
315
  }
310
316
 
311
317
 
312
- var qE: bool = (sL >= 0.0) & (tY < 0.0);
313
- var ndv: f32 = select(tY, sL, qE);
314
- var N: vec3f = select((*si).normal, (*si).faceNormal, qE);
318
+ var rS: bool = (uk >= 0.0) & (vH < 0.0);
319
+ var ndv: f32 = select(vH, uk, rS);
320
+ var N: vec3f = select((*si).normal, (*si).faceNormal, rS);
315
321
 
316
322
  (*ma).inside = (ndv <= 0.0) & !(*ma).thinWalled;
317
323
 
@@ -320,63 +326,76 @@ var ffnormal = select(-N, N, ndv >= 0.0);
320
326
  ${hasCoatNormals ? /* wgsl */ `
321
327
  if ((*ma).coatNormalEnabled) {
322
328
  let view = -(*path).ray.d;
323
- let fZ = dot(bA, view);
324
- (*ma).geometricNormal = select(-bA, bA, fZ >= 0.0);
325
- ffnormal = fE(ni, bA, view);
326
- (*ma).coatNormal = fE((*si).coatNormal, bA, view);
327
- (*ma).inside = (fZ <= 0.0) & !(*ma).thinWalled;
328
- (*ma).relativeIor = select((*ma).specularIor, 1.0 / (*ma).specularIor, (fZ > 0.0) | (*ma).thinWalled);
329
+ let gr = dot(bC, view);
330
+ (*ma).geometricNormal = select(-bC, bC, gr >= 0.0);
331
+ ffnormal = fQ(oh, bC, view);
332
+ (*ma).coatNormal = fQ((*si).coatNormal, bC, view);
333
+ (*ma).inside = (gr <= 0.0) & !(*ma).thinWalled;
334
+ (*ma).relativeIor = select((*ma).specularIor, 1.0 / (*ma).specularIor, (gr > 0.0) | (*ma).thinWalled);
329
335
  }
330
336
  ` : ''}
331
337
 
332
338
  (*path).scatteringIsDelta = false;
333
339
  var mediumSampled = false;
334
- var hj = false;
340
+ var hE = false;
335
341
  let mediumType = (*si).mediumType;
336
342
 
337
343
  var scatteringPdf: f32;
338
- var df: vec3f;
344
+ var di: vec3f;
339
345
 
340
346
  if (HAS_MEDIUM) {
341
347
  let d = distance((*si).position, (*path).ray.o);
342
- let od = (*path).ray.o;
348
+ let pd = (*path).ray.o;
343
349
  let extinction = (*si).mediumExtinction;
344
350
  let scattering = min((*si).mediumScattering, extinction);
345
- let tU = max(max(extinction.x, extinction.y), extinction.z);
346
- if ((mediumType > 0) & (tU > 0.0)) {
351
+ let vD = max(max(extinction.x, extinction.y), extinction.z);
352
+ if ((mediumType > 0) & (vD > 0.0)) {
347
353
 
348
354
 
349
- let nX = min(i32(sample1D(bE(MEDIUM_CHANNEL)) * 3.0), 2);
350
- let fD = extinction[nX];
351
- let ij = select(
355
+ let oW = min(i32(sample1D(aX(MEDIUM_CHANNEL)) * 3.0), 2);
356
+ let fP = extinction[oW];
357
+ let iO = select(
352
358
  d,
353
- min(-log(max(sample1D(bE(MEDIUM_DISTANCE)), 1e-7)) / fD, d),
354
- fD > 0.0
359
+ min(-log(max(sample1D(aX(MEDIUM_DISTANCE)), 1e-7)) / fP, d),
360
+ fP > 0.0
355
361
  );
356
- mediumSampled = ij < d;
357
- let transmittance = exp(-extinction * ij);
358
- let oK = select(
362
+ mediumSampled = iO < d;
363
+ let transmittance = exp(-extinction * iO);
364
+ let density = select(
359
365
  transmittance,
360
366
  extinction * transmittance,
361
367
  mediumSampled
362
368
  );
363
- let mediumPdf = max((oK.x + oK.y + oK.z) / 3.0, 1e-8);
369
+ let mediumPdf = max((density.x + density.y + density.z) / 3.0, 1e-8);
364
370
  if (mediumSampled) {
365
371
  (*path).beta *= transmittance * scattering / mediumPdf;
366
372
 
367
- (*path).ray.o = od + ij * (*path).ray.d;
373
+ if (all((*path).beta == vec3f(0.0))) { (*path).abort = true; return; }
374
+
375
+ (*path).ray.o = pd + iO * (*path).ray.d;
368
376
  (*si).position = (*path).ray.o;
377
+
378
+ (*si).triangleIndex = -1;
379
+ (*si).instanceIndex = -1;
369
380
  }
370
381
  else {
371
382
  (*path).beta *= transmittance / mediumPdf;
383
+
384
+ if (all((*path).beta == vec3f(0.0))) { (*path).abort = true; return; }
372
385
  }
373
386
  }
374
387
  }
375
388
 
376
389
  if (!mediumSampled) {
377
- ${caustics ? ` let mM=emissiveHitMisWeight(si,path);
378
- causticHotRecord(*path,mM*(*ma).emission,1u);causticEmitterRecord(*si,*path,mM,(*ma).emission);
379
- (*path).li+=mM*(*ma).emission*(*path).beta;` : ' (*path).li += emissiveHitMisWeight(si, path) * (*ma).emission * (*path).beta;'}
390
+
391
+
392
+ var surfaceEmission = (*ma).emission;
393
+ if (SPECTRAL) {
394
+ surfaceEmission = sampling_spectral_rgb_filter(surfaceEmission, (*si).spectralChannel);
395
+ }
396
+ ${caustics ? ` let nO=emissiveHitMisWeight(si,path);
397
+ causticHotRecord(*path,nO*surfaceEmission,1u);causticEmitterRecord(*si,*path,nO,surfaceEmission);
398
+ (*path).li+=nO*surfaceEmission*(*path).beta;` : ' (*path).li += emissiveHitMisWeight(si, path) * surfaceEmission * (*path).beta;'}
380
399
  }
381
400
  if ((*ma).materialType == UNLIT) {
382
401
  (*path).abort = true;
@@ -392,22 +411,22 @@ ${hasAnisotropyDirections ? /* wgsl */ `
392
411
  (*ma).geometryTangent = (*si).geometryTangent;
393
412
  (*ma).geometryBitangent = (*si).geometryBitangent;
394
413
  ` : /* wgsl */ ``}
395
- prepared = bV((*si).tangent, *ma, -(*path).ray.d, ffnormal);
414
+ prepared = bX((*si).tangent, *ma, -(*path).ray.d, ffnormal);
396
415
  }
397
- ${researchContribution}${photonMapping ? /* wgsl */ ` if(!mediumSampled){let value=(*path).beta*rI(*si,prepared,(*path).fromEye,!(*path).causticHasReceiver);causticEstimateRecord(value,1u);(*path).li+=value;}
398
- ` : ''} let qP = sV(si, *ma, prepared, path, ffnormal, !mediumSampled);
399
- df = qP.direction;
400
- scatteringPdf = qP.pdf;
416
+ ${researchContribution}${photonMapping ? /* wgsl */ ` if(!mediumSampled){let value=(*path).beta*sY(*si,prepared,(*path).fromEye,!(*path).causticHasReceiver);causticEstimateRecord(value,1u);(*path).li+=value;}
417
+ ` : ''} let lX = ps(si, *ma, prepared, path, ffnormal, !mediumSampled);
418
+ di = lX.direction;
419
+ scatteringPdf = lX.pdf;
401
420
  if (!mediumSampled) {
402
- let f = qP.response;
403
- let isNextRefraction = qP.transmission;
421
+ let f = lX.response;
422
+ let isNextRefraction = lX.transmission;
404
423
 
405
424
 
406
425
 
407
426
 
408
427
  if (!(scatteringPdf > 0.0) |
409
428
  !all(f == f) | !all(abs(f) < vec3f(3.402823e38)) |
410
- (dot(df, df) < 0.5)) {
429
+ (dot(di, di) < 0.5)) {
411
430
  (*path).scatteringPdf = 0.0;
412
431
  (*path).abort = true;
413
432
  return;
@@ -420,17 +439,19 @@ return;
420
439
  ${caustics ? /* wgsl */ ` causticAdvance(path, *ma, isNextRefraction, true);
421
440
  ` : ''} (*path).beta *= f / scatteringPdf;
422
441
 
423
- hj = isNextRefraction & !(*ma).thinWalled;
442
+ if (all((*path).beta == vec3f(0.0))) { (*path).abort = true; return; }
443
+
444
+ hE = isNextRefraction & !(*ma).thinWalled;
424
445
  (*path).isNextRefraction = isNextRefraction;
425
446
 
426
447
 
427
- (*path).ray.o = (*si).position + EPS * df;
448
+ (*path).ray.o = (*si).position + EPS * di;
428
449
  ${hasCoatNormals ? /* wgsl */ `
429
- if ((*ma).coatNormalEnabled) { (*path).ray.o = (*si).position + EPS * select(-bA, bA, dot(bA, df) >= 0.0); }
450
+ if ((*ma).coatNormalEnabled) { (*path).ray.o = (*si).position + EPS * select(-bC, bC, dot(bC, di) >= 0.0); }
430
451
  ` : ''}
431
452
  }
432
453
  (*path).scatteringPdf = scatteringPdf;
433
- (*path).ray.d = df;
454
+ (*path).ray.d = di;
434
455
  if (mediumSampled) {${caustics ? /* wgsl */ `
435
456
  causticAdvance(path, *ma, false, false);` : ''}
436
457
  (*path).isNextRefraction = false;
@@ -441,11 +462,12 @@ causticAdvance(path, *ma, false, false);` : ''}
441
462
  if (HAS_MEDIUM) {
442
463
 
443
464
 
444
- if (!mediumSampled & hj & ((*ma).mediumType > 0)) {
445
- if (sL >= 0.0) {
465
+ if (!mediumSampled & hE & ((*ma).mediumType > 0)) {
466
+ if (uk >= 0.0) {
446
467
  (*si).mediumType = (*ma).mediumType;
447
468
  (*si).mediumExtinction = (*ma).mediumExtinction;
448
469
  (*si).mediumScattering = (*ma).mediumScattering;
470
+ (*path).scatteringMediumEntered = (*path).scatteringMediumEntered || any((*ma).mediumScattering > vec3f(0.0));
449
471
  (*si).mediumAnisotropy = (*ma).mediumAnisotropy;
450
472
  }
451
473
  else {