@meimu/mutracer 0.2.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 (372) 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/README.md +3 -0
  5. package/THIRD_PARTY_NOTICES.md +18 -4
  6. package/dist/assets/bvh.worker.js +1 -1
  7. package/dist/mutracer.umd.js +9328 -7614
  8. package/docs/api.md +83 -35
  9. package/docs/caustics.md +80 -0
  10. package/docs/materials.md +9 -6
  11. package/docs/performance.md +7 -0
  12. package/docs/post-processing.md +62 -9
  13. package/docs/progressive-rendering.md +53 -9
  14. package/docs/sampling.md +4 -0
  15. package/docs/technical/acceleration.md +52 -0
  16. package/docs/technical/aovs.md +79 -0
  17. package/docs/technical/caustics.md +109 -0
  18. package/docs/technical/continuous-spectrum.md +122 -0
  19. package/docs/technical/display-upscale.md +82 -0
  20. package/docs/technical/openpbr.md +99 -0
  21. package/docs/technical/pbrt-import.md +168 -0
  22. package/docs/technical/tiling.md +74 -0
  23. package/docs/technical/webgl.md +53 -0
  24. package/docs/updates.md +3 -1
  25. package/docs/viewer-checklist.md +65 -0
  26. package/docs/viewer.md +18 -6
  27. package/lib/Display.d.ts +19 -5
  28. package/lib/Display.js +10 -7
  29. package/lib/Display.js.map +1 -1
  30. package/lib/Engine.d.ts +4 -1
  31. package/lib/Engine.js +77 -14
  32. package/lib/Engine.js.map +1 -1
  33. package/lib/Render.d.ts +81 -24
  34. package/lib/Render.js +201 -26
  35. package/lib/Render.js.map +1 -1
  36. package/lib/RenderLoop.d.ts +7 -3
  37. package/lib/RenderLoop.js +68 -44
  38. package/lib/RenderLoop.js.map +1 -1
  39. package/lib/main.d.ts +4 -2
  40. package/lib/main.js +1 -0
  41. package/lib/main.js.map +1 -1
  42. package/lib/oidn.d.ts +1 -1
  43. package/lib/renderer/AovPrimitiveCache.js +39 -8
  44. package/lib/renderer/AovPrimitiveCache.js.map +1 -1
  45. package/lib/renderer/DisplayPostProcess.d.ts +8 -3
  46. package/lib/renderer/DisplayPostProcess.js +51 -18
  47. package/lib/renderer/DisplayPostProcess.js.map +1 -1
  48. package/lib/renderer/GPUTraceQueue.d.ts +2 -1
  49. package/lib/renderer/GPUTraceQueue.js +3 -1
  50. package/lib/renderer/GPUTraceQueue.js.map +1 -1
  51. package/lib/renderer/MaterialData.js +7 -2
  52. package/lib/renderer/MaterialData.js.map +1 -1
  53. package/lib/renderer/RenderingPipeline.d.ts +11 -1
  54. package/lib/renderer/RenderingPipeline.js.map +1 -1
  55. package/lib/renderer/TileRender.d.ts +2 -2
  56. package/lib/renderer/TileRender.js +128 -7
  57. package/lib/renderer/TileRender.js.map +1 -1
  58. package/lib/renderer/WGPUAov.d.ts +6 -1
  59. package/lib/renderer/WGPUAov.js +108 -14
  60. package/lib/renderer/WGPUAov.js.map +1 -1
  61. package/lib/renderer/WGPUCanvasSurface.js +12 -1
  62. package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
  63. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  64. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  65. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  66. package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
  67. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  68. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  69. package/lib/renderer/WGPUPhotonMap.js +191 -0
  70. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  71. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  72. package/lib/renderer/WGPURayTraceOutput.js +122 -28
  73. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  74. package/lib/renderer/WGPURayTracePass.d.ts +65 -21
  75. package/lib/renderer/WGPURayTracePass.js +730 -409
  76. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  77. package/lib/renderer/WGPURenderingPipeline.js +110 -68
  78. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  79. package/lib/renderer/WebGLAov.js +3 -3
  80. package/lib/renderer/WebGLAov.js.map +1 -1
  81. package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
  82. package/lib/renderer/WebGLFullQuadPass.js +10 -0
  83. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  84. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  85. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  86. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  87. package/lib/renderer/WebGLRayTracePass.d.ts +20 -11
  88. package/lib/renderer/WebGLRayTracePass.js +157 -116
  89. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  90. package/lib/renderer/WebGLRenderingPipeline.js +17 -14
  91. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  92. package/lib/renderer/WebGLSkyBaker.js +60 -60
  93. package/lib/renderer/accumulationTarget.d.ts +2 -1
  94. package/lib/renderer/accumulationTarget.js.map +1 -1
  95. package/lib/renderer/aov.d.ts +13 -1
  96. package/lib/renderer/aov.js +21 -2
  97. package/lib/renderer/aov.js.map +1 -1
  98. package/lib/renderer/aovDisplay.js +2 -2
  99. package/lib/renderer/aovDisplay.js.map +1 -1
  100. package/lib/renderer/binnedSahBvh.d.ts +2 -1
  101. package/lib/renderer/binnedSahBvh.js +24 -17
  102. package/lib/renderer/binnedSahBvh.js.map +1 -1
  103. package/lib/renderer/bvhAccel.d.ts +3 -1
  104. package/lib/renderer/bvhAccel.js +36 -6
  105. package/lib/renderer/bvhAccel.js.map +1 -1
  106. package/lib/renderer/cameraUniform.d.ts +1 -1
  107. package/lib/renderer/cameraUniform.js +6 -2
  108. package/lib/renderer/cameraUniform.js.map +1 -1
  109. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  110. package/lib/renderer/causticDiagnostics.js +5 -0
  111. package/lib/renderer/causticDiagnostics.js.map +1 -0
  112. package/lib/renderer/causticEmission.d.ts +10 -0
  113. package/lib/renderer/causticEmission.js +40 -0
  114. package/lib/renderer/causticEmission.js.map +1 -0
  115. package/lib/renderer/causticUniform.d.ts +12 -0
  116. package/lib/renderer/causticUniform.js +22 -0
  117. package/lib/renderer/causticUniform.js.map +1 -0
  118. package/lib/renderer/caustics.d.ts +16 -0
  119. package/lib/renderer/caustics.js +93 -0
  120. package/lib/renderer/caustics.js.map +1 -0
  121. package/lib/renderer/compactVertices.d.ts +14 -0
  122. package/lib/renderer/compactVertices.js +124 -0
  123. package/lib/renderer/compactVertices.js.map +1 -0
  124. package/lib/renderer/easu.d.ts +11 -0
  125. package/lib/renderer/easu.js +156 -0
  126. package/lib/renderer/easu.js.map +1 -0
  127. package/lib/renderer/geometryUpdateState.d.ts +1 -0
  128. package/lib/renderer/geometryUpdateState.js.map +1 -1
  129. package/lib/renderer/geometryUpdates.js +3 -2
  130. package/lib/renderer/geometryUpdates.js.map +1 -1
  131. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  132. package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
  133. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  134. package/lib/renderer/glsl/aovTrace.frag.js +45 -37
  135. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
  136. package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
  137. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
  138. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
  139. package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
  140. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
  141. package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
  142. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  143. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  144. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  145. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
  146. package/lib/renderer/glsl/chunks/intersect.glsl.js +478 -465
  147. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  148. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  149. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
  150. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  151. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
  152. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  153. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  154. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  155. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +70 -63
  156. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  157. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +89 -75
  158. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  159. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  160. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +160 -118
  161. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  162. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
  163. package/lib/renderer/glsl/chunks/sampling.glsl.js +88 -91
  164. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  165. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  166. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
  167. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
  168. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
  169. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  170. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  171. package/lib/renderer/glsl/depthQuery.frag.js +13 -7
  172. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  173. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  174. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  175. package/lib/renderer/glsl/rayTrace.frag.js +338 -252
  176. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  177. package/lib/renderer/glsl/shadowCatcher.frag.js +27 -26
  178. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  179. package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
  180. package/lib/renderer/gpuMemory.js +1 -1
  181. package/lib/renderer/gpuMemory.js.map +1 -1
  182. package/lib/renderer/lightSampling.d.ts +3 -2
  183. package/lib/renderer/lightSampling.js +14 -8
  184. package/lib/renderer/lightSampling.js.map +1 -1
  185. package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
  186. package/lib/renderer/openPbrEnergyLut.js +18 -1
  187. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  188. package/lib/renderer/pathLimits.d.ts +5 -4
  189. package/lib/renderer/pathLimits.js +6 -5
  190. package/lib/renderer/pathLimits.js.map +1 -1
  191. package/lib/renderer/prepareMeshBVH.d.ts +2 -0
  192. package/lib/renderer/prepareMeshBVH.js +5 -3
  193. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  194. package/lib/renderer/progressiveScheduler.js +5 -4
  195. package/lib/renderer/progressiveScheduler.js.map +1 -1
  196. package/lib/renderer/renderPipeline.d.ts +5 -0
  197. package/lib/renderer/renderPipeline.js +1 -0
  198. package/lib/renderer/renderPipeline.js.map +1 -1
  199. package/lib/renderer/researchTransport.d.ts +31 -0
  200. package/lib/renderer/researchTransport.js +5 -0
  201. package/lib/renderer/researchTransport.js.map +1 -0
  202. package/lib/renderer/sceneAssembly.d.ts +1 -1
  203. package/lib/renderer/sceneAssembly.js +4 -3
  204. package/lib/renderer/sceneAssembly.js.map +1 -1
  205. package/lib/renderer/sceneChangeDetector.d.ts +1 -1
  206. package/lib/renderer/sceneChangeDetector.js +3 -1
  207. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  208. package/lib/renderer/sceneLayoutSchema.d.ts +2 -0
  209. package/lib/renderer/sceneLayoutSchema.js +3 -3
  210. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  211. package/lib/renderer/scenePreparation.d.ts +3 -2
  212. package/lib/renderer/scenePreparation.js +18 -2
  213. package/lib/renderer/scenePreparation.js.map +1 -1
  214. package/lib/renderer/scratchSampling.js +6 -6
  215. package/lib/renderer/spectrum.d.ts +21 -0
  216. package/lib/renderer/spectrum.js +154 -0
  217. package/lib/renderer/spectrum.js.map +1 -0
  218. package/lib/renderer/staticBvhPreparation.d.ts +9 -0
  219. package/lib/renderer/staticBvhPreparation.js +8 -2
  220. package/lib/renderer/staticBvhPreparation.js.map +1 -1
  221. package/lib/renderer/surfaceHit.d.ts +10 -0
  222. package/lib/renderer/surfaceHit.js +22 -0
  223. package/lib/renderer/surfaceHit.js.map +1 -0
  224. package/lib/renderer/tangentRequirements.d.ts +2 -0
  225. package/lib/renderer/tangentRequirements.js +7 -0
  226. package/lib/renderer/tangentRequirements.js.map +1 -0
  227. package/lib/renderer/textureAtlas.d.ts +4 -0
  228. package/lib/renderer/textureAtlas.js +48 -2
  229. package/lib/renderer/textureAtlas.js.map +1 -1
  230. package/lib/renderer/webgl.js +4 -0
  231. package/lib/renderer/webgl.js.map +1 -1
  232. package/lib/renderer/webglLightSampling.d.ts +39 -0
  233. package/lib/renderer/webglLightSampling.js +15 -0
  234. package/lib/renderer/webglLightSampling.js.map +1 -0
  235. package/lib/renderer/webglVertexAttributes.d.ts +17 -0
  236. package/lib/renderer/webglVertexAttributes.js +44 -0
  237. package/lib/renderer/webglVertexAttributes.js.map +1 -0
  238. package/lib/renderer/wgpuBindlessSource.js +3 -3
  239. package/lib/renderer/wgpuMaterialConstants.js +4 -3
  240. package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
  241. package/lib/renderer/wgpuSceneUniform.js +2 -2
  242. package/lib/renderer/wgpuSceneUniform.js.map +1 -1
  243. package/lib/renderer/wgpuShaderSource.d.ts +22 -0
  244. package/lib/renderer/wgpuShaderSource.js +3 -1
  245. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  246. package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
  247. package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
  248. package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
  249. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  250. package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
  251. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  252. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
  253. package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
  254. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
  255. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
  256. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
  257. package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
  258. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
  259. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
  260. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
  261. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  262. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  263. package/lib/renderer/wgsl/causticLight.compute.js +539 -0
  264. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  265. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  266. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  267. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  268. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  269. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  270. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  271. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  272. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  273. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  274. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  275. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  276. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  277. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  278. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
  279. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
  280. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +634 -620
  281. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  282. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
  283. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +23 -21
  284. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  285. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +3 -1
  286. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +77 -74
  287. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  288. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +795 -795
  289. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
  290. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  291. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -1
  292. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +45 -29
  293. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  294. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  295. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
  296. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  297. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  298. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +228 -189
  299. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  300. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  301. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
  302. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  303. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  304. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +88 -92
  305. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  306. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  307. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
  308. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
  309. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
  310. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  311. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
  312. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
  313. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
  314. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
  315. package/lib/renderer/wgsl/compose.frag.wgsl.js +100 -98
  316. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  317. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  318. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  319. package/lib/renderer/wgsl/depthQuery.wgsl.js +12 -3
  320. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  321. package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
  322. package/lib/renderer/wgsl/easu.wgsl.js +80 -0
  323. package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
  324. package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
  325. package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
  326. package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
  327. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  328. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
  329. package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
  330. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  331. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  332. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  333. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  334. package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
  335. package/lib/renderer/wgsl/rayTrace.compute.d.ts +23 -1
  336. package/lib/renderer/wgsl/rayTrace.compute.js +531 -543
  337. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  338. package/lib/scene/MaterialState.d.ts +2 -2
  339. package/lib/scene/MaterialState.js +2 -2
  340. package/lib/scene/MaterialState.js.map +1 -1
  341. package/lib/scene/Scene.js.map +1 -1
  342. package/lib/settings/render.d.ts +22 -0
  343. package/lib/settings/render.js +2 -0
  344. package/lib/settings/render.js.map +1 -1
  345. package/lib/util/fromTHREE.js +23 -16
  346. package/lib/util/fromTHREE.js.map +1 -1
  347. package/lib/version.d.ts +1 -1
  348. package/lib/version.js +1 -1
  349. package/lib/version.js.map +1 -1
  350. package/llms.txt +2 -1
  351. package/package.json +7 -4
  352. package/lib/oidnBundledWeights.cdn.d.ts +0 -2
  353. package/lib/oidnBundledWeights.cdn.js +0 -5
  354. package/lib/oidnBundledWeights.cdn.js.map +0 -1
  355. package/lib/renderer/bvh.worker.d.ts +0 -1
  356. package/lib/renderer/bvh.worker.js +0 -16
  357. package/lib/renderer/bvh.worker.js.map +0 -1
  358. package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
  359. package/lib/renderer/bvhWorkerBuild.js +0 -17
  360. package/lib/renderer/bvhWorkerBuild.js.map +0 -1
  361. package/lib/renderer/lightCore.d.ts +0 -12
  362. package/lib/renderer/lightCore.js +0 -13
  363. package/lib/renderer/lightCore.js.map +0 -1
  364. package/lib/renderer/materialCore.d.ts +0 -8
  365. package/lib/renderer/materialCore.js +0 -9
  366. package/lib/renderer/materialCore.js.map +0 -1
  367. package/lib/scene/PixelTexture.d.ts +0 -6
  368. package/lib/scene/PixelTexture.js +0 -10
  369. package/lib/scene/PixelTexture.js.map +0 -1
  370. package/lib/util/studioLighting.d.ts +0 -18
  371. package/lib/util/studioLighting.js +0 -36
  372. package/lib/util/studioLighting.js.map +0 -1
@@ -1,7 +1,13 @@
1
- import { MAX_PATH_EVENTS } from '../pathLimits.js';
1
+ import { spectralPrefixWgsl, prefixCheckpoint, prefixSave, prefixRestore, prefixRandomBindings } from './chunks/spectralPrefix.wgsl.js';
2
+ import { photonQuerySource } from './photonMap.compute.js';
3
+ import backgroundWgsl from './chunks/background.wgsl.js';
4
+ import { researchTransport } from '../researchTransport.js';
5
+ import { causticPartitionWGSL } from './chunks/caustics.wgsl.js';
6
+ import { MAX_PATH_EVENTS_WEBGL } from '../pathLimits.js';
2
7
  import shadowCatcherAccumulationWGSL from './chunks/shadowCatcherAccumulation.wgsl.js';
3
8
  import reflectanceWGSL from './aovReflectance.wgsl.js';
4
9
  import aovTraceWGSL from './aovTrace.wgsl.js';
10
+ import aovTraceDisplayWGSL from './aovTraceDisplay.wgsl.js';
5
11
  import depthQueryWGSL from './depthQuery.wgsl.js';
6
12
  // Portions adapted from ray-tracing-renderer@0.10.15
7
13
  // (https://github.com/hoverinc/ray-tracing-renderer).
@@ -18,15 +24,35 @@ import { createSampleMaterialWgsl } from './chunks/sampleMaterial.wgsl.js';
18
24
  import sampleLightWgsl from './chunks/sampleLight.wgsl.js';
19
25
  import { createOpenPbrBsdfWgsl } from './chunks/openPbrBsdf.wgsl.js';
20
26
  import samplingWgsl from './chunks/sampling.wgsl.js';
27
+ import { spectrumWgsl } from '../spectrum.js';
21
28
  import sampleShadowCatcherWgsl from './chunks/sampleShadowCatcher.wgsl.js';
22
29
  import envMapWgsl from './chunks/envMap.wgsl.js';
23
30
  import uvProjectionWgsl from './chunks/uvProjection.wgsl.js';
24
31
  export const WORKGROUP_SIZE = 8;
25
32
  /** Generates the WebGPU megakernel path tracing compute shader. */
26
- export default function rayTraceCompute({ hasDisplacement, hasAnisotropyDirections = false, hasCoatNormals = false, hasAlpha = true, hasSceneAlpha = true, blasLayoutMask = 1, spectral, sceneCapabilities, dynamicEnvironment = false, materialCapabilities = ALL_MATERIAL_SHADER_CAPABILITIES, lightCapabilities }, sceneIntersections = '', pathDiagnostic = false, inputHooks) {
33
+ export default function rayTraceCompute(options, sceneIntersections = '', pathDiagnostic = false, inputHooks) {
34
+ const maxPathEvents = options.maxPathEvents ?? MAX_PATH_EVENTS_WEBGL;
35
+ const research = researchTransport()?.compute(options);
36
+ const enabled = research?.enabled ?? false;
37
+ const partitionDepth = research?.maxDepth ?? 20;
38
+ const debugGroup = research?.debugGroup ?? options.debugGroup ?? -1;
39
+ let { compactVertices = false, hasDisplacement, workgroupSize = WORKGROUP_SIZE, lightTracing = false, photonMapping = false, photonMaxDepth = 20, hasAnisotropyDirections = false, hasCoatNormals = false, hasAlpha = true, hasSceneAlpha = true, blasLayoutMask = 1, spectral, sceneCapabilities, dynamicEnvironment = false, materialCapabilities = ALL_MATERIAL_SHADER_CAPABILITIES, lightCapabilities } = options;
27
40
  hasAnisotropyDirections ||= hasCoatNormals;
28
41
  const deterministicPrimaryAlpha = hasAlpha;
29
42
  const hasShadowCatcher = sceneCapabilities === undefined || (sceneCapabilities & WGPU_SCENE_FEATURE_BITS.HAS_SHADOW_CATCHER) !== 0;
43
+ // MNEE can refract a wavelength-dependent connection at an ordinary receiver,
44
+ // before the camera path reaches any Cauchy boundary. Preserve its independent
45
+ // wavelength paths until a connection-solver checkpoint is available.
46
+ const sharePrefix = options.shareSpectralPrefix ?? false;
47
+ const surfacePrefix = {
48
+ path: ['Path', 'path'], si: ['SurfaceInteraction', '*si'], ma: ['OpenPbrResolvedMaterial', '*ma'],
49
+ aux: ['RayTraceAuxiliary', '*outAux'], depth: ['i32', 'depth'], event: ['i32', 'event'],
50
+ ignored: ['bool', 'sampleIgnored'], opaque: ['bool', 'isNotTransparent'], ...prefixRandomBindings
51
+ };
52
+ const flatPrefix = {
53
+ ...surfacePrefix, si: ['SurfaceInteraction', 'si'], ma: ['OpenPbrResolvedMaterial', 'ma'],
54
+ aux: ['RayTraceAuxiliary', 'wavelengthAux']
55
+ };
30
56
  const primaryVariables = /* wgsl */ `
31
57
  var si: SurfaceInteraction;
32
58
  var ma: OpenPbrResolvedMaterial;
@@ -44,10 +70,10 @@ si.barycentrics = vec2f(0.0);
44
70
 
45
71
  (*outAux).albedo = vec3f(1.0);
46
72
  (*outAux).normal = select(si.normal, -si.normal, dot(si.normal, ray.d) > 0.0);
47
- var aa: Path;
48
- aa.ray = ray;
49
- aa.fromEye = true;
50
- (*outAux).shadowCounts = sampleShadowCatcher(si, 0, &aa);
73
+ var path: Path;
74
+ path.ray = ray;
75
+ path.fromEye = true;
76
+ (*outAux).shadowCounts = sampleShadowCatcher(si, 0, &path);
51
77
 
52
78
 
53
79
  return vec4f(1.0);
@@ -55,7 +81,7 @@ return vec4f(1.0);
55
81
  else {
56
82
  if (HAS_BEVEL && rtUniform.bevel != 0) {
57
83
  if (ma.bevel > 0.0) {
58
- si.normal = nj(si, ma.bevel);
84
+ si.normal = kB(si, ma.bevel);
59
85
  }
60
86
  }
61
87
 
@@ -83,71 +109,77 @@ si.albedoSampled = ma.transmissionWeight > 0.5;
83
109
 
84
110
  ${commonWgsl}
85
111
 
86
- ${rayTraceCoreWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals, lightCapabilities })}
112
+ ${rayTraceCoreWgsl({ independentTextures: options.independentTextures, compactVertices, cameraProjectionInverse: options.cameraProjectionInverse, hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals, lightCapabilities, caustics: enabled || lightTracing || photonMapping })}
87
113
 
88
114
  ${uvProjectionWgsl}
89
115
 
90
- ${createMaterialBufferWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals,
116
+ ${createMaterialBufferWgsl({ independentTextures: options.independentTextures, hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals,
117
+ caustics: enabled || lightTracing || photonMapping,
91
118
  hasTransmission: (materialCapabilities & MATERIAL_SHADER_CAPABILITIES.transmission) !== 0,
92
119
  hasMetalness: (materialCapabilities & MATERIAL_SHADER_CAPABILITIES.metal) !== 0 })}
93
120
 
94
- ${createIntersectionWgsl({ hasDisplacement, blasLayoutMask, hasAnisotropyDirections, hasCoatNormals, sceneIntersections })}
121
+ ${createIntersectionWgsl({ compactVertices, perInstanceBounds: options.perInstanceBounds, hasDisplacement, blasLayoutMask, hasAnisotropyDirections, hasCoatNormals, sceneIntersections })}
95
122
  ${randWgsl}
96
123
  ${randomWgsl}
97
124
  ${envMapWgsl}
98
125
 
99
126
  ${samplingWgsl}
127
+ ${spectrumWgsl}
100
128
  ${createOpenPbrBsdfWgsl(hasAnisotropyDirections, hasCoatNormals)}
101
129
  ${sampleLightWgsl}${inputHooks?.declarations ?? ''}
102
130
 
103
131
 
104
- var<private> vg: u32 = 0u;
132
+ var<private> bounceIndex: u32 = 0u;
105
133
 
106
134
 
107
135
 
108
- fn kB() -> u32 {
136
+ fn kL() -> u32 {
109
137
  return u32(max(rtUniform.directLightCandidates, 1));
110
138
  }
111
139
 
112
140
 
113
141
 
114
142
 
115
- fn qx(ys: u32) -> f32 {
143
+ fn rA(AT: u32) -> f32 {
116
144
 
117
145
 
118
146
 
119
147
 
120
148
  if (SAMPLING_PATTERN == 2) { _ = rand(); }
121
- let kI = aZ.x + aZ.y * u32(rtUniform.outputSize.x);
122
- let key = ar(ar(kI, aQ), rtUniform.sequenceSeed);
123
- let dimension = ar(bT, ys) ^ 0xa511e9b3u;
124
- return f32(dG(key ^ dimension) >> 8u) * (1.0 / 16777216.0);
149
+ let kT = aJ.x + aJ.y * u32(rtUniform.outputSize.x);
150
+ let key = ak(ak(kT, aC), rtUniform.sequenceSeed);
151
+ let dimension = ak(samplingBounce, AT) ^ 0xa511e9b3u;
152
+ return f32(cD(key ^ dimension) >> 8u) * (1.0 / 16777216.0);
125
153
  }
126
154
 
127
155
 
128
156
 
129
- fn uS(fA: f32, scatteringPdf: f32) -> f32 {
130
- let candidateCount = kB();
157
+ fn wM(lightPdf: f32, scatteringPdf: f32) -> f32 {
158
+ let candidateCount = kL();
131
159
  if (candidateCount <= 1u) {
132
- return aK(fA, scatteringPdf);
160
+ return aG(lightPdf, scatteringPdf);
133
161
  }
134
- let jb = f32(candidateCount) * fA;
135
- return jb /
136
- max(jb + scatteringPdf, 1e-20);
162
+ let weightedLightPdf = f32(candidateCount) * lightPdf;
163
+ return weightedLightPdf /
164
+ max(weightedLightPdf + scatteringPdf, 1e-20);
137
165
  }
138
166
 
139
167
 
140
- fn gj(scatteringPdf: f32, fA: f32) -> f32 {
141
- let candidateCount = kB();
168
+ fn gm(scatteringPdf: f32, lightPdf: f32) -> f32 {
169
+ let candidateCount = kL();
142
170
  if (candidateCount <= 1u) {
143
- return aK(scatteringPdf, fA);
171
+ return aG(scatteringPdf, lightPdf);
144
172
  }
145
- let jb = f32(candidateCount) * fA;
173
+ let weightedLightPdf = f32(candidateCount) * lightPdf;
146
174
  return scatteringPdf /
147
- max(scatteringPdf + jb, 1e-20);
175
+ max(scatteringPdf + weightedLightPdf, 1e-20);
148
176
  }
149
177
 
150
- ${createSampleMaterialWgsl(hasAnisotropyDirections, hasCoatNormals)}
178
+ ${enabled || lightTracing || photonMapping ? causticPartitionWGSL(enabled, lightTracing, photonMapping, partitionDepth, debugGroup >= 30, photonMaxDepth) : ''}${research?.declarations ?? ''}${photonMapping ? `const CAUSTIC_LIGHT_TRACING=${lightTracing};
179
+ const CAUSTIC_MNEE=${enabled};
180
+ const CAUSTIC_MNEE_MAX_DEPTH=${partitionDepth}u;
181
+ const CAUSTIC_PHOTON_MAX_DEPTH=${photonMaxDepth}u;
182
+ ` + photonQuerySource(debugGroup, !lightTracing && (options.photonDirectSubset ?? true)) : ''}${createSampleMaterialWgsl(hasAnisotropyDirections, hasCoatNormals, enabled || lightTracing || photonMapping, research?.contribution, photonMapping, options.channelIndependentRis)}
151
183
  ${sampleShadowCatcherWgsl}
152
184
 
153
185
 
@@ -159,24 +191,24 @@ ${shadowCatcherAccumulationWGSL}
159
191
  @group(3) @binding(3) var<storage, read_write> outShadowCatcher: array<ShadowCatcherAccumulation>;
160
192
 
161
193
 
162
- fn ie(
163
- gv: u32,
194
+ fn ij(
195
+ gx: u32,
164
196
  radiance: vec3f,
165
197
  normal: vec3f
166
198
  ) {
167
199
  if (rtUniform.varianceMoments != 0) {
168
200
  let value = dot(radiance, luminance);
169
- outNormal[gv] += vec4f(value * value, 0.0, 0.0, 1.0);
201
+ outNormal[gx] += vec4f(value * value, 0.0, 0.0, 1.0);
170
202
  }
171
203
  else {
172
- outNormal[gv] += vec4f(normal, 1.0);
204
+ outNormal[gx] += vec4f(normal, 1.0);
173
205
  }
174
206
  }
175
207
 
176
208
 
177
209
 
178
- fn ji(gv: u32, value: f32) {
179
- outShadowCatcher[gv].moments += vec4f(value, value * value, 0.0, 0.0);
210
+ fn ju(gx: u32, value: f32) {
211
+ outShadowCatcher[gx].moments += vec4f(value, value * value, 0.0, 0.0);
180
212
  }
181
213
 
182
214
 
@@ -190,123 +222,23 @@ isBlank: bool,
190
222
  shadowCounts: vec2f,
191
223
  }
192
224
 
193
- fn dK(point: vec3f, height: f32, radius: f32) -> f32 {
194
- let ge = length(point);
195
- if (ge < 0.00001) {
196
- return -radius;
197
- }
198
-
199
- let iX = radius * point.y / ge;
200
- let iL = -1.5 * height;
201
- var eH: f32;
202
- if (iX >= 0.0) {
203
- eH = radius;
204
- }
205
- else if (iX < iL) {
206
- eH = -height * ge / point.y;
207
- }
208
- else {
209
- let cL = 1.0
210
- - iX * iX / (3.0 * iL * iL);
211
- eH = radius * cL;
212
- }
213
- return ge - eH;
214
- }
215
-
216
- fn fd(origin: vec3f, direction: vec3f) -> vec3f {
217
- if (!USE_GROUNDED_BACKGROUND) {
218
- return direction;
219
- }
220
- let params = rtUniform.groundedBackgroundParams;
221
- let cf = normalize(direction);
222
- let center = vec3f(
223
- rtUniform.groundedBackgroundCenter.x,
224
- params.z + params.x,
225
- rtUniform.groundedBackgroundCenter.y
226
- );
227
- let bI = origin - center;
228
- let eT = dot(bI, cf);
229
- let br = eT * eT
230
- - dot(bI, bI) + params.y * params.y;
231
- if (
232
- br <= 0.0
233
- || dK(bI, params.x, params.y) > 0.0
234
- ) {
235
- return direction;
236
- }
237
-
238
- var cM = -eT + sqrt(br);
239
- if (cM <= 0.0) {
240
- return direction;
241
- }
242
-
243
- let oK = bI + cf * cM;
244
- if (oK.y >= 0.0) {
245
- return normalize(oK);
246
- }
247
-
248
- if (cf.y < -0.00001 && params.y > 1.5 * params.x) {
249
- let ir = (-params.x - bI.y) / cf.y;
250
- let oB = bI + cf * ir;
251
- let pe = (2.0 / 3.0)
252
- * sqrt(params.y * params.y - 2.25 * params.x * params.x);
253
- if (ir > 0.0 && length(oB.xz) <= pe) {
254
- return normalize(oB);
255
- }
256
- }
257
-
258
- var cV = 0.0;
259
- for (var i = 0; i < 14; i++) {
260
- let fB = (cV + cM) * 0.5;
261
- let qy = bI + cf * fB;
262
- if (dK(qy, params.x, params.y) > 0.0) {
263
- cM = fB;
264
- }
265
- else {
266
- cV = fB;
267
- }
268
- }
269
- let hit = bI + cf * ((cV + cM) * 0.5);
270
- return normalize(hit);
271
- }
272
-
273
- fn hX(ray: Ray) -> vec4f {
274
- var bg = vec4f(0.0);
275
- if (USE_BACKGROUND_MAP) {
276
- let d = fd(ray.o, ray.d);
277
- let t = rtUniform.backgroundMapTransform;
278
- let qZ = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);
279
- let rotation = rtUniform.backgroundMapRotation;
280
- let hn = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * qZ;
281
- let bc = textureLinear(backgroundMap, eV(hn));
282
- bg = vec4f(bc.rgb * t.z, bc.a);
283
- }
284
- else if (USE_BACKGROUND) {
285
- bg = rtUniform.backgroundColor;
286
- }
287
- else if (USE_ENVMAP) {
288
- bg = textureLinear(envMap, dm(ray.d));
289
- }
290
- return bg;
291
- }
292
-
293
- fn di(ray: Ray, wavelength: f32) -> vec4f {
294
- let bg = hX(ray);
225
+ ${backgroundWgsl}fn cS(ray: Ray, channel: i32) -> vec4f {
226
+ let bg = fI(ray);
295
227
  if (SPECTRAL) {
296
- return vec4f(aj(bg.rgb, wavelength), bg.a);
228
+ return vec4f(sampling_spectral_rgb_filter(bg.rgb, channel), bg.a);
297
229
  }
298
230
  return bg;
299
231
  }
300
232
 
301
233
 
302
234
 
303
- fn nY(uv: vec2f, aa: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, fm: ptr<function, bool>) {
304
- *fm = false;
305
- bT = u32(max(*depth, 0));
235
+ fn mD(uv: vec2f, path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, fg: ptr<function, bool>) {
236
+ *fg = false;
237
+ samplingBounce = u32(max(*depth, 0));
306
238
  let matType = (*ma).materialType;
307
239
  let isShadowCatcher = ${hasShadowCatcher ? /* wgsl */ `matType == SHADOW_CATCHER` : /* wgsl */ `false`};
308
240
  if (isShadowCatcher) {
309
- if ((*aa).fromEye) {
241
+ if ((*path).fromEye) {
310
242
  (*si).hit = false;
311
243
  }
312
244
  else {
@@ -314,37 +246,37 @@ else {
314
246
 
315
247
 
316
248
  if (USE_ENVMAP) {
317
- if ((*aa).isNextRefraction) {
249
+ if ((*path).isNextRefraction) {
318
250
 
319
251
 
320
- let bg = di(
321
- (*aa).ray,
322
- (*si).wavelength
252
+ let bg = cS(
253
+ (*path).ray,
254
+ (*si).spectralChannel
323
255
  );
324
- let da = select(gj((*aa).scatteringPdf,
325
- iT(dm((*aa).ray.d)) * rtUniform.envLightPmf),
326
- 1.0, (*aa).scatteringIsDelta);
327
- (*aa).li += da * (*aa).beta * bg.rgb * bg.a;
328
- (*aa).alpha = max((*aa).alpha, bg.a);
256
+ let cP = select(gm((*path).scatteringPdf,
257
+ envMapPdf(cU((*path).ray.d)) * rtUniform.envLightPmf),
258
+ 1.0, (*path).scatteringIsDelta);
259
+ (*path).li += cP * (*path).beta * bg.rgb * bg.a;
260
+ (*path).alpha = max((*path).alpha, bg.a);
329
261
  }
330
262
  else {
331
- let vo = dm((*aa).ray.d);
332
- var emission = textureLinear(envMap, vo).rgb;
263
+ let xp = cU((*path).ray.d);
264
+ var emission = textureLinear(envMap, xp).rgb;
333
265
  if (SPECTRAL) {
334
- emission = aj(emission, (*si).wavelength);
266
+ emission = sampling_spectral_rgb_filter(emission, (*si).spectralChannel);
335
267
  }
336
- (*aa).li += (*aa).beta * emission *
337
- gj((*aa).scatteringPdf, iT(vo));
268
+ (*path).li += (*path).beta * emission *
269
+ gm((*path).scatteringPdf, envMapPdf(xp));
338
270
  }
339
271
  }
340
272
  else {
341
- let bg = di(
342
- (*aa).ray,
343
- (*si).wavelength
273
+ let bg = cS(
274
+ (*path).ray,
275
+ (*si).spectralChannel
344
276
  );
345
- (*aa).li += (*aa).beta * bg.rgb * bg.a;
277
+ (*path).li += (*path).beta * bg.rgb * bg.a;
346
278
  }
347
- (*aa).abort = true;
279
+ (*path).abort = true;
348
280
  return;
349
281
  }
350
282
  }
@@ -352,40 +284,40 @@ if (!(*si).hit) {
352
284
 
353
285
 
354
286
 
355
- let bg = di(
356
- (*aa).ray,
357
- (*si).wavelength
287
+ let bg = cS(
288
+ (*path).ray,
289
+ (*si).spectralChannel
358
290
  );
359
- if ((*aa).fromEye) {
291
+ if ((*path).fromEye) {
360
292
 
361
- (*aa).li = (*aa).beta * bg.rgb * bg.a;
362
- (*aa).alpha = bg.a;
293
+ (*path).li = (*path).beta * bg.rgb * bg.a;
294
+ (*path).alpha = bg.a;
363
295
 
364
296
  (*outAux).isBlank = bg.a < 0.001 ||
365
297
  (USE_BACKGROUND && !USE_BACKGROUND_MAP);
366
298
  }
367
299
  else {
368
- let cam = fj(uv);
369
- let nK = dot(cam.d, (*aa).ray.d) > 0.0;
300
+ let cam = cV(uv);
301
+ let ou = dot(cam.d, (*path).ray.d) > 0.0;
370
302
  if (rtUniform.transmissiveOutputAlphaMin < 1.0) {
371
- if (nK) {
372
- (*aa).alpha = max((*aa).alpha, bg.a);
303
+ if (ou) {
304
+ (*path).alpha = max((*path).alpha, bg.a);
373
305
  } else {
374
- (*aa).alpha = 1.0;
306
+ (*path).alpha = 1.0;
375
307
  }
376
308
  }
377
309
  if (!USE_ENVMAP) {
378
310
 
379
311
 
380
- if (nK) {
312
+ if (ou) {
381
313
 
382
314
 
383
- (*aa).li += (*aa).beta *
384
- gj((*aa).scatteringPdf, 1.0) * bg.rgb;
315
+ (*path).li += (*path).beta *
316
+ gm((*path).scatteringPdf, 1.0) * bg.rgb;
385
317
  }
386
318
  }
387
319
  }
388
- (*aa).abort = true;
320
+ (*path).abort = true;
389
321
  return;
390
322
  }
391
323
 
@@ -396,28 +328,28 @@ let alpha = clamp((*ma).alpha, 0.0, 1.0);
396
328
  if (alpha < 1.0) {
397
329
 
398
330
 
399
- if (alpha <= 0.0 || eC(3u) > alpha) {
400
- (*fm) = true;
331
+ if (alpha <= 0.0 || cm(3u) > alpha) {
332
+ (*fg) = true;
401
333
  }
402
334
  }
403
- if (!(*fm) && rtUniform.transmissiveOutputAlphaMin < 1.0) {
335
+ if (!(*fg) && rtUniform.transmissiveOutputAlphaMin < 1.0) {
404
336
 
405
337
 
406
338
  let outputAlpha = max(1.0 - (*ma).transmissionWeight, 1.0 - pow(1.0 - rtUniform.transmissiveOutputAlphaMin, f32(*depth)));
407
- (*aa).alpha = max(outputAlpha, (*aa).alpha);
339
+ (*path).alpha = max(outputAlpha, (*path).alpha);
408
340
  }
409
- if (!(*fm)) {
410
- vg = u32(max(*depth, 0));
411
- mL(si, ma, aa);
341
+ if (!(*fg)) {
342
+ bounceIndex = u32(max(*depth, 0));
343
+ nB(si, ma, path);
412
344
  }
413
345
  else {
414
346
 
415
347
 
416
- (*aa).ray.o = (*si).position + (*aa).ray.d * EPS;
348
+ (*path).ray.o = (*si).position + (*path).ray.d * EPS;
417
349
  }
418
350
  }
419
351
 
420
- if (!(*si).albedoSampled && !(*fm)) {
352
+ if (!(*si).albedoSampled && !(*fg)) {
421
353
 
422
354
  if ((matType == STANDARD || matType == UNLIT)) {
423
355
  if (!((*ma).transmissionWeight > 0.5 ||
@@ -442,34 +374,34 @@ if (*depth > 4) {
442
374
 
443
375
 
444
376
  if (USE_RR) {
445
- if (*depth >= RR_MAX && !(*fm)) {
446
- let pG = (*aa).beta;
377
+ if (*depth >= select(2, RR_MAX, (*path).scatteringMediumEntered) && !(*fg)) {
378
+ let qv = (*path).beta;
447
379
 
448
- let pn = max(max(pG.x, pG.y), pG.z);
449
- let q: f32 = max(0.0, 1.0 - pn);
450
- if (dp(cE(RUSSIAN_ROULETTE)) < q) {
380
+ let ql = max(max(qv.x, qv.y), qv.z);
381
+ let q: f32 = max(0.0, 1.0 - ql);
382
+ if (sample1D(aX(RUSSIAN_ROULETTE)) < q) {
451
383
 
452
384
 
453
- (*aa).alpha = 1.0;
454
- (*aa).abort = true;
385
+ (*path).alpha = 1.0;
386
+ (*path).abort = true;
455
387
  }
456
388
  else {
457
- (*aa).beta /= 1.0 - q;
389
+ (*path).beta /= 1.0 - q;
458
390
  }
459
391
  }
460
392
  }
461
- if ((*aa).abort) {
393
+ if ((*path).abort) {
462
394
  return;
463
395
  }
464
396
 
465
397
 
466
398
  }
467
399
 
468
- fn kl(aa: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, aJ: bool) {
400
+ fn gN(path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, sampleIgnored: bool) {
469
401
  if (SPECTRAL) {
470
402
 
471
403
  if ((*ma).transmissionWeight > 0.001) {
472
- (*ma).specularIor = ee(
404
+ (*ma).specularIor = sampling_cauchy_ior(
473
405
  (*si).wavelength,
474
406
  (*ma).specularIor,
475
407
  (*ma).transmissionDispersionScale,
@@ -478,304 +410,329 @@ if ((*ma).transmissionWeight > 0.001) {
478
410
  }
479
411
  }
480
412
 
481
- if (aJ) {
413
+ if (sampleIgnored) {
482
414
  return;
483
415
  }
484
416
 
485
417
 
486
418
  var lightSample: LightSampleRec;
487
- let hM = eC(3u) < (*ma).alpha;
419
+ let hN = cm(3u) < (*ma).alpha;
488
420
  for (var i = 0; i < rtUniform.lightsCount; i++) {
489
421
 
490
422
  let light: Light = analyticLights[i];
491
- let d = nr((*aa).ray, light, &lightSample);
423
+ let d = iB((*path).ray, light, &lightSample);
492
424
  lightSample.pdf *= light.selectionPmf;
493
- let lY = (*si).hit && d > distance((*si).position, (*aa).ray.o);
494
- if (d != INF && !(lY && hM)) {
495
- let fl = gj((*aa).scatteringPdf, lightSample.pdf);
425
+ let mz = (*si).hit && d > distance((*si).position, (*path).ray.o);
426
+ if (d != INF && !(mz && hN)) {
427
+ let misWeight = gm((*path).scatteringPdf, lightSample.pdf);
496
428
  if (SPECTRAL) {
497
- lightSample.emission = aj(lightSample.emission, (*si).wavelength);
429
+ lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, (*si).spectralChannel);
498
430
  }
499
- (*aa).li += fl * (*aa).beta * lightSample.emission;
500
- (*aa).alpha = 1.0;
501
- (*aa).abort = true;
431
+ ${enabled || lightTracing || photonMapping ? 'if (!causticHitOwned(*path, true, true)) { causticHotRecord(*path,misWeight*lightSample.emission,2u); ' : ''}(*path).li += misWeight * (*path).beta * lightSample.emission;${enabled || lightTracing || photonMapping ? ' }' : ''}
432
+ (*path).alpha = 1.0;
433
+ (*path).abort = true;
502
434
  }
503
435
  }
504
436
 
505
437
  if (USE_ENVMAP) {
506
- if (!((*si).hit && hM)) {
507
- if ((*aa).isNextRefraction) {
438
+ if (!((*si).hit && hN)) {${lightTracing || photonMapping ? /* wgsl */ `
439
+ if(causticHitOwned(*path,false,true)){(*path).abort=true;return;}` : ''}
440
+ if ((*path).isNextRefraction) {
508
441
 
509
442
 
510
443
 
511
- let bg = di(
512
- (*aa).ray,
513
- (*si).wavelength
444
+ let bg = cS(
445
+ (*path).ray,
446
+ (*si).spectralChannel
514
447
  );
515
- let da = select(gj((*aa).scatteringPdf,
516
- iT(dm((*aa).ray.d)) * rtUniform.envLightPmf),
517
- 1.0, (*aa).scatteringIsDelta);
518
- (*aa).li += da * (*aa).beta * bg.rgb * bg.a;
519
- (*aa).alpha = max((*aa).alpha, bg.a);
520
- (*aa).abort = true;
448
+ let cP = select(gm((*path).scatteringPdf,
449
+ envMapPdf(cU((*path).ray.d)) * rtUniform.envLightPmf),
450
+ 1.0, (*path).scatteringIsDelta);
451
+ (*path).li += cP * (*path).beta * bg.rgb * bg.a;
452
+ (*path).alpha = max((*path).alpha, bg.a);
453
+ (*path).abort = true;
521
454
  return;
522
455
  }
523
- let _uv = dm((*aa).ray.d);
456
+ let _uv = cU((*path).ray.d);
524
457
  var emission = textureLinear(envMap, _uv).rgb;
525
- let fl = gj(
526
- (*aa).scatteringPdf,
527
- iT(_uv) * rtUniform.envLightPmf
458
+ let misWeight = gm(
459
+ (*path).scatteringPdf,
460
+ envMapPdf(_uv) * rtUniform.envLightPmf
528
461
  );
529
462
  if (SPECTRAL) {
530
- emission = aj(emission, (*si).wavelength);
463
+ emission = sampling_spectral_rgb_filter(emission, (*si).spectralChannel);
531
464
  }
532
465
 
533
466
  if (!USE_BACKGROUND) {
534
- (*aa).alpha = 1.0;
467
+ (*path).alpha = 1.0;
535
468
  }
536
- (*aa).li += (*aa).beta * emission * fl;
537
- (*aa).abort = true;
469
+ (*path).li += (*path).beta * emission * misWeight;
470
+ (*path).abort = true;
538
471
  }
539
472
  }
540
473
 
541
474
  *depth = *depth + 1;
542
475
  }
543
476
 
544
- fn fj(coord: vec2f) -> Ray {
477
+ ${options.cameraProjectionInverse ? /* wgsl */ `
478
+ fn cV(coord: vec2f) -> Ray {
479
+
480
+
481
+ let origin = cameraUniform.projectionInv * vec4f(coord * 2.0 - 1.0, -1.0, 1.0);
482
+ let center = cameraUniform.projectionInv * vec4f(coord * 2.0 - 1.0, 1.0, 1.0);
483
+ let direction = center.xyz * origin.w - origin.xyz * center.w;
484
+ var cam: Ray;
485
+ initRay(&cam, (cameraUniform.viewInv * vec4f(origin.xyz / origin.w, 1.0)).xyz,
486
+ normalize((cameraUniform.viewInv * vec4f(direction, 0.0)).xyz));
487
+ return cam;
488
+ }
489
+ ` : /* wgsl */ `fn cV(coord: vec2f) -> Ray {
545
490
  let origin = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, -1.0, 1.0);
546
491
  let center = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, 1.0, 1.0);
547
492
  var cam: Ray;
548
- gC(&cam, origin.xyz / origin.w, normalize(center.xyz * origin.w - origin.xyz * center.w));
493
+ initRay(&cam, origin.xyz / origin.w, normalize(center.xyz * origin.w - origin.xyz * center.w));
549
494
 
550
495
  return cam;
551
- }
496
+ }`}
552
497
 
553
498
 
554
- fn ld(radius: f32, xi: f32) -> vec2f {
499
+ fn lD(radius: f32, xi: f32) -> vec2f {
555
500
  var x = 0.25;
556
- for (var oD = 0; oD < 10; oD++) {
501
+ for (var iteration = 0; iteration < 10; iteration++) {
557
502
  let x2 = x * x;
558
503
  let x3 = x2 * x;
559
- let lw = 1.0 - x;
504
+ let lU = 1.0 - x;
560
505
  let value = 10.0 * x2 - 20.0 * x3 + 15.0 * x2 * x2 -
561
506
  4.0 * x2 * x3 - xi;
562
- let mX = 20.0 * x * lw * lw * lw;
563
- if (abs(value) < 1e-6 || mX == 0.0) { break; }
564
- x = clamp(x - value / mX, 0.0, 1.0);
507
+ let nL = 20.0 * x * lU * lU * lU;
508
+ if (abs(value) < 1e-6 || nL == 0.0) { break; }
509
+ x = clamp(x - value / nL, 0.0, 1.0);
565
510
  }
566
- let jL = x * radius;
567
- return vec2f(jL, sqrt(max(radius * radius - jL * jL, 0.0)));
511
+ let jW = x * radius;
512
+ return vec2f(jW, sqrt(max(radius * radius - jW * jW, 0.0)));
568
513
  }
569
514
 
570
- fn jj(radius: f32, gM: f32) -> f32 {
571
- if (gM >= radius) { return 0.0; }
572
- let pa = radius - gM;
573
- return pa * pa * pa;
515
+ fn bevelCubicPdf(radius: f32, gO: f32) -> f32 {
516
+ if (gO >= radius) { return 0.0; }
517
+ let falloff = radius - gO;
518
+ return falloff * falloff * falloff;
574
519
  }
575
520
 
576
521
 
577
- fn nj(source: SurfaceInteraction, radius: f32) -> vec3f {
522
+ fn kB(source: SurfaceInteraction, radius: f32) -> vec3f {
578
523
  var geometricNormal = source.faceNormal;
579
524
  if (dot(geometricNormal, source.vertexNormal) < 0.0) {
580
525
  geometricNormal = -geometricNormal;
581
526
  }
582
527
  var tangent: vec3f;
583
528
  var bitangent: vec3f;
584
- aP(geometricNormal, &tangent, &bitangent);
585
- var iW = vec3f(0.0);
586
-
587
- for (var iG = 0; iG < BEVEL_SAMPLES; iG++) {
588
- let qf = dZ(CAMERA_BEVEL_BASE + u32(iG));
589
- var cJ = qf.x;
590
- let pv = qf.y;
591
- var dz = geometricNormal;
592
- var fW = tangent;
593
- var eA = bitangent;
594
- var gu = 0.5;
595
- var iB = 0.25;
596
- var gT = 0.25;
597
- if (cJ < 0.5) {
598
- cJ *= 2.0;
599
- }
600
- else if (cJ < 0.75) {
601
- let nI = dz;
602
- dz = fW;
603
- fW = nI;
604
- gu = 0.25;
605
- iB = 0.5;
606
- cJ = (cJ - 0.5) * 4.0;
529
+ sampling_orthonormal_basis(geometricNormal, &tangent, &bitangent);
530
+ var jd = vec3f(0.0);
531
+
532
+ for (var iN = 0; iN < BEVEL_SAMPLES; iN++) {
533
+ let rh = sample2D(CAMERA_BEVEL_BASE + u32(iN));
534
+ var cu = rh.x;
535
+ let qt = rh.y;
536
+ var dc = geometricNormal;
537
+ var fU = tangent;
538
+ var eo = bitangent;
539
+ var gw = 0.5;
540
+ var iH = 0.25;
541
+ var gV = 0.25;
542
+ if (cu < 0.5) {
543
+ cu *= 2.0;
544
+ }
545
+ else if (cu < 0.75) {
546
+ let os = dc;
547
+ dc = fU;
548
+ fU = os;
549
+ gw = 0.25;
550
+ iH = 0.5;
551
+ cu = (cu - 0.5) * 4.0;
607
552
  }
608
553
  else {
609
- let nI = dz;
610
- dz = eA;
611
- eA = nI;
612
- gu = 0.25;
613
- gT = 0.5;
614
- cJ = (cJ - 0.75) * 4.0;
615
- }
616
-
617
- let hj = ld(radius, pv);
618
- let phi = TWOPI * cJ;
619
- let rw = hj.x *
620
- (cos(phi) * fW + sin(phi) * eA);
554
+ let os = dc;
555
+ dc = eo;
556
+ eo = os;
557
+ gw = 0.25;
558
+ gV = 0.5;
559
+ cu = (cu - 0.75) * 4.0;
560
+ }
561
+
562
+ let hm = lD(radius, qt);
563
+ let phi = TWOPI * cu;
564
+ let sI = hm.x *
565
+ (cos(phi) * fU + sin(phi) * eo);
621
566
  var ray: Ray;
622
- gC(
567
+ initRay(
623
568
  &ray,
624
- source.position + dz * hj.y + rw,
625
- -dz
569
+ source.position + dc * hm.y + sI,
570
+ -dc
626
571
  );
627
572
  var hit: SurfaceInteraction;
628
573
  intersectSceneBevel(
629
574
  ray,
630
575
  &hit,
631
576
  source.instanceIndex,
632
- max(2.0 * hj.y, EPS)
577
+ max(2.0 * hm.y, EPS)
633
578
  );
634
579
  if (!hit.hit) { continue; }
635
580
 
636
- let lA = gu * abs(dot(dz, hit.faceNormal));
637
- let nC = iB * abs(dot(fW, hit.faceNormal));
638
- let kG = gT * abs(dot(eA, hit.faceNormal));
639
- var weight = lA / max(
640
- lA * lA + nC * nC +
641
- kG * kG,
581
+ let lV = gw * abs(dot(dc, hit.faceNormal));
582
+ let oi = iH * abs(dot(fU, hit.faceNormal));
583
+ let kR = gV * abs(dot(eo, hit.faceNormal));
584
+ var weight = lV / max(
585
+ lV * lV + oi * oi +
586
+ kR * kR,
642
587
  1e-8
643
588
  );
644
- weight *= jj(radius, distance(hit.position, source.position)) /
645
- max(jj(radius, hj.x), 1e-8);
646
- iW += weight * hit.vertexNormal;
589
+ weight *= bevelCubicPdf(radius, distance(hit.position, source.position)) /
590
+ max(bevelCubicPdf(radius, hm.x), 1e-8);
591
+ jd += weight * hit.vertexNormal;
647
592
  }
648
593
 
649
- if (dot(iW, iW) <= 1e-12) { return source.normal; }
650
- let kg = normalize(iW);
651
- let result = source.normal + kg - source.vertexNormal;
594
+ if (dot(jd, jd) <= 1e-12) { return source.normal; }
595
+ let kt = normalize(jd);
596
+ let result = source.normal + kt - source.vertexNormal;
652
597
  if (dot(result, result) > 1e-12) { return normalize(result); }
653
598
  return source.normal;
654
599
  }
655
600
 
656
- fn cT(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, sh: bool) -> vec4f {
657
- var aa: Path;
658
- aa.ray = ray;
659
- aa.li = vec3f(0.0);
660
- aa.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
661
- aa.beta = vec3f(1.0);
662
- aa.fromEye = true;
663
- aa.scatteringPdf = 0.0;
664
- aa.scatteringIsDelta = false;
665
- aa.isNextRefraction = false;
666
- aa.abort = false;
601
+ ${sharePrefix ? spectralPrefixWgsl(!enabled) + prefixCheckpoint('spSurface', surfacePrefix) + prefixCheckpoint('spFlat', flatPrefix) : ''}fn cJ(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, initialQuery: bool) -> vec4f {
602
+ var path: Path;
603
+ path.ray = ray;
604
+ path.li = vec3f(0.0);
605
+ path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
606
+ path.beta = vec3f(1.0);
607
+ path.fromEye = true;
608
+ path.scatteringPdf = 0.0;
609
+ path.scatteringIsDelta = false;
610
+ path.isNextRefraction = false;
611
+ path.abort = false;
667
612
 
668
613
  let bounceLimit = max(rtUniform.bounces, 0);
669
- let ft = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
614
+ let fj = min(bounceLimit * 3, ${maxPathEvents});
670
615
  var depth = 0;
671
- var aJ = false;
672
- var bQ = false;
673
-
616
+ var sampleIgnored = false;
617
+ var isNotTransparent = false;
618
+ ${sharePrefix ? /* wgsl */ ` let spSlot = qz; qz++;
619
+ if (spActive && spChannel > 1 && eB[spSlot].ready) { return rN(spSlot, outAux); }
620
+ var spEvent = 0; var spResume = false;
621
+ if (spActive && spChannel > 1 && fC == spSlot) {
622
+ var event = 0;
623
+ ${prefixRestore('spSurface', surfacePrefix)}
624
+ spEvent = event; spResume = true; qA(&path, si);
625
+ } else if (sd) { (*si).spectralChannel = select(spChannel, 0, spActive); (*si).wavelength = lg; }
626
+ ` : ''}
674
627
 
675
628
 
676
629
 
677
- for (var event = 0; event <= ft; event++) {
678
- if ((event != 0) | sh) {
679
- intersectScene(aa.ray, si, depth, event != 0, aa.isNextRefraction);
680
- dg(ma, (*si).materialIndex, (*si).uv, (*si).uv1, (*si).instanceIndex, (*si).vertexColor);
630
+ for (var event = ${sharePrefix ? 'spEvent' : '0'}; event <= fj; event++) {
631
+ if (${sharePrefix ? '!spResume && ((event != 0) | initialQuery)' : '(event != 0) | initialQuery'}) {
632
+ intersectScene(path.ray, si, depth, event != 0, path.isNextRefraction);
633
+ getMaterial(ma, (*si).materialIndex, (*si).uv, (*si).uv1, (*si).instanceIndex, (*si).vertexColor);
681
634
  }
682
635
  if (event == 0) {
683
- if (sh & (*si).hit & ((*ma).materialType == STANDARD)) {
636
+ if (initialQuery & (*si).hit & ((*ma).materialType == STANDARD)) {
684
637
  (*outAux).albedo = select((*ma).baseColor, vec3f(1.0), (*ma).transmissionWeight > 0.5);
685
638
  (*outAux).normal = select((*si).normal, -(*si).normal,
686
639
  dot((*si).normal, (*si).position - cameraUniform.viewInv[3].xyz) > 0.0);
687
640
  (*si).albedoSampled = (*ma).transmissionWeight > 0.5;
688
641
  }
689
- bQ = ((*ma).transmissionWeight < 0.001) & ((*ma).subsurfaceWeight < 0.001) & ((*ma).alpha > 0.99);
690
- } else {
691
- kl(&aa, &depth, si, ma, aJ);
642
+ isNotTransparent = ((*ma).transmissionWeight < 0.001) & ((*ma).subsurfaceWeight < 0.001) & ((*ma).alpha > 0.99);
643
+ } else {${sharePrefix ? /* wgsl */ `
644
+ if (spActive && (*ma).transmissionWeight > 0.001 && gf(*ma)) {
645
+ ${prefixSave('spSurface', surfacePrefix)}
646
+ fC = spSlot; qA(&path, si);
647
+ }` : ''}
648
+ gN(&path, &depth, si, ma, sampleIgnored);
692
649
  }
693
- if (bQ & (event > bounceLimit)) { aa.abort = true; }
694
- if (aa.abort | (event >= ft)) { break; }
695
- nY(uv, &aa, &depth, si, ma, outAux, &aJ);
696
- if (aa.abort) { break; }
650
+ ${sharePrefix ? ' spResume = false;\n' : ''} if (isNotTransparent & (event > bounceLimit)) { path.abort = true; }
651
+ if (path.abort | (event >= fj)) { break; }
652
+ mD(uv, &path, &depth, si, ma, outAux, &sampleIgnored);
653
+ if (path.abort) { break; }
697
654
  }
698
655
 
699
- return vec4f(aa.li, aa.alpha);
656
+ return ${sharePrefix ? 'spFinish(spSlot, vec4f(path.li, path.alpha), *outAux)' : 'vec4f(path.li, path.alpha)'};
700
657
  }
701
658
 
702
- fn iU(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
659
+ fn jb(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
703
660
  ${deterministicPrimaryAlpha ? /* wgsl */ `let coverage = clamp((*ma).alpha, 0.0, 1.0);
704
661
 
705
662
 
706
663
 
707
664
 
708
665
  let split = (*si).hit & (((*ma).materialType == STANDARD) | ((*ma).materialType == UNLIT)) & (coverage < 1.0);
709
- var sB = ray;
710
- var tr = *si;
711
- var tq = *ma;
712
- var iP = *outAux;
666
+ var tT = ray;
667
+ var uW = *si;
668
+ var uV = *ma;
669
+ var iX = *outAux;
713
670
  if (split) {
714
- sB.o = (*si).position + ray.d * (EPS * 0.02);
715
- tr.albedoSampled = false;
671
+ tT.o = (*si).position + ray.d * (EPS * 0.02);
672
+ uW.albedoSampled = false;
716
673
  }
717
674
  var back: vec4f;
718
- var ez: RayTraceAuxiliary;
675
+ var backAux: RayTraceAuxiliary;
719
676
 
720
677
 
721
- let vh = select(1u, rtUniform.loopUnrollGuard >> 1u, split & (coverage > 0.0));
722
- for (var uI = 0u; uI < vh; uI++) {
723
- let result = cT(uv, &tr, sB, &tq, &iP, split & (uI == 0u));
724
- if (!split | (coverage <= 0.0)) { *outAux = iP; return result; }
725
- if (uI == 0u) {
726
- back = result; ez = iP;
727
- tr = *si; tq = *ma; tq.alpha = 1.0;
728
- sB = ray; iP = *outAux;
678
+ let xh = select(1u, rtUniform.loopUnrollGuard >> 1u, split & (coverage > 0.0));
679
+ for (var wv = 0u; wv < xh; wv++) {
680
+ let result = cJ(uv, &uW, tT, &uV, &iX, split & (wv == 0u));
681
+ if (!split | (coverage <= 0.0)) { *outAux = iX; return result; }
682
+ if (wv == 0u) {
683
+ back = result; backAux = iX;
684
+ uW = *si; uV = *ma; uV.alpha = 1.0;
685
+ tT = ray; iX = *outAux;
729
686
  } else {
730
- (*outAux).albedo = mix(ez.albedo, iP.albedo, coverage);
731
- let dl = mix(ez.normal, iP.normal, coverage);
732
- (*outAux).normal = select(vec3f(0.0), normalize(dl), dot(dl, dl) > 1e-12);
733
- (*outAux).isBlank = ez.isBlank & iP.isBlank;
734
- (*outAux).isShadowCatcher = ez.isShadowCatcher & iP.isShadowCatcher;
735
- (*outAux).shadowCounts = mix(ez.shadowCounts, iP.shadowCounts, coverage);
687
+ (*outAux).albedo = mix(backAux.albedo, iX.albedo, coverage);
688
+ let aS = mix(backAux.normal, iX.normal, coverage);
689
+ (*outAux).normal = select(vec3f(0.0), normalize(aS), dot(aS, aS) > 1e-12);
690
+ (*outAux).isBlank = backAux.isBlank & iX.isBlank;
691
+ (*outAux).isShadowCatcher = backAux.isShadowCatcher & iX.isShadowCatcher;
692
+ (*outAux).shadowCounts = mix(backAux.shadowCounts, iX.shadowCounts, coverage);
736
693
  return mix(back, result, coverage);
737
694
  }
738
695
  }
739
- return vec4f(0.0);` : /* wgsl */ `return cT(uv, si, ray, ma, outAux, false);`}
696
+ return vec4f(0.0);` : /* wgsl */ `return cJ(uv, si, ray, ma, outAux, false);`}
740
697
  }
741
698
 
742
699
 
743
700
 
744
- ${spectral === false && deterministicPrimaryAlpha ? /* wgsl */ `fn iu(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
701
+ ${spectral === false && deterministicPrimaryAlpha ? /* wgsl */ `fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
745
702
  ${primaryVariables}
746
- var oI: SurfaceInteraction;
747
- var oH: OpenPbrResolvedMaterial;
748
- var ue: RayTraceAuxiliary;
749
- var iY = false;
703
+ var primarySi: SurfaceInteraction;
704
+ var primaryMa: OpenPbrResolvedMaterial;
705
+ var vR: RayTraceAuxiliary;
706
+ var jg = false;
750
707
  var query = true;
751
708
  var split = false;
752
709
  var coverage = 1.0;
753
710
  var front = false;
754
711
  var back: vec4f;
755
- var ez: RayTraceAuxiliary;
756
- var aa: Path; aa.ray = ray;
757
- aa.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
758
- aa.beta = vec3f(1.0); aa.fromEye = true;
712
+ var backAux: RayTraceAuxiliary;
713
+ var path: Path; path.ray = ray;
714
+ path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
715
+ path.beta = vec3f(1.0); path.fromEye = true;
759
716
  let bounceLimit = max(rtUniform.bounces, 0);
760
- let ft = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
761
- var event = 0; var depth = 0; var aJ = false;
762
- var bQ = false;
717
+ let fj = min(bounceLimit * 3, ${maxPathEvents});
718
+ var event = 0; var depth = 0; var sampleIgnored = false;
719
+ var isNotTransparent = false;
763
720
 
764
721
 
765
- for (var step = 0; step < (${MAX_PATH_EVENTS} + 1) * 2 + 2; step++) {
722
+ for (var step = 0; step < (${maxPathEvents} + 1) * 2 + 2; step++) {
766
723
  if (query) {
767
- intersectScene(aa.ray, &si, depth, event != 0, aa.isNextRefraction);
768
- dg(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
724
+ intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
725
+ getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
769
726
  }
770
727
  query = true;
771
- if (!iY) {
728
+ if (!jg) {
772
729
  ${primaryGuides}
773
- oI = si; oH = ma; ue = *outAux;
774
- iY = true;
730
+ primarySi = si; primaryMa = ma; vR = *outAux;
731
+ jg = true;
775
732
  coverage = clamp(ma.alpha, 0.0, 1.0);
776
733
  split = si.hit & ((ma.materialType == STANDARD) | (ma.materialType == UNLIT)) & (coverage < 1.0);
777
734
  if (split) {
778
- aa.ray.o = si.position + ray.d * (EPS * 0.02);
735
+ path.ray.o = si.position + ray.d * (EPS * 0.02);
779
736
  si.albedoSampled = false;
780
737
  continue;
781
738
  }
@@ -788,146 +745,170 @@ si.albedoSampled = ma.transmissionWeight > 0.5;
788
745
  }
789
746
  }
790
747
  if (event == 0) {
791
- bQ = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
748
+ isNotTransparent = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
792
749
  } else {
793
- kl(&aa, &depth, &si, &ma, aJ);
750
+ gN(&path, &depth, &si, &ma, sampleIgnored);
794
751
  }
795
- if (bQ & (event > bounceLimit)) { aa.abort = true; }
796
- if (!aa.abort & (event < ft)) {
797
- nY(uv, &aa, &depth, &si, &ma, outAux, &aJ);
752
+ if (isNotTransparent & (event > bounceLimit)) { path.abort = true; }
753
+ if (!path.abort & (event < fj)) {
754
+ mD(uv, &path, &depth, &si, &ma, outAux, &sampleIgnored);
798
755
  }
799
- if (aa.abort | (event >= ft)) {
800
- let result = vec4f(aa.li, aa.alpha);
756
+ if (path.abort | (event >= fj)) {
757
+ let result = vec4f(path.li, path.alpha);
801
758
  if (!split | (coverage <= 0.0)) { return result; }
802
759
  if (front) {
803
- (*outAux).albedo = mix(ez.albedo, (*outAux).albedo, coverage);
804
- let dl = mix(ez.normal, (*outAux).normal, coverage);
805
- (*outAux).normal = select(vec3f(0.0), normalize(dl), dot(dl, dl) > 1e-12);
806
- (*outAux).isBlank = ez.isBlank & (*outAux).isBlank;
807
- (*outAux).isShadowCatcher = ez.isShadowCatcher & (*outAux).isShadowCatcher;
808
- (*outAux).shadowCounts = mix(ez.shadowCounts, (*outAux).shadowCounts, coverage);
760
+ (*outAux).albedo = mix(backAux.albedo, (*outAux).albedo, coverage);
761
+ let aS = mix(backAux.normal, (*outAux).normal, coverage);
762
+ (*outAux).normal = select(vec3f(0.0), normalize(aS), dot(aS, aS) > 1e-12);
763
+ (*outAux).isBlank = backAux.isBlank & (*outAux).isBlank;
764
+ (*outAux).isShadowCatcher = backAux.isShadowCatcher & (*outAux).isShadowCatcher;
765
+ (*outAux).shadowCounts = mix(backAux.shadowCounts, (*outAux).shadowCounts, coverage);
809
766
  return mix(back, result, coverage);
810
767
  }
811
- back = result; ez = *outAux;
812
- front = true; query = false; event = 0; depth = 0; aJ = false;
813
- si = oI; ma = oH; ma.alpha = 1.0; *outAux = ue;
814
- aa = Path(); aa.ray = ray; aa.beta = vec3f(1.0); aa.fromEye = true;
815
- aa.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
768
+ back = result; backAux = *outAux;
769
+ front = true; query = false; event = 0; depth = 0; sampleIgnored = false;
770
+ si = primarySi; ma = primaryMa; ma.alpha = 1.0; *outAux = vR;
771
+ path = Path(); path.ray = ray; path.beta = vec3f(1.0); path.fromEye = true;
772
+ path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
816
773
  } else { event++; }
817
774
  }
818
775
  return vec4f(0.0);
819
776
  }
820
- ` : spectral === false && !deterministicPrimaryAlpha ? /* wgsl */ `fn iu(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
777
+ ` : spectral === false && !deterministicPrimaryAlpha ? /* wgsl */ `fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
821
778
  ${primaryVariables}
822
- var aa: Path;
823
- aa.ray = ray;
824
- aa.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
825
- aa.beta = vec3f(1.0);
826
- aa.fromEye = true;
779
+ var path: Path;
780
+ path.ray = ray;
781
+ path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
782
+ path.beta = vec3f(1.0);
783
+ path.fromEye = true;
827
784
  let bounceLimit = max(rtUniform.bounces, 0);
828
- let ft = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
829
- var bQ = false;
785
+ let fj = min(bounceLimit * 3, ${maxPathEvents});
786
+ var isNotTransparent = false;
830
787
  var depth = 0;
831
- var aJ = false;
788
+ var sampleIgnored = false;
832
789
 
833
790
 
834
791
 
835
- for (var event = 0; event <= ft; event++) {
836
- intersectScene(aa.ray, &si, depth, event != 0, aa.isNextRefraction);
837
- dg(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
792
+ for (var event = 0; event <= fj; event++) {
793
+ intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
794
+ getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
838
795
  if (event == 0) {
839
796
  ${primaryGuides}
840
- bQ = ma.transmissionWeight < 0.001 && ma.subsurfaceWeight < 0.001 && ma.alpha > 0.99;
797
+ isNotTransparent = ma.transmissionWeight < 0.001 && ma.subsurfaceWeight < 0.001 && ma.alpha > 0.99;
841
798
  } else {
842
- kl(&aa, &depth, &si, &ma, aJ);
799
+ gN(&path, &depth, &si, &ma, sampleIgnored);
843
800
  }
844
- if (bQ && event > bounceLimit) { aa.abort = true; }
845
- if (aa.abort || event >= ft) { break; }
846
- nY(uv, &aa, &depth, &si, &ma, outAux, &aJ);
847
- if (aa.abort) { break; }
801
+ if (isNotTransparent && event > bounceLimit) { path.abort = true; }
802
+ if (path.abort || event >= fj) { break; }
803
+ mD(uv, &path, &depth, &si, &ma, outAux, &sampleIgnored);
804
+ if (path.abort) { break; }
848
805
  }
849
- return vec4f(aa.li, aa.alpha);
806
+ return vec4f(path.li, path.alpha);
850
807
  }
851
808
  ` : spectral === true && !deterministicPrimaryAlpha ? /* wgsl */ `
852
- fn iu(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
809
+ fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
853
810
  ${primaryVariables}
854
- var oI: SurfaceInteraction;
855
- var oH: OpenPbrResolvedMaterial;
856
- var iY = false;
857
- var aa: Path; aa.ray = ray;
811
+ var primarySi: SurfaceInteraction;
812
+ var primaryMa: OpenPbrResolvedMaterial;
813
+ var jg = false;
814
+ var path: Path; path.ray = ray;
858
815
  let bounceLimit = max(rtUniform.bounces, 0);
859
- let ft = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
860
- var depth = 0; var event = 0; var aJ = false;
861
- var bQ = false;
862
- var mx = 0;
863
- let bo = rtUniform.dispersionWavelengths == 1;
864
- var df = false;
865
- var eX = 0;
866
- var hz: vec4u;
867
- var eO = 0u;
868
- var ba: RayTraceAuxiliary;
869
- let wavelengths = array<f32, 3>(650.0, 510.0, 475.0);
816
+ let fj = min(bounceLimit * 3, ${maxPathEvents});
817
+ var depth = 0; var event = 0; var sampleIgnored = false;
818
+ var isNotTransparent = false;
819
+ var jR = 0;
820
+ let bj = rtUniform.dispersionWavelengths == 1;
821
+ var eG = false;
822
+ var eQ = 0;
823
+ var aE = 0.0;
824
+ var wavelengthRngState: vec4u;
825
+ var eH = 0u;
826
+ var wavelengthAux: RayTraceAuxiliary;
870
827
  var color = vec3f(0.0); var alpha = 0.0;
871
- var dO = vec3f(0.0);
872
- var dP = vec3f(0.0);
873
- var mN = true;
828
+ var dD = vec3f(0.0);
829
+ var dE = vec3f(0.0);
830
+ var ik = true;
874
831
 
875
832
 
876
833
 
877
- let wF = min((${MAX_PATH_EVENTS} + 1) * 3, i32(rtUniform.loopUnrollGuard * ${Math.ceil((MAX_PATH_EVENTS + 1) * 3 / 4)}u));
878
- for (var step = 0; step < wF; step++) {
879
- if (!iY | ((event != 0) & !aa.abort)) {
880
- intersectScene(aa.ray, &si, depth, event != 0, aa.isNextRefraction);
881
- dg(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
834
+ let zh = min((${maxPathEvents} + 1) * 3, i32(rtUniform.loopUnrollGuard * ${Math.ceil((maxPathEvents + 1) * 3 / 4)}u));
835
+ for (var step = 0; step < zh; step++) {
836
+ if (!jg | ((event != 0) & !path.abort)) {
837
+ intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
838
+ getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
882
839
  }
883
840
  if (event == 0) {
884
- if (!iY) {
841
+ if (!jg) {
885
842
  ${primaryGuides}
886
- oI = si; oH = ma; iY = true;
887
- hz = s0; eO = cP;
888
- df = si.hit & (ma.transmissionWeight > 0.001) & (ma.transmissionDispersionScale > 0.001);
889
- if (bo & df) {
890
- eX = min(i32(floor(dp(CAMERA_WAVELENGTH) * 3.0)), 2);
891
- }
892
- }
893
- si = oI; ma = oH; ba = *outAux;
894
- if (!bo) {
895
- s0 = hz; cP = eO; bT = 0u;
896
- ba.isBlank = false; ba.isShadowCatcher = false;
897
- }
898
- si.wavelength = 0.0;
899
- if (!bo | df) {
900
- si.wavelength = wavelengths[select(mx, eX, bo)];
901
- ma.specularIor = ee(si.wavelength, ma.specularIor,
843
+ primarySi = si; primaryMa = ma; jg = true;
844
+ eG = si.hit & (ma.transmissionWeight > 0.001) & (ma.transmissionDispersionScale > 0.001);
845
+ aE = sample1D(CAMERA_WAVELENGTH);
846
+ if (bj) {
847
+ eQ = min(i32(floor(aE * 3.0)), 2);
848
+ aE = fract(aE * 3.0);
849
+ }
850
+ wavelengthRngState = s0; eH = hashedCounter;
851
+ }
852
+ si = primarySi; ma = primaryMa; wavelengthAux = *outAux;
853
+ if (!bj) {
854
+ s0 = wavelengthRngState; hashedCounter = eH; samplingBounce = 0u;
855
+ wavelengthAux.isBlank = false; wavelengthAux.isShadowCatcher = false;
856
+ }
857
+ si.wavelength = 0.0; si.spectralChannel = 0;
858
+ if (!bj | eG) {
859
+ let channel = select(jR, eQ, bj);
860
+ si.spectralChannel = channel + 1;
861
+ si.wavelength = ce(u32(channel), aE);
862
+ ${sharePrefix ? /* wgsl */ ` wY(channel + 1, si.wavelength, gf(ma));
863
+ if (spActive) { si.spectralChannel = 0; }
864
+ ` : ''} ma.specularIor = sampling_cauchy_ior(si.wavelength, ma.specularIor,
902
865
  ma.transmissionDispersionScale, ma.dispersionAbbeNumber);
903
866
  }
904
- aa = Path(); aa.ray = ray; aa.beta = vec3f(1.0); aa.fromEye = true;
905
- aa.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
906
- depth = 0; aJ = false;
907
- bQ = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
908
- } else if (!aa.abort) {
909
- kl(&aa, &depth, &si, &ma, aJ);
910
- }
911
- if (bQ & (event > bounceLimit)) { aa.abort = true; }
912
- if (!aa.abort & (event < ft)) {
913
- nY(uv, &aa, &depth, &si, &ma, &ba, &aJ);
914
- }
915
- if (aa.abort | (event >= ft)) {
916
- let result = vec4f(aa.li, aa.alpha);
917
- if (bo) {
918
- *outAux = ba;
919
- let scale = select(1.0, 3.0, df);
867
+ path = Path(); path.ray = ray; path.beta = vec3f(1.0); path.fromEye = true;
868
+ path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
869
+ depth = 0; sampleIgnored = false;
870
+ isNotTransparent = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
871
+ ${sharePrefix ? /* wgsl */ ` if (spActive && jR > 0 && fC == 0) {
872
+ ${prefixRestore('spFlat', flatPrefix)}
873
+ qA(&path, &si);
874
+ }
875
+ }
876
+ if (event > 0 && !path.abort) {
877
+ if (spActive && ma.transmissionWeight > 0.001 && gf(ma)) {
878
+ ${prefixSave('spFlat', flatPrefix)}
879
+ fC = 0; qA(&path, &si);
880
+ }
881
+ gN(&path, &depth, &si, &ma, sampleIgnored);
882
+ }` : /* wgsl */ ` } else if (!path.abort) {
883
+ gN(&path, &depth, &si, &ma, sampleIgnored);
884
+ }`}
885
+ if (isNotTransparent & (event > bounceLimit)) { path.abort = true; }
886
+ if (!path.abort & (event < fj)) {
887
+ mD(uv, &path, &depth, &si, &ma, &wavelengthAux, &sampleIgnored);
888
+ }
889
+ if (path.abort | (event >= fj)) {
890
+ let result = vec4f(path.li, path.alpha);
891
+ if (bj) {
892
+ *outAux = wavelengthAux;
893
+ let scale = select(1.0, 3.0, eG);
920
894
  return vec4f(result.rgb * scale, result.a);
921
895
  }
922
- color += result.rgb; alpha = max(alpha, result.a);
923
- dO += ba.albedo;
924
- dP += ba.normal;
925
- mN = mN & ba.isBlank;
926
- mx++;
927
- if (mx >= 3) {
928
- (*outAux).albedo = dO / 3.0;
929
- (*outAux).normal = dP / 3.0;
930
- (*outAux).isBlank = mN;
896
+ ${sharePrefix ? /* wgsl */ ` if (spActive) {
897
+ (*outAux).isBlank = wavelengthAux.isBlank;
898
+
899
+ (*outAux).albedo = (wavelengthAux.albedo + wavelengthAux.albedo + wavelengthAux.albedo) / 3.0;
900
+ (*outAux).normal = (wavelengthAux.normal + wavelengthAux.normal + wavelengthAux.normal) / 3.0;
901
+ return result;
902
+ }
903
+ ` : ''} color += result.rgb; alpha = max(alpha, result.a);
904
+ dD += wavelengthAux.albedo;
905
+ dE += wavelengthAux.normal;
906
+ ik = ik & wavelengthAux.isBlank;
907
+ jR++;
908
+ if (jR >= 3) {
909
+ (*outAux).albedo = dD / 3.0;
910
+ (*outAux).normal = dE / 3.0;
911
+ (*outAux).isBlank = ik;
931
912
  return vec4f(color, alpha);
932
913
  }
933
914
  event = 0;
@@ -935,91 +916,97 @@ event = 0;
935
916
  }
936
917
  return vec4f(0.0);
937
918
  }
938
- ` : /* wgsl */ `fn iu(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
919
+ ` : /* wgsl */ `fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
939
920
  ${primaryVariables}
940
921
  intersectScene(ray, &si, 0, false, false);
941
- dg(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
922
+ getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
942
923
  ${primaryGuides}
943
924
  if (SPECTRAL) {
944
925
 
945
926
 
946
927
 
947
928
 
948
- let ug = array<f32, 3>(650.0, 510.0, 475.0);
949
- var vl = vec3f(0.0);
929
+ var xl = vec3f(0.0);
950
930
  var alpha = 0.0;
951
- var dO = vec3f(0.0);
952
- var dP = vec3f(0.0);
953
- var mN = true;
931
+ var dD = vec3f(0.0);
932
+ var dE = vec3f(0.0);
933
+ var ik = true;
954
934
  var si2 = si;
955
935
  var ma2 = ma;
956
- let hz = s0;
957
- let eO = cP;
958
- let bo = rtUniform.dispersionWavelengths == 1;
959
- let df = si.hit &&
936
+ var aE = sample1D(CAMERA_WAVELENGTH);
937
+ let wavelengthRngState = s0;
938
+ let eH = hashedCounter;
939
+ let bj = rtUniform.dispersionWavelengths == 1;
940
+ let eG = si.hit &&
960
941
  ma.transmissionWeight > 0.001 &&
961
942
  ma.transmissionDispersionScale > 0.001;
962
- let tm = select(3, 1, bo);
963
- var eX = 0;
964
- if (bo && df) {
943
+ let uR = select(3, 1, bj);
944
+ var eQ = 0;
945
+ if (bj) {
965
946
 
966
947
 
967
- eX = min(i32(floor(dp(CAMERA_WAVELENGTH) * 3.0)), 2);
948
+ eQ = min(i32(floor(aE * 3.0)), 2);
949
+ aE = fract(aE * 3.0);
968
950
  }
969
- for (var i = 0; i < tm; i++) {
951
+ for (var i = 0; i < uR; i++) {
970
952
 
971
953
 
972
954
 
973
- if (!bo) {
974
- s0 = hz;
975
- cP = eO;
976
- bT = 0u;
955
+ if (!bj) {
956
+ s0 = wavelengthRngState;
957
+ hashedCounter = eH;
958
+ samplingBounce = 0u;
977
959
  }
978
960
  si.wavelength = 0.0;
979
- if (!bo || df) {
980
- si.wavelength = ug[select(i, eX, bo)];
981
- ma.specularIor = ee(
961
+ si.spectralChannel = 0;
962
+ if (!bj || eG) {
963
+ let channel = select(i, eQ, bj);
964
+ si.spectralChannel = channel + 1;
965
+ si.wavelength = ce(u32(channel), aE);
966
+ ${sharePrefix ? /* wgsl */ ` wY(channel + 1, si.wavelength, gf(ma));
967
+ if (spActive) { si.spectralChannel = 0; }
968
+ ` : ''} ma.specularIor = sampling_cauchy_ior(
982
969
  si.wavelength,
983
970
  ma.specularIor,
984
971
  ma.transmissionDispersionScale,
985
972
  ma.dispersionAbbeNumber
986
973
  );
987
974
  }
988
- var ba: RayTraceAuxiliary;
989
- if (bo) {
990
- ba = *outAux;
975
+ var wavelengthAux: RayTraceAuxiliary;
976
+ if (bj) {
977
+ wavelengthAux = *outAux;
991
978
  } else {
992
- ba.albedo = (*outAux).albedo;
993
- ba.normal = (*outAux).normal;
994
- ba.isBlank = false;
995
- ba.isShadowCatcher = false;
996
- }
997
- let res = iU(uv, &si, ray, &ma, &ba);
998
- if (bo) {
999
- *outAux = ba;
1000
- let scale = select(1.0, 3.0, df);
979
+ wavelengthAux.albedo = (*outAux).albedo;
980
+ wavelengthAux.normal = (*outAux).normal;
981
+ wavelengthAux.isBlank = false;
982
+ wavelengthAux.isShadowCatcher = false;
983
+ }
984
+ let res = jb(uv, &si, ray, &ma, &wavelengthAux);
985
+ if (bj) {
986
+ *outAux = wavelengthAux;
987
+ let scale = select(1.0, 3.0, eG);
1001
988
  return vec4f(res.rgb * scale, res.a);
1002
989
  }
1003
- vl += res.rgb;
990
+ xl += res.rgb;
1004
991
  alpha = max(alpha, res.a);
1005
- dO += ba.albedo;
1006
- dP += ba.normal;
1007
- mN = mN && ba.isBlank;
992
+ dD += wavelengthAux.albedo;
993
+ dE += wavelengthAux.normal;
994
+ ik = ik && wavelengthAux.isBlank;
1008
995
  si = si2;
1009
996
  ma = ma2;
1010
997
  }
1011
- (*outAux).albedo = dO / 3.0;
1012
- (*outAux).normal = dP / 3.0;
1013
- (*outAux).isBlank = mN;
1014
- return vec4f(vl, alpha);
998
+ (*outAux).albedo = dD / 3.0;
999
+ (*outAux).normal = dE / 3.0;
1000
+ (*outAux).isBlank = ik;
1001
+ return vec4f(xl, alpha);
1015
1002
  }
1016
1003
  else {
1017
- return iU(uv, &si, ray, &ma, outAux);
1004
+ return jb(uv, &si, ray, &ma, outAux);
1018
1005
  }
1019
1006
  }
1020
1007
  `}
1021
1008
 
1022
- fn kN(ip: vec2f) -> vec2f {
1009
+ fn kX(ip: vec2f) -> vec2f {
1023
1010
  let p = 2.0 * ip - 1.0;
1024
1011
  let greater = abs(p.x) > abs(p.y);
1025
1012
  let r = select(p.y, p.x, greater);
@@ -1028,7 +1015,7 @@ return r * vec2f(cos(theta), sin(theta));
1028
1015
  }
1029
1016
 
1030
1017
 
1031
- @compute @workgroup_size(${WORKGROUP_SIZE}, ${WORKGROUP_SIZE}, 1)
1018
+ @compute @workgroup_size(${workgroupSize}, ${workgroupSize}, 1)
1032
1019
  fn main(@builtin(global_invocation_id) globalId: vec3u) {
1033
1020
  let outputSize = rtUniform.outputSize;
1034
1021
  let scaleOffset = rtUniform.scaleOffset;
@@ -1058,24 +1045,24 @@ return;
1058
1045
 
1059
1046
  let uv = (vec2<f32>(f32(coord.x), f32(coord.y)) + vec2f(0.5)) / outputSize;
1060
1047
 
1061
- aZ = coord;
1062
- aQ = u32(outNormal[idx].a) + rtUniform.sampleSequenceOffset;
1063
- bT = 0u; cP = 0u;
1048
+ aJ = coord;
1049
+ aC = u32(outNormal[idx].a) + rtUniform.sampleSequenceOffset;
1050
+ samplingBounce = 0u; hashedCounter = 0u;
1064
1051
  if (${inputHooks?.uniformJitter ? 'false' : 'SAMPLING_PATTERN == 0 || SAMPLING_PATTERN == 1'}) {
1065
- jitter = (dZ(CAMERA_PIXEL) - 0.5) / outputSize;
1052
+ jitter = (sample2D(CAMERA_PIXEL) - 0.5) / outputSize;
1066
1053
  }
1067
- gW(coord, i32(aQ ^ dG(rtUniform.sequenceSeed)));
1068
- var cam = fj(uv + jitter);
1054
+ fA(coord, i32(aC ^ cD(rtUniform.sequenceSeed)));
1055
+ var cam = cV(uv + jitter);
1069
1056
 
1070
1057
  if (cameraUniform.apertureRadius > 0.0) {
1071
1058
 
1072
1059
  let eye = cameraUniform.viewInv[3].xyz;
1073
1060
  let forward = -normalize(cameraUniform.viewInv[2].xyz);
1074
- let jN = eye + cam.d * (cameraUniform.focusDistance / dot(cam.d, forward));
1075
- let sK = cameraUniform.apertureRadius * kN(dZ(CAMERA_LENS));
1076
- let origin = (cameraUniform.viewInv * vec4f(sK, 0.0, 1.0)).xyz;
1077
- let dir = normalize(jN - origin);
1078
- gC(&cam, origin, dir);
1061
+ let jY = eye + cam.d * (cameraUniform.focusDistance / dot(cam.d, forward));
1062
+ let uh = cameraUniform.apertureRadius * kX(sample2D(CAMERA_LENS));
1063
+ let origin = (cameraUniform.viewInv * vec4f(uh, 0.0, 1.0)).xyz;
1064
+ let dir = normalize(jY - origin);
1065
+ initRay(&cam, origin, dir);
1079
1066
  }
1080
1067
 
1081
1068
  var outAux: RayTraceAuxiliary;
@@ -1083,39 +1070,40 @@ outAux.albedo = vec3f(0.0);
1083
1070
  outAux.normal = vec3f(0.0);
1084
1071
  outAux.isBlank = false;
1085
1072
  outAux.isShadowCatcher = false;
1086
- ${pathDiagnostic ? ' mtPathBegin(coord);\n' : ''}${inputHooks?.begin ?? ''} var aW = iu(uv + jitter, cam, &outAux);
1073
+ ${pathDiagnostic ? ' mtPathBegin(coord);\n' : ''}${inputHooks?.begin ?? ''} var liAndAlpha = hq(uv + jitter, cam, &outAux);
1087
1074
  ${inputHooks?.unclampedColor ?? ''}
1088
-
1075
+ ${(enabled || lightTracing || photonMapping) && debugGroup >= 0 ? /* wgsl */ ` liAndAlpha=${debugGroup >= 50 ? `vec4f(photonQueryStats,1.0)` : debugGroup >= 30 ? `vec4f(causticHot[${debugGroup - 30}],1.0)` : research?.debugOutput ?? 'liAndAlpha'};
1076
+ ` : ''}
1089
1077
 
1090
1078
  if (rtUniform.clamping > 0.0) {
1091
1079
  let clamping = rtUniform.clamping;
1092
- aW = vec4(clamp(aW.rgb, -vec3f(clamping), vec3f(clamping)), aW.a);
1080
+ liAndAlpha = vec4(clamp(liAndAlpha.rgb, -vec3f(clamping), vec3f(clamping)), liAndAlpha.a);
1093
1081
  }
1094
- if (!(aW.x < INF && aW.x > -EPS)) {
1095
- aW = vec4f(0.0, 0.0, 0.0, 1.0);
1082
+ if (!(liAndAlpha.x < INF && liAndAlpha.x > -EPS)) {
1083
+ liAndAlpha = vec4f(0.0, 0.0, 0.0, 1.0);
1096
1084
  }
1097
1085
 
1098
1086
  if (outAux.isShadowCatcher) {
1099
1087
 
1100
1088
 
1101
- let bc = hX(cam);
1102
- let rh = select(0.0, 1.0, bc.a >= 0.01);
1103
- let jW = vec4f(bc.rgb * bc.a, bc.a);
1089
+ let aW = fI(cam);
1090
+ let sn = select(0.0, 1.0, aW.a >= 0.01);
1091
+ let kg = vec4f(aW.rgb * aW.a, aW.a);
1104
1092
 
1105
1093
 
1106
1094
 
1107
- outShadowCatcher[idx].mask += vec4f(1.0, bc.a, rh, 0.0);
1095
+ outShadowCatcher[idx].mask += vec4f(1.0, aW.a, sn, 0.0);
1108
1096
  outShadowCatcher[idx].moments += vec4f(0.0, 0.0, outAux.shadowCounts);
1109
- outShadowCatcher[idx].background += jW;
1110
- outColor[idx] += jW;
1111
- outAlbedo[idx] += vec4f(outAux.albedo, rh);
1112
- ie(idx, bc.rgb, outAux.normal);
1097
+ outShadowCatcher[idx].background += kg;
1098
+ outColor[idx] += kg;
1099
+ outAlbedo[idx] += vec4f(outAux.albedo, sn);
1100
+ ij(idx, aW.rgb, outAux.normal);
1113
1101
 
1114
1102
 
1115
1103
  let counts = outAux.shadowCounts;
1116
1104
  let visibility = 1.0 - select(0.0, counts.x / counts.y, counts.y > 0.0);
1117
- ji(idx, visibility * select(
1118
- 1.0, dot(bc.rgb, luminance), bc.a >= 0.01
1105
+ ju(idx, visibility * select(
1106
+ 1.0, dot(aW.rgb, luminance), aW.a >= 0.01
1119
1107
  ));
1120
1108
  }
1121
1109
  else {
@@ -1125,13 +1113,13 @@ if (HAS_SHADOW_CATCHER && outAux.isBlank && USE_BACKGROUND && !USE_BACKGROUND_MA
1125
1113
 
1126
1114
 
1127
1115
 
1128
- outShadowCatcher[idx].background += aW;
1129
- outShadowCatcher[idx].mask.g += aW.a;
1116
+ outShadowCatcher[idx].background += liAndAlpha;
1117
+ outShadowCatcher[idx].mask.g += liAndAlpha.a;
1130
1118
  }
1131
- outColor[idx] += aW;
1119
+ outColor[idx] += liAndAlpha;
1132
1120
  outAlbedo[idx] += vec4f(outAux.albedo, select(1.0, 0.0, outAux.isBlank));
1133
- ie(idx, aW.rgb, outAux.normal);
1134
- ji(idx, dot(aW.rgb, luminance));
1121
+ ij(idx, liAndAlpha.rgb, outAux.normal);
1122
+ ju(idx, dot(liAndAlpha.rgb, luminance));
1135
1123
  }
1136
1124
  ${pathDiagnostic ? ' mtPathEnd(outAux.normal, outAux.albedo);\n' : ''}${inputHooks?.end ?? ''}}
1137
1125
  `;
@@ -1139,7 +1127,7 @@ ${pathDiagnostic ? ' mtPathEnd(outAux.normal, outAux.albedo);\n' : ''}${inputHo
1139
1127
  // It has no effect on the beauty entry point or its bindings.
1140
1128
  // Gate optional material layers on scene-level feature flags so drivers can
1141
1129
  // skip the unused BSDF lobes.
1142
- let specializedSource = source + depthQueryWGSL + reflectanceWGSL + aovTraceWGSL;
1130
+ let specializedSource = source + depthQueryWGSL + reflectanceWGSL + (options.displayAovStorage ? aovTraceDisplayWGSL : aovTraceWGSL);
1143
1131
  const backgroundBits = {
1144
1132
  USE_BACKGROUND: 1,
1145
1133
  USE_BACKGROUND_MAP: 2,