@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticLight.compute.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/causticLight.compute.ts"],"names":[],"mappings":"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","sourcesContent":["import {PHOTON_GRID_SIZE, photonPackingWgsl} from './photonMap.compute.js';\nimport {SPECTRUM_PHOTON_DISTRIBUTION, SPECTRUM_WAVELENGTH_RANGE, spectrumWgsl} from '../spectrum.js';\nimport background from './chunks/background.wgsl.js';\nimport atomic from './chunks/causticAtomic.wgsl.js';\nimport adjoint from './chunks/causticAdjoint.wgsl.js';\nimport common from './chunks/common.wgsl.js';\nimport core from './chunks/rayTraceCore.wgsl.js';\nimport {createMaterialBufferWgsl} from './chunks/materialBuffer.wgsl.js';\nimport intersect from './chunks/intersect.wgsl.js';\nimport rand from './chunks/rand.wgsl.js';\nimport random from './chunks/random.wgsl.js';\nimport env from './chunks/envMap.wgsl.js';\nimport sampling from './chunks/sampling.wgsl.js';\nimport {createOpenPbrBsdfWgsl} from './chunks/openPbrBsdf.wgsl.js';\nimport light from './chunks/sampleLight.wgsl.js';\nimport uv from './chunks/uvProjection.wgsl.js';\nimport {causticPartitionWGSL} from './chunks/caustics.wgsl.js';\nimport {wgpuShaderPreamble} from '../wgpuShaderSource.js';\nimport {WGPU_SCENE_FEATURE_BITS} from '../WGPUSceneFeatures.js';\n\nexport const CAUSTIC_UNIFORM_BYTES = 112;\nexport const causticUnitRandomWgsl = /* wgsl */ `\n fn causticUnitRandom(value:f32)->f32 {\n return clamp((value-EPS)/(1.0-2.0*EPS),0.0,0.99999994);\n }\n`;\n\n// Preserve the dormant R1 uniform slot and shader spelling for source parity.\n// Production packs zero; only an explicitly registered research adapter sets it.\nexport function causticLightCompute(\n constants: Record<string, boolean | number>,\n blasLayoutMask: number,\n hasDisplacement: boolean,\n mode: 'lightTracing' | 'photonMapping' = 'lightTracing',\n sceneIntersections = '',\n fullEmissionRandom = true,\n perInstanceBounds = false,\n compactVertices = false,\n independentTextures = false\n) {\n const frames = !!constants.USE_ANISOTROPY_DIRECTIONS || !!constants.USE_COAT_NORMAL_FRAMES,\n coat = !!constants.USE_COAT_NORMAL_FRAMES;\n return (\n (independentTextures ? 'enable wgpu_binding_array;\\n' : '') + wgpuShaderPreamble(constants, true) +\n /* wgsl */ `\n${Object.keys(WGPU_SCENE_FEATURE_BITS)\n .map((name) => `const ${name} = ${!!constants[name]};`)\n .join('\\n')}\n${common}\n${core({independentTextures, compactVertices, hasAnisotropyDirections: frames, hasCoatNormals: coat, caustics: true})}\n${uv}\n${createMaterialBufferWgsl({independentTextures, hasAnisotropyDirections: frames, hasCoatNormals: coat, caustics: true})}\n${intersect({\n perInstanceBounds,\n compactVertices,\n hasDisplacement,\n blasLayoutMask,\n hasAnisotropyDirections: frames,\n hasCoatNormals: coat,\n sceneIntersections\n})}\n${rand}\n${random}\n${env}\n${sampling}\n${spectrumWgsl}\n${createOpenPbrBsdfWgsl(frames, coat)}\n${light}\n${background.replace(\n /\\b(?:USE_BACKGROUND|USE_BACKGROUND_MAP|USE_GROUNDED_BACKGROUND)\\b/g,\n (name) =>\n `((rtUniform.backgroundFlags & ${\n {USE_BACKGROUND: 1, USE_BACKGROUND_MAP: 2, USE_GROUNDED_BACKGROUND: 4}[name]\n }) != 0)`\n)}\n${causticPartitionWGSL(false, false)}\n${adjoint}\n struct CausticLightUniform {\n casterSphere: vec4f,\n viewProjection: mat4x4f,\n photonCount: u32,\n batch: u32,\n mnee: u32,\n cameraScale: f32,\n casterCount: u32,\n choiceCount: u32,\n orthographic: u32,\n experiments: u32,\n }\n @group(3) @binding(0) var<uniform> caustic: CausticLightUniform;\n${\n mode === 'lightTracing'\n ? '@group(3) @binding(1) var<storage,read_write> splats: array<atomic<u32>>;'\n : `${photonPackingWgsl}\n @group(3)@binding(1)var photons:texture_storage_2d<rgba32uint,write>;\n @group(3)@binding(3)var photonDirections:texture_storage_2d<r32uint,write>;\n fn photonStore(i:u32,value:vec4u) {\n let width=textureDimensions(photons).x;\n textureStore(photons,vec2i(vec2u(i%width,i/width)),value);\n }\n fn photonStoreDirections(i:u32,value:u32) {\n let buckets=min(${PHOTON_GRID_SIZE}u,1u<<(32u-countLeadingZeros(max(256u,caustic.photonCount*2u)-1u)));\n let index=8u+buckets*4u+caustic.photonCount*2u+i;\n let width=textureDimensions(photonDirections).x;\n textureStore(photonDirections,vec2i(vec2u(index%width,index/width)),vec4u(value));\n }\n`\n}\n @group(3) @binding(2) var causticDistribution:texture_2d<f32>;\n // Geometric emission PDFs assume the full disk/cone/area support. The generic\n // BSDF sampler contracts randoms by EPS; undo that contraction for these warps.\n${causticUnitRandomWgsl}\nfn causticEmission1D(dim:u32)->f32{return ${\n fullEmissionRandom ? 'causticUnitRandom(sample1D(dim))' : 'sample1D(dim)'\n }\n ;\n}\nfn causticEmission2D(dim:u32)->vec2f {\n let value=sample2D(dim);\n return\n${fullEmissionRandom ? 'vec2f(causticUnitRandom(value.x),causticUnitRandom(value.y))' : 'value'}\n ;\n}\nfn causticLoad(i:u32)->vec4f {\n let width=textureDimensions(causticDistribution).x;\n return textureLoad(causticDistribution,vec2i(vec2u(i%width,i/width)),0);\n}\nfn causticSphere(i:u32)->vec4f {\n return causticLoad(i);\n}\n// Photon emission samples a source surface, independently of any receiver.\n// A NEE sample viewed from the aggregate caster center can reject an emitter\n// which still illuminates another caster, or sample only part of a sphere.\nvar<private> causticEmissionOrigin:vec3f;\nvar<private> causticEmissionAreaPdf:f32;\nfn causticAreaLight(origin:vec3f,position:vec3f,normal:vec3f,emission:vec3f,area:f32,pmf:f32,result:ptr<function,LightSampleRec>) {\n causticEmissionOrigin=position;\n causticEmissionAreaPdf=pmf/max(area,1e-20);\n let offset=position-origin;\n (*result).dist=length(offset);\n (*result).direction=offset/max((*result).dist,1e-20);\n (*result).normal=normal;\n (*result).emission=emission;\n (*result).pdf=pmf;\n}\nfn causticSampleLight(origin:vec3f,rnd:vec3f,result:ptr<function,LightSampleRec>) {\n causticEmissionAreaPdf=0.0;\n (*result).pdf=0.0;\n (*result).sourceType=0u;\n (*result).isDelta=false;\n if(caustic.choiceCount==0u) {\n return;\n }\n let scaled=rnd.z*f32(caustic.choiceCount);\n let column=min(u32(scaled),caustic.choiceCount-1u);\n let entry=causticLoad(caustic.casterCount+column*2u);\n let selected=select(bitcast<u32>(entry.y),column,fract(scaled)<entry.x);\n let choice=bitcast<vec4u>(causticLoad(caustic.casterCount+selected*2u));\n let pmf=causticLoad(caustic.casterCount+selected*2u+1u).x;\n (*result).sourceIndex=choice.w;\n if(choice.z==1u) {\n (*result).sourceType=0u;\n sampleEnvLight(rnd.xy,result);\n (*result).pdf*=pmf;\n }\n else if(choice.z==2u) {\n (*result).sourceType=2u;\n var light=analyticLights[choice.w];\n let kind=i32(light.litType);\n if(kind==RECT_LIGHT) {\n let position=light.position+light.u*(rnd.x-.5)+light.v*(rnd.y-.5);\n causticAreaLight(origin,position,normalize(cross(light.u,light.v)),light.emission,light.area,pmf,result);\n (*result).isDelta=light.radiusOrSpread<=.001;\n light_apply_rect_texture(light,position,light.position-.5*(light.u+light.v),result);\n }\n else if((kind==SPHERE_LIGHT||kind==SPOT_LIGHT)&&light.radiusOrSpread>0.0) {\n let z=1.0-2.0*rnd.x;\n let radial=sqrt(max(0.0,1.0-z*z));\n let normal=vec3f(radial*cos(TWOPI*rnd.y),radial*sin(TWOPI*rnd.y),z);\n causticAreaLight(origin,light.position+light.radiusOrSpread*normal,normal,light.emission,light.area,pmf,result);\n }\n else {\n light.selectionPmf=1.0;\n sampleAnalyticLight(light,origin,rnd.xy,result);\n (*result).pdf*=pmf;\n }\n }\n else {\n (*result).sourceType=1u;\n let triangle=getEmissiveTriangle(i32(choice.w));\n let u=sqrt(rnd.x);\n let bary=vec3f(1.0-u,u*(1.0-rnd.y),u*rnd.y);\n let position=bary.x*triangle.p0+bary.y*triangle.p1+bary.z*triangle.p2;\n let normal=normalize(cross(triangle.p1-triangle.p0,triangle.p2-triangle.p0));\n let uv=bary.x*triangle.uv0+bary.y*triangle.uv1+bary.z*triangle.uv2;\n let uv1=bary.x*triangle.secondaryUv0+bary.y*triangle.secondaryUv1+bary.z*triangle.secondaryUv2;\n causticAreaLight(origin,position,normal,getMaterialEmission(i32(triangle.materialIndex),uv,uv1),triangle.area,pmf,result);\n }\n (*result).selectionPmf=pmf;\n}\nfn causticCosMax(s:vec4f,origin:vec3f)->f32 {\n let distanceSquared=dot(s.xyz-origin,s.xyz-origin);\n return select(-1.0,sqrt(max(0.0,1.0-s.w*s.w/distanceSquared)),distanceSquared>s.w*s.w);\n}\n// A positive floor retains paths from offscreen or occluded casters. The\n// complete weighted mixture PDF below, including overlaps, compensates selection.\nfn causticTargetWeight(s:vec4f)->f32 {\n if((caustic.experiments&2u)==0u) { return 1.0; }\n let clip=caustic.viewProjection*vec4f(s.xyz,1.0);\n let m=caustic.viewProjection;\n let extent=s.w*max(length(vec3f(m[0].x,m[1].x,m[2].x)),length(vec3f(m[0].y,m[1].y,m[2].y)));\n if(clip.w<=0.0||abs(clip.x)>clip.w+extent||abs(clip.y)>clip.w+extent) { return .05; }\n return .05+min(1.0,extent*extent/max(clip.w*clip.w,1e-20));\n}\nfn causticDirection(origin:vec3f,rnd:vec3f,pdf:ptr<function,f32>,targetRadius:ptr<function,f32>)->vec3f {\n var total=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n total+=(1.0-causticCosMax(causticSphere(i),origin))*causticTargetWeight(causticSphere(i));\n }\n var choice=rnd.z*total;\n var selected=causticSphere(0u);\n for(var i=0u;i<caustic.casterCount;i++) {\n let sphere=causticSphere(i);\n selected=sphere;\n choice-=(1.0-causticCosMax(sphere,origin))*causticTargetWeight(sphere);\n if(choice<=0.0) {\n break;\n }\n }\n *targetRadius=selected.w;\n let offset=selected.xyz-origin;\n let axis=normalize(select(vec3f(0.0,0.0,1.0),offset,dot(offset,offset)>1e-20));\n let cosine=mix(1.0,causticCosMax(selected,origin),rnd.x);\n let sine=sqrt(max(0.0,1.0-cosine*cosine));\n var t:vec3f;\n var b:vec3f;\n sampling_orthonormal_basis(axis,&t,&b);\n let direction=axis*cosine+(t*cos(TWOPI*rnd.y)+b*sin(TWOPI*rnd.y))*sine;\n // Evaluate the entire mixture, since intersecting bounding cones overlap.\n var overlaps=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n let sphere=causticSphere(i);\n let c=causticCosMax(sphere,origin);\n if(c<0.0||dot(normalize(sphere.xyz-origin),direction)>=c) {\n overlaps+=causticTargetWeight(sphere);\n }\n }\n *pdf=overlaps/max(TWOPI*total,1e-20);\n return direction;\n}\n${\n mode === 'lightTracing'\n ? /* wgsl */ `${atomic}\n fn causticCameraConnect(si: SurfaceInteraction, material: OpenPbrResolvedMaterial, incoming: Ray, flux: vec3f, extinction: vec3f) {\n let eye=cameraUniform.viewInv[3].xyz;\n let forward=-normalize(cameraUniform.viewInv[2].xyz);\n let lensSample=causticEmission2D(causticDim(68u));\n let radius=cameraUniform.apertureRadius*sqrt(lensSample.x);\n var lens=eye+radius*(cos(TWOPI*lensSample.y)*cameraUniform.viewInv[0].xyz+sin(TWOPI*lensSample.y)*cameraUniform.viewInv[1].xyz);\n if(caustic.orthographic!=0u) {\n lens=si.position-forward*dot(si.position-eye,forward);\n }\n let toEye=lens-si.position;\n let distanceSquared=dot(toEye,toEye);\n let direction=normalize(toEye);\n let focalPoint=lens+(si.position-lens)*cameraUniform.focusDistance/max(dot(si.position-lens,forward),1e-12);\n let projected=select(focalPoint,si.position,caustic.orthographic!=0u);\n let clip=caustic.viewProjection*vec4f(projected,1.0);\n if(clip.w<=0.0||dot(si.position-eye,forward)<=0.0) {\n return;\n }\n let film=clip.xy/clip.w*0.5+0.5;\n if(any(film<vec2f(0.0))||any(film>=vec2f(1.0))) {\n return;\n }\n var shadow:Ray;\n initRay(&shadow,si.position+EPS*direction,direction);\n if(intersectSceneShadow(shadow,sqrt(distanceSquared)-2.0*EPS,si.triangleIndex,si.instanceIndex)) {\n return;\n }\n var m=material;\n let normal=select(-si.normal,si.normal,dot(si.normal,-incoming.d)>=0.0);\n m.inside=dot(si.faceNormal,-incoming.d)<0.0;\n m.relativeIor=select(1.0/m.specularIor,m.specularIor,m.inside);\n${\n frames\n ? /* wgsl */ ` m.directionTangent=si.directionTangent;m.directionBitangent=si.directionBitangent;m.geometryTangent=si.geometryTangent;m.geometryBitangent=si.geometryBitangent;`\n : ''\n}\n${\n coat\n ? /* wgsl */ ` m.coatNormal=normal;m.geometricNormal=select(-si.faceNormal,si.faceNormal,dot(si.faceNormal,-incoming.d)>=0.0);`\n : ''\n}\n let prepared=openpbr_prepare(si.tangent,m,-incoming.d,normal);\n var pdf:f32;\n let response=openpbr_eval_prepared(prepared,direction,&pdf);\n let cameraCosine=dot(-direction,-normalize(cameraUniform.viewInv[2].xyz));\n if(cameraCosine<=0.0) {\n return;\n }\n let importance=caustic.cameraScale*rtUniform.outputSize.x*rtUniform.outputSize.y /\n select(max(distanceSquared*cameraCosine*cameraCosine*cameraCosine,1e-12),1.0,caustic.orthographic!=0u);\n let transmittance=exp(-extinction*sqrt(distanceSquared));\n let value=flux*transmittance*response*causticAdjoint(-incoming.d,direction,normal,si.faceNormal)*importance/f32(caustic.photonCount);\n let pixel=vec2u(film*rtUniform.outputSize);\n let index=(pixel.x+pixel.y*u32(rtUniform.outputSize.x))*3u;\n causticAtomicAdd(index,value.x);\n causticAtomicAdd(index+1u,value.y);\n causticAtomicAdd(index+2u,value.z);\n}\n`\n : ''\n}\n @compute @workgroup_size(64)\n fn main(@builtin(global_invocation_id) id:vec3u) {\n let photonIndex=id.x+id.y*4194240u;\n if(photonIndex>=caustic.photonCount) {\n return;\n }\n${mode === 'photonMapping' ? 'photonStore(photonIndex,vec4u(0u));' : ''}\n samplingPixel=vec2u(photonIndex%u32(rtUniform.outputSize.x),photonIndex/u32(rtUniform.outputSize.x));\n pixelSampleIndex=caustic.batch;\n samplingBounce=0u;\n hashedCounter=0u;\n rng_initialize(samplingPixel,i32(sampleSeed(caustic.batch,rtUniform.sequenceSeed)));\n var wavelength=0.0;\n var wavelengthPdf=1.0;\n if(SPECTRAL) {\n wavelength=spectrumSample(${SPECTRUM_PHOTON_DISTRIBUTION}u,causticEmission1D(causticDim(69u)),&wavelengthPdf);\n }\n var ls:LightSampleRec;\n causticSampleLight(caustic.casterSphere.xyz,vec3f(causticEmission2D(causticDim(60u)),causticEmission1D(causticDim(61u))),&ls);\n if(ls.pdf<=0.0) {\n return;\n }\n var infinite=ls.sourceType==0u;\n if(ls.sourceType==2u) {\n infinite=i32(analyticLights[ls.sourceIndex].litType)==DIRECTIONAL_LIGHT;\n }\n var origin=caustic.casterSphere.xyz+ls.direction*ls.dist;\n if(causticEmissionAreaPdf>0.0) { origin=causticEmissionOrigin; }\n var direction:vec3f;\n var flux:vec3f;\n var targetRadius=caustic.casterSphere.w;\n if(infinite) {\n direction=-ls.direction;\n // Mixture of projected caster disks. Every overlap contributes to the PDF.\n var area=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n let s=causticSphere(i);\n area+=s.w*s.w*causticTargetWeight(s);\n }\n var choice=causticEmission1D(causticDim(63u))*area;\n var sphere=causticSphere(0u);\n for(var i=0u;i<caustic.casterCount;i++) {\n sphere=causticSphere(i);\n choice-=sphere.w*sphere.w*causticTargetWeight(sphere);\n if(choice<=0.0) {\n break;\n }\n }\n targetRadius=sphere.w;\n var t:vec3f;\n var b:vec3f;\n sampling_orthonormal_basis(direction,&t,&b);\n let rnd=causticEmission2D(causticDim(62u));\n origin=sphere.xyz-direction*dot(sphere.xyz-caustic.casterSphere.xyz,direction)-direction*caustic.casterSphere.w;\n origin+=sphere.w*sqrt(rnd.x)*(t*cos(TWOPI*rnd.y)+b*sin(TWOPI*rnd.y));\n var overlaps=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n let s=causticSphere(i);\n let offset=origin-s.xyz;\n let projected=offset-direction*dot(offset,direction);\n if(dot(projected,projected)<=s.w*s.w) {\n overlaps+=causticTargetWeight(s);\n }\n }\n let diskPdf=overlaps/max(PI*area,1e-20);\n flux=ls.emission/(ls.pdf*diskPdf);\n }\n else if(ls.sourceType==2u&&i32(analyticLights[ls.sourceIndex].litType)==RECT_LIGHT&&ls.isDelta) {\n // A zero-spread rectangle is a collimated beam, matching PT's delta source.\n direction=ls.normal;\n flux=ls.emission/causticEmissionAreaPdf;\n }\n else {\n var areaPdf=ls.pdf*abs(dot(ls.normal,-ls.direction))/max(ls.dist*ls.dist,1e-20);\n if(causticEmissionAreaPdf>0.0) { areaPdf=causticEmissionAreaPdf; }\n if(ls.isDelta) {\n areaPdf=ls.selectionPmf;\n }\n if(areaPdf<=0.0) {\n return;\n }\n var directionPdf:f32;\n direction=causticDirection(origin,vec3f(causticEmission2D(causticDim(62u)),causticEmission1D(causticDim(63u))),&directionPdf,&targetRadius);\n var emission=ls.emission;\n var emissionCosine=max(0.0,dot(ls.normal,direction));\n if(ls.sourceType==2u) {\n let source=analyticLights[ls.sourceIndex];\n emission=source.emission;\n if(i32(source.litType)==SPOT_LIGHT) {\n emission*=evaluateSpotEmissionMultiplier(source,direction);\n }\n if(ls.isDelta) {\n emissionCosine=1.0;\n }\n if(i32(source.litType)==RECT_LIGHT&&emissionCosine<cos(0.5*PI*source.radiusOrSpread)) {\n return;\n }\n if(i32(source.litType)==RECT_LIGHT) {\n var textured:LightSampleRec;\n textured.emission=emission;\n light_apply_rect_texture(source,origin,source.position-0.5*(source.u+source.v),&textured);\n emission=textured.emission;\n }\n }\n flux=emission*emissionCosine/(areaPdf*directionPdf);\n }\n if(SPECTRAL) {\n flux*=spectrumRgb(wavelength)/(wavelengthPdf*${SPECTRUM_WAVELENGTH_RANGE}.0);\n }\n var ray:Ray;\n initRay(&ray,origin+EPS*direction,direction);\n var chain=0u;\n var singleT=false;\n var extinction=vec3f(0.0);\n var scattering=vec3f(0.0);\n var si:SurfaceInteraction;\n for(var depth=0;\n${mode === 'photonMapping' ? 'depth<=max(rtUniform.bounces,0)' : 'depth<20'}\n ;\n depth++) {\n samplingBounce=u32(depth);\n si.triangleIndex=-1;\n intersectScene(ray,&si,0,true,depth>0);\n if(!si.hit) {\n return;\n }\n var m:OpenPbrResolvedMaterial;\n getMaterial(&m,si.materialIndex,si.uv,si.uv1,si.instanceIndex,si.vertexColor);\n if(m.alpha<1.0&&causticEmission1D(causticDim(79u))>=m.alpha) {\n initRay(&ray,si.position+EPS*ray.d,ray.d);\n continue;\n }\n if(m.materialType==SHADOW_CATCHER) {\n return;\n }\n let segment=distance(ray.o,si.position);\n let channel=min(u32(sample1D(bounceDim(MEDIUM_CHANNEL))*3.0),2u);\n if(extinction[channel]>0.0&&any(scattering>vec3f(0.0))) {\n let sampled=-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)),1e-7))/extinction[channel];\n // A volume event belongs to PT's R3. Surface-reaching photons use the\n // same RGB survival mixture as PT, retaining absorption and scattering.\n if(sampled<segment) {\n return;\n }\n }\n let transmittance=exp(-extinction*segment);\n let survival=(transmittance.x+transmittance.y+transmittance.z)/3.0;\n flux*=transmittance/select(1.0,max(survival,1e-20),any(scattering>vec3f(0.0)));\n if(SPECTRAL) {\n m.specularIor=sampling_cauchy_ior(spectrumIorWavelength(wavelength),m.specularIor,m.transmissionDispersionScale,m.dispersionAbbeNumber);\n }\n if(!isCausticSpecular(m)) {\n let mneeSource=ls.sourceType!=0u;\n let r1=mneeSource&&chain==1u&&singleT&&m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0&&m.subsurfaceWeight==0.0;\n if(chain>0u\n${mode === 'lightTracing' ? '&&!(caustic.mnee!=0u&&r1)' : ''}){${\n mode === 'lightTracing'\n ? 'causticCameraConnect(si,m,ray,flux,extinction);'\n : /* wgsl */ `\n let position=bitcast<vec3u>(si.position);\n photonStore(photonIndex,vec4u(position,photonEncodeFlux(flux)));\n if((caustic.experiments&1u)!=0u) {\n var maximum=1e-8;\n for(var i=0u;i<caustic.casterCount;i++) { maximum=max(maximum,causticSphere(i).w); }\n let buckets=min(${PHOTON_GRID_SIZE}u,1u<<(32u-countLeadingZeros(max(256u,caustic.photonCount*2u)-1u)));\n let index=8u+buckets*4u+caustic.photonCount*3u+photonIndex;\n let width=textureDimensions(photonDirections).x;\n textureStore(photonDirections,vec2i(vec2u(index%width,index/width)),vec4u(bitcast<u32>(targetRadius/maximum)));\n }\n let incoming=vec2u(round(photonEncodeOct(-ray.d)*255.0));\n let normal=vec2u(round(photonEncodeOct(si.faceNormal)*vec2f(255.0,127.0)));\n photonStoreDirections(photonIndex,normal.x|(normal.y<<8u)|(select(0u,1u,r1)<<15u)|(incoming.x<<16u)|(incoming.y<<24u));\n`\n }\n}\nreturn;\n}\nlet view=-ray.d;\nlet normal=select(-si.normal,si.normal,dot(si.normal,view)>=0.0);\nm.inside=dot(si.faceNormal,view)<0.0;\nm.relativeIor=select(1.0/m.specularIor,m.specularIor,m.inside);\n${\n frames\n ? /* wgsl */ ` m.directionTangent=si.directionTangent;m.directionBitangent=si.directionBitangent;m.geometryTangent=si.geometryTangent;m.geometryBitangent=si.geometryBitangent;`\n : ''\n}\n${\n coat\n ? /* wgsl */ ` m.coatNormal=normal;m.geometricNormal=select(-si.faceNormal,si.faceNormal,dot(si.faceNormal,view)>=0.0);`\n : ''\n}\n let prepared=openpbr_prepare(si.tangent,m,view,normal);\n var next:vec3f;\n var pdf:f32;\n var transmission:bool;\n var roughness:f32;\n var specular:bool;\n var diffuse:bool;\n var lobe:u32;\n var marginal:f32;\n var full:vec3f;\n let response=openpbr_sample_prepared(prepared,vec3f(sample2D(bounceDim(BSDF_DIRECTION)),sample1D(bounceDim(BSDF_LOBE))),&next,&pdf,&transmission,&roughness,&specular,&diffuse,&lobe,&marginal,&full);\n if(!(pdf>0.0)) {\n return;\n }\n if(chain==0u&&ls.sourceType==0u&&transmission) {\n var reverse:Ray;\n initRay(&reverse,si.position,-ray.d);\n let bg=sampleSceneBackground(reverse);\n flux*=bg.rgb*bg.a/max(ls.emission,vec3f(1e-20));\n }\n flux*=response/pdf*causticAdjoint(view,next,normal,si.faceNormal);\n // The shared BSDF is a radiance sampler. Cancel its eta_i/eta_t squared\n // factor for adjoint (light-to-camera) propagation.\n if(transmission&&!m.thinWalled) {\n flux/=m.relativeIor*m.relativeIor;\n }\n // Match PT: a clear solid interface does not replace the active medium.\n if(transmission&&!m.thinWalled&&m.mediumType>0) {\n extinction=select(m.mediumExtinction,vec3f(0.0),m.inside);\n scattering=select(m.mediumScattering,vec3f(0.0),m.inside);\n }\n chain++;\n singleT=chain==1u&&((isCausticT(m)&&transmission)||(isCausticR(m)&&!transmission));\n initRay(&ray,si.position+EPS*next,next);\n}\n}\n`\n );\n}\n\nexport const causticAccumulateCompute = /* wgsl */ `\n @group(0) @binding(0) var<storage,read_write> splats:array<atomic<u32>>;\n @group(0) @binding(1) var<storage,read_write> accumulation:array<vec4f>;\n @compute @workgroup_size(64)\n fn main(@builtin(global_invocation_id) id:vec3u, @builtin(num_workgroups) groups:vec3u) {\n // Large images exceed one dispatch row; preserve the linear pixel order.\n let pixel=id.x+id.y*groups.x*64u;\n if(pixel>=arrayLength(&accumulation)) {\n return;\n }\n let i=pixel*3u;\n accumulation[pixel]+=vec4f(vec3f(bitcast<f32>(atomicLoad(&splats[i])),bitcast<f32>(atomicLoad(&splats[i+1u])),bitcast<f32>(atomicLoad(&splats[i+2u]))),1.0);\n }\n`;\n\n/** Native buffer resolve has the same independent batch normalization as web. */\nexport const causticBufferCompositeCompute = /* wgsl */ `\n @group(0)@binding(0)var<storage,read>pt:array<vec4f>;\n @group(0)@binding(1)var<storage,read>caustics:array<vec4f>;\n @group(0)@binding(2)var<storage,read>normal:array<vec4f>;\n @group(0)@binding(3)var<storage,read_write>output:array<vec4f>;\n @compute @workgroup_size(64)fn main(@builtin(global_invocation_id)id:vec3u,@builtin(num_workgroups)groups:vec3u) {\n // Large images exceed one dispatch row; preserve the linear pixel order.\n let pixel=id.x+id.y*groups.x*64u;\n if(pixel>=arrayLength(&output)) {\n return;\n }\n let c=caustics[pixel];\n let p=pt[pixel];\n output[pixel]=vec4f(p.rgb+c.rgb/max(c.a,1.0)*normal[pixel].a,p.a);\n }\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const _default: "fn groundedSurfaceDistance(point: vec3f, height: f32, radius: f32) -> f32 {\n let pointLength = length(point);\n if (pointLength < 0.00001) {\n return -radius;\n }\n\n let originalY = radius * point.y / pointLength;\n let transitionY = -1.5 * height;\n var surfaceRadius: f32;\n if (originalY >= 0.0) {\n surfaceRadius = radius;\n }\n else if (originalY < transitionY) {\n surfaceRadius = -height * pointLength / point.y;\n }\n else {\n let factor = 1.0\n - originalY * originalY / (3.0 * transitionY * transitionY);\n surfaceRadius = radius * factor;\n }\n return pointLength - surfaceRadius;\n}\n\nfn groundedBackgroundDirection(origin: vec3f, direction: vec3f) -> vec3f {\n if (!USE_GROUNDED_BACKGROUND) {\n return direction;\n }\n let params = rtUniform.groundedBackgroundParams;\n let rayDirection = normalize(direction);\n let center = vec3f(\n rtUniform.groundedBackgroundCenter.x,\n params.z + params.x,\n rtUniform.groundedBackgroundCenter.y\n );\n let localOrigin = origin - center;\n let projectedOrigin = dot(localOrigin, rayDirection);\n let discriminant = projectedOrigin * projectedOrigin\n - dot(localOrigin, localOrigin) + params.y * params.y;\n if (\n discriminant <= 0.0\n || groundedSurfaceDistance(localOrigin, params.x, params.y) > 0.0\n ) {\n return direction;\n }\n\n var farDistance = -projectedOrigin + sqrt(discriminant);\n if (farDistance <= 0.0) {\n return direction;\n }\n\n let sphereHit = localOrigin + rayDirection * farDistance;\n if (sphereHit.y >= 0.0) {\n return normalize(sphereHit);\n }\n\n if (rayDirection.y < -0.00001 && params.y > 1.5 * params.x) {\n let groundDistance = (-params.x - localOrigin.y) / rayDirection.y;\n let groundHit = localOrigin + rayDirection * groundDistance;\n let groundRadius = (2.0 / 3.0)\n * sqrt(params.y * params.y - 2.25 * params.x * params.x);\n if (groundDistance > 0.0 && length(groundHit.xz) <= groundRadius) {\n return normalize(groundHit);\n }\n }\n\n var nearDistance = 0.0;\n for (var i = 0; i < 14; i++) {\n let middleDistance = (nearDistance + farDistance) * 0.5;\n let middlePoint = localOrigin + rayDirection * middleDistance;\n if (groundedSurfaceDistance(middlePoint, params.x, params.y) > 0.0) {\n farDistance = middleDistance;\n }\n else {\n nearDistance = middleDistance;\n }\n }\n let hit = localOrigin + rayDirection * ((nearDistance + farDistance) * 0.5);\n return normalize(hit);\n}\n\nfn sampleSceneBackground(ray: Ray) -> vec4f {\n var bg = vec4f(0.0);\n if (USE_BACKGROUND_MAP) {\n let d = groundedBackgroundDirection(ray.o, ray.d);\n let t = rtUniform.backgroundMapTransform;\n let backgroundDirection = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);\n let rotation = rtUniform.backgroundMapRotation;\n let mapDirection = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * backgroundDirection;\n let backgroundSample = textureLinear(backgroundMap, cartesianToEquirect(mapDirection));\n bg = vec4f(backgroundSample.rgb * t.z, backgroundSample.a);\n }\n else if (USE_BACKGROUND) {\n bg = rtUniform.backgroundColor;\n }\n else if (USE_ENVMAP) {\n bg = textureLinear(envMap, environmentUv(ray.d));\n }\n return bg;\n}\n\n";
2
+ export default _default;
@@ -0,0 +1,102 @@
1
+ export default /* wgsl */ `fn dk(point: vec3f, height: f32, radius: f32) -> f32 {
2
+ let gc = length(point);
3
+ if (gc < 0.00001) {
4
+ return -radius;
5
+ }
6
+
7
+ let jf = radius * point.y / gc;
8
+ let iS = -1.5 * height;
9
+ var ez: f32;
10
+ if (jf >= 0.0) {
11
+ ez = radius;
12
+ }
13
+ else if (jf < iS) {
14
+ ez = -height * gc / point.y;
15
+ }
16
+ else {
17
+ let cA = 1.0
18
+ - jf * jf / (3.0 * iS * iS);
19
+ ez = radius * cA;
20
+ }
21
+ return gc - ez;
22
+ }
23
+
24
+ fn eW(origin: vec3f, direction: vec3f) -> vec3f {
25
+ if (!USE_GROUNDED_BACKGROUND) {
26
+ return direction;
27
+ }
28
+ let params = rtUniform.groundedBackgroundParams;
29
+ let bT = normalize(direction);
30
+ let center = vec3f(
31
+ rtUniform.groundedBackgroundCenter.x,
32
+ params.z + params.x,
33
+ rtUniform.groundedBackgroundCenter.y
34
+ );
35
+ let bA = origin - center;
36
+ let eN = dot(bA, bT);
37
+ let bk = eN * eN
38
+ - dot(bA, bA) + params.y * params.y;
39
+ if (
40
+ bk <= 0.0
41
+ || dk(bA, params.x, params.y) > 0.0
42
+ ) {
43
+ return direction;
44
+ }
45
+
46
+ var cB = -eN + sqrt(bk);
47
+ if (cB <= 0.0) {
48
+ return direction;
49
+ }
50
+
51
+ let pw = bA + bT * cB;
52
+ if (pw.y >= 0.0) {
53
+ return normalize(pw);
54
+ }
55
+
56
+ if (bT.y < -0.00001 && params.y > 1.5 * params.x) {
57
+ let iz = (-params.x - bA.y) / bT.y;
58
+ let pm = bA + bT * iz;
59
+ let qb = (2.0 / 3.0)
60
+ * sqrt(params.y * params.y - 2.25 * params.x * params.x);
61
+ if (iz > 0.0 && length(pm.xz) <= qb) {
62
+ return normalize(pm);
63
+ }
64
+ }
65
+
66
+ var cK = 0.0;
67
+ for (var i = 0; i < 14; i++) {
68
+ let fp = (cK + cB) * 0.5;
69
+ let rD = bA + bT * fp;
70
+ if (dk(rD, params.x, params.y) > 0.0) {
71
+ cB = fp;
72
+ }
73
+ else {
74
+ cK = fp;
75
+ }
76
+ }
77
+ let hit = bA + bT * ((cK + cB) * 0.5);
78
+ return normalize(hit);
79
+ }
80
+
81
+ fn fI(ray: Ray) -> vec4f {
82
+ var bg = vec4f(0.0);
83
+ if (USE_BACKGROUND_MAP) {
84
+ let d = eW(ray.o, ray.d);
85
+ let t = rtUniform.backgroundMapTransform;
86
+ let sh = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);
87
+ let rotation = rtUniform.backgroundMapRotation;
88
+ let hs = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * sh;
89
+ let aW = textureLinear(backgroundMap, eP(hs));
90
+ bg = vec4f(aW.rgb * t.z, aW.a);
91
+ }
92
+ else if (USE_BACKGROUND) {
93
+ bg = rtUniform.backgroundColor;
94
+ }
95
+ else if (USE_ENVMAP) {
96
+ bg = textureLinear(envMap, cU(ray.d));
97
+ }
98
+ return bg;
99
+ }
100
+
101
+ `;
102
+ //# sourceMappingURL=background.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/background.wgsl.ts"],"names":[],"mappings":"AAAA,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGzB,CAAC","sourcesContent":["export default /* wgsl */ `fn groundedSurfaceDistance(point: vec3f, height: f32, radius: f32) -> f32 {\n let pointLength = length(point);\n if (pointLength < 0.00001) {\n return -radius;\n }\n\n let originalY = radius * point.y / pointLength;\n let transitionY = -1.5 * height;\n var surfaceRadius: f32;\n if (originalY >= 0.0) {\n surfaceRadius = radius;\n }\n else if (originalY < transitionY) {\n surfaceRadius = -height * pointLength / point.y;\n }\n else {\n let factor = 1.0\n - originalY * originalY / (3.0 * transitionY * transitionY);\n surfaceRadius = radius * factor;\n }\n return pointLength - surfaceRadius;\n}\n\nfn groundedBackgroundDirection(origin: vec3f, direction: vec3f) -> vec3f {\n if (!USE_GROUNDED_BACKGROUND) {\n return direction;\n }\n let params = rtUniform.groundedBackgroundParams;\n let rayDirection = normalize(direction);\n let center = vec3f(\n rtUniform.groundedBackgroundCenter.x,\n params.z + params.x,\n rtUniform.groundedBackgroundCenter.y\n );\n let localOrigin = origin - center;\n let projectedOrigin = dot(localOrigin, rayDirection);\n let discriminant = projectedOrigin * projectedOrigin\n - dot(localOrigin, localOrigin) + params.y * params.y;\n if (\n discriminant <= 0.0\n || groundedSurfaceDistance(localOrigin, params.x, params.y) > 0.0\n ) {\n return direction;\n }\n\n var farDistance = -projectedOrigin + sqrt(discriminant);\n if (farDistance <= 0.0) {\n return direction;\n }\n\n let sphereHit = localOrigin + rayDirection * farDistance;\n if (sphereHit.y >= 0.0) {\n return normalize(sphereHit);\n }\n\n if (rayDirection.y < -0.00001 && params.y > 1.5 * params.x) {\n let groundDistance = (-params.x - localOrigin.y) / rayDirection.y;\n let groundHit = localOrigin + rayDirection * groundDistance;\n let groundRadius = (2.0 / 3.0)\n * sqrt(params.y * params.y - 2.25 * params.x * params.x);\n if (groundDistance > 0.0 && length(groundHit.xz) <= groundRadius) {\n return normalize(groundHit);\n }\n }\n\n var nearDistance = 0.0;\n for (var i = 0; i < 14; i++) {\n let middleDistance = (nearDistance + farDistance) * 0.5;\n let middlePoint = localOrigin + rayDirection * middleDistance;\n if (groundedSurfaceDistance(middlePoint, params.x, params.y) > 0.0) {\n farDistance = middleDistance;\n }\n else {\n nearDistance = middleDistance;\n }\n }\n let hit = localOrigin + rayDirection * ((nearDistance + farDistance) * 0.5);\n return normalize(hit);\n}\n\nfn sampleSceneBackground(ray: Ray) -> vec4f {\n var bg = vec4f(0.0);\n if (USE_BACKGROUND_MAP) {\n let d = groundedBackgroundDirection(ray.o, ray.d);\n let t = rtUniform.backgroundMapTransform;\n let backgroundDirection = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);\n let rotation = rtUniform.backgroundMapRotation;\n let mapDirection = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * backgroundDirection;\n let backgroundSample = textureLinear(backgroundMap, cartesianToEquirect(mapDirection));\n bg = vec4f(backgroundSample.rgb * t.z, backgroundSample.a);\n }\n else if (USE_BACKGROUND) {\n bg = rtUniform.backgroundColor;\n }\n else if (USE_ENVMAP) {\n bg = textureLinear(envMap, environmentUv(ray.d));\n }\n return bg;\n}\n\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const _default: "\nfn causticAdjoint(view:vec3f,outgoing:vec3f,shading:vec3f,geometric:vec3f)->f32 {\n let numerator=abs(dot(view,shading)*dot(outgoing,geometric));\n let denominator=abs(dot(view,geometric)*dot(outgoing,shading));\n if(denominator==0.0){return 0.0;}\n return numerator/denominator;\n}\n";
2
+ export default _default;
@@ -0,0 +1,12 @@
1
+ // Veach's adjoint shading-normal ratio. Directions point away from the vertex;
2
+ // view is toward the preceding light vertex, outgoing toward the camera.
3
+ // Reference: Veach 1997, thesis section 5.3 (mathematical formula, no copied code).
4
+ export default /* wgsl */ `
5
+ fn causticAdjoint(view:vec3f,xB:vec3f,shading:vec3f,geometric:vec3f)->f32 {
6
+ let je=abs(dot(view,shading)*dot(xB,geometric));
7
+ let ah=abs(dot(view,geometric)*dot(xB,shading));
8
+ if(ah==0.0){return 0.0;}
9
+ return je/ah;
10
+ }
11
+ `;
12
+ //# sourceMappingURL=causticAdjoint.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticAdjoint.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/causticAdjoint.wgsl.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,yEAAyE;AACzE,oFAAoF;AACpF,eAAe,UAAU,CAAC;;;;;;;CAOzB,CAAC","sourcesContent":["// Veach's adjoint shading-normal ratio. Directions point away from the vertex;\n// view is toward the preceding light vertex, outgoing toward the camera.\n// Reference: Veach 1997, thesis section 5.3 (mathematical formula, no copied code).\nexport default /* wgsl */ `\nfn causticAdjoint(view:vec3f,outgoing:vec3f,shading:vec3f,geometric:vec3f)->f32 {\n let numerator=abs(dot(view,shading)*dot(outgoing,geometric));\n let denominator=abs(dot(view,geometric)*dot(outgoing,shading));\n if(denominator==0.0){return 0.0;}\n return numerator/denominator;\n}\n`;\n"]}
@@ -0,0 +1,2 @@
1
+ declare const _default: "\nfn causticAtomicAdd(index:u32,value:f32) {\n if(!(value>0.0)||!(value<3.402823e38)){return;}\n var previous=atomicLoad(&splats[index]);\n loop {\n let sum=bitcast<f32>(previous)+value;\n let replacement=bitcast<u32>(sum);\n let result=atomicCompareExchangeWeak(&splats[index],previous,replacement);\n if(result.exchanged){break;}\n previous=result.old_value;\n }\n}\n";
2
+ export default _default;
@@ -0,0 +1,16 @@
1
+ // Float32 addition implemented with u32 compare/exchange works on baseline
2
+ // WebGPU, without a fixed radiance quantum or the Q16.16 saturation ceiling.
3
+ export default /* wgsl */ `
4
+ fn lF(index:u32,value:f32) {
5
+ if(!(value>0.0)||!(value<3.402823e38)){return;}
6
+ var previous=atomicLoad(&splats[index]);
7
+ loop {
8
+ let sum=bitcast<f32>(previous)+value;
9
+ let xH=bitcast<u32>(sum);
10
+ let result=atomicCompareExchangeWeak(&splats[index],previous,xH);
11
+ if(result.exchanged){break;}
12
+ previous=result.old_value;
13
+ }
14
+ }
15
+ `;
16
+ //# sourceMappingURL=causticAtomic.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"causticAtomic.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/causticAtomic.wgsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,eAAe,UAAU,CAAC;;;;;;;;;;;;CAYzB,CAAC","sourcesContent":["// Float32 addition implemented with u32 compare/exchange works on baseline\n// WebGPU, without a fixed radiance quantum or the Q16.16 saturation ceiling.\nexport default /* wgsl */ `\nfn causticAtomicAdd(index:u32,value:f32) {\n if(!(value>0.0)||!(value<3.402823e38)){return;}\n var previous=atomicLoad(&splats[index]);\n loop {\n let sum=bitcast<f32>(previous)+value;\n let replacement=bitcast<u32>(sum);\n let result=atomicCompareExchangeWeak(&splats[index],previous,replacement);\n if(result.exchanged){break;}\n previous=result.old_value;\n }\n}\n`;\n"]}
@@ -0,0 +1 @@
1
+ export declare function causticPartitionWGSL(mnee: boolean, lightTracing: boolean, photonMapping?: boolean, mneeMaxDepth?: number, hot?: boolean, photonMaxDepth?: number): string;
@@ -0,0 +1,62 @@
1
+ // Smooth classification is independent of the sampled lobe. The single-vertex
2
+ // marker records either an eligible delta transmission or a smooth reflection.
3
+ export function causticPartitionWGSL(mnee, lightTracing, photonMapping = false, mneeMaxDepth = 20, hot = false, photonMaxDepth = 20) {
4
+ return /* wgsl */ `
5
+ fn causticDim(slot:u32)->u32{return 1048576u+samplingBounce*4096u+slot;}
6
+ fn isCausticSpecular(m: OpenPbrResolvedMaterial) -> bool {
7
+ return m.baseWeight * (1.0 - m.baseMetalness) * (1.0 - m.transmissionWeight) <= 1e-6 &&
8
+ m.subsurfaceWeight <= 0.0 && m.fuzzWeight <= 0.0 && m.coatWeight <= 0.0 && m.causticRoughness <= 0.1;
9
+ }
10
+ fn isCausticT(m: OpenPbrResolvedMaterial) -> bool {
11
+ return isCausticSpecular(m) && m.transmissionWeight == 1.0 && m.causticRoughness == 0.0 && !m.thinWalled && !m.causticNormalMapped && m.alpha>=1.0;
12
+ }
13
+ fn isCausticR(m:OpenPbrResolvedMaterial)->bool{
14
+ return isCausticSpecular(m)&&m.causticRoughness==0.0&&!m.causticNormalMapped&&m.alpha>=1.0;
15
+ }
16
+ fn causticHitOwned(path: Path, zf: bool, xc: bool) -> bool {
17
+ let r1 = ${mnee} && zf && path.causticMneeReceiver && path.causticK == 1u && path.causticSingleT;
18
+ let r2 = ${lightTracing} && xc && path.causticK > 0u && path.causticReceiverPrimary;
19
+ let r3=${photonMapping}&&path.causticPhotonReceiver&&path.causticK>0u;
20
+ return path.causticHasReceiver && (r1 || r2 || r3);
21
+ }
22
+
23
+ var<private> causticHot:array<vec3f,15>;
24
+ fn causticHotRecord(path:Path,emission:vec3f,kind:u32){
25
+ if(!${hot}){return;}
26
+ let value=max(max(path.beta.x*emission.x,path.beta.y*emission.y),path.beta.z*emission.z);
27
+ if(value<=100.0){return;}
28
+ causticHot[9][kind]+=1.0;
29
+ causticHot[0]+=vec3f(1.0,f32(samplingBounce),f32(path.causticK));
30
+ causticHot[1]+=vec3f(select(0.0,1.0,path.causticHasReceiver),select(0.0,1.0,path.causticSingleT),select(0.0,1.0,path.causticReceiverPrimary));
31
+ causticHot[2]+=vec3f(select(0.0,1.0,path.causticMneeReceiver),select(0.0,1.0,path.causticPhotonReceiver),value);
32
+ if(samplingBounce>=3u&&samplingBounce<=8u){causticHot[samplingBounce]+=vec3f(1.0,f32(path.causticK),value);}
33
+ }
34
+ fn causticEstimateRecord(value:vec3f,kind:u32){
35
+ if(!${hot}){return;}
36
+ let peak=max(max(value.x,value.y),value.z);if(peak>100.0){causticHot[10u+kind]+=vec3f(1.0,f32(samplingBounce),peak);}
37
+ }
38
+ fn causticEmitterRecord(si:SurfaceInteraction,path:Path,weight:f32,emission:vec3f){
39
+ if(!${hot}){return;}
40
+ let value=path.beta*weight*emission;if(max(max(value.x,value.y),value.z)<=100.0){return;}
41
+ let material=materialsBuffer[si.materialIndex];
42
+ causticHot[12]+=vec3f(1.0+dot(si.faceNormal,-path.ray.d),select(0.0,1.0,path.fromEye),material.doubleSided);
43
+ causticHot[13]+=vec3f(weight,material.matType,rtUniform.lightWeightTotal);
44
+ causticHot[14]+=vec3f(path.scatteringPdf,dot(material.emission,luminance),max(max(path.beta.x,path.beta.y),path.beta.z));
45
+ }
46
+ fn causticAdvance(path: ptr<function, Path>, m: OpenPbrResolvedMaterial, transmission: bool, surface: bool) {
47
+ if (surface && isCausticSpecular(m)) {
48
+ (*path).causticK++;
49
+ (*path).causticSingleT = (*path).causticK == 1u && ((isCausticT(m) && transmission)||(isCausticR(m)&&!transmission));
50
+ } else {
51
+ (*path).causticK = 0u;
52
+ (*path).causticSingleT = false;
53
+ (*path).causticPhotonReceiver=surface&&samplingBounce<=${photonMaxDepth}u&&m.materialType!=SHADOW_CATCHER;
54
+ (*path).causticHasReceiver = m.materialType != SHADOW_CATCHER;
55
+ (*path).causticMneeReceiver = surface && samplingBounce<=${mneeMaxDepth}u &&
56
+ m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0 && m.subsurfaceWeight==0.0;
57
+ (*path).causticReceiverPrimary = (*path).fromEye && surface;
58
+ }
59
+ }
60
+ `;
61
+ }
62
+ //# sourceMappingURL=caustics.wgsl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caustics.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/caustics.wgsl.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,IAAa,EAAE,YAAqB,EAAC,aAAa,GAAC,KAAK,EAAC,YAAY,GAAC,EAAE,EAAC,GAAG,GAAC,KAAK,EAAC,cAAc,GAAC,EAAE;IACvI,OAAO,UAAU,CAAC;;;;;;;;;;;;;WAaP,IAAI;WACJ,YAAY;SACd,aAAa;;;;;;MAMjB,GAAG;;;;;;;;;;MAUH,GAAG;;;;MAIH,GAAG;;;;;;;;;;;;;;yDAcmD,cAAc;;2DAEZ,YAAY;;;;;CAK1E,CAAC;AACF,CAAC","sourcesContent":["// Smooth classification is independent of the sampled lobe. The single-vertex\n// marker records either an eligible delta transmission or a smooth reflection.\nexport function causticPartitionWGSL(mnee: boolean, lightTracing: boolean,photonMapping=false,mneeMaxDepth=20,hot=false,photonMaxDepth=20) {\n return /* wgsl */ `\nfn causticDim(slot:u32)->u32{return 1048576u+samplingBounce*4096u+slot;}\nfn isCausticSpecular(m: OpenPbrResolvedMaterial) -> bool {\n return m.baseWeight * (1.0 - m.baseMetalness) * (1.0 - m.transmissionWeight) <= 1e-6 &&\n m.subsurfaceWeight <= 0.0 && m.fuzzWeight <= 0.0 && m.coatWeight <= 0.0 && m.causticRoughness <= 0.1;\n}\nfn isCausticT(m: OpenPbrResolvedMaterial) -> bool {\n return isCausticSpecular(m) && m.transmissionWeight == 1.0 && m.causticRoughness == 0.0 && !m.thinWalled && !m.causticNormalMapped && m.alpha>=1.0;\n}\nfn isCausticR(m:OpenPbrResolvedMaterial)->bool{\n return isCausticSpecular(m)&&m.causticRoughness==0.0&&!m.causticNormalMapped&&m.alpha>=1.0;\n}\nfn causticHitOwned(path: Path, mneeLight: bool, tracingLight: bool) -> bool {\n let r1 = ${mnee} && mneeLight && path.causticMneeReceiver && path.causticK == 1u && path.causticSingleT;\n let r2 = ${lightTracing} && tracingLight && path.causticK > 0u && path.causticReceiverPrimary;\n let r3=${photonMapping}&&path.causticPhotonReceiver&&path.causticK>0u;\n return path.causticHasReceiver && (r1 || r2 || r3);\n}\n// Private evidence images count only unsuppressed PT contributions above 100 after MIS.\nvar<private> causticHot:array<vec3f,15>;\nfn causticHotRecord(path:Path,emission:vec3f,kind:u32){\n if(!${hot}){return;}\n let value=max(max(path.beta.x*emission.x,path.beta.y*emission.y),path.beta.z*emission.z);\n if(value<=100.0){return;}\n causticHot[9][kind]+=1.0;\n causticHot[0]+=vec3f(1.0,f32(samplingBounce),f32(path.causticK));\n causticHot[1]+=vec3f(select(0.0,1.0,path.causticHasReceiver),select(0.0,1.0,path.causticSingleT),select(0.0,1.0,path.causticReceiverPrimary));\n causticHot[2]+=vec3f(select(0.0,1.0,path.causticMneeReceiver),select(0.0,1.0,path.causticPhotonReceiver),value);\n if(samplingBounce>=3u&&samplingBounce<=8u){causticHot[samplingBounce]+=vec3f(1.0,f32(path.causticK),value);}\n}\nfn causticEstimateRecord(value:vec3f,kind:u32){\n if(!${hot}){return;}\n let peak=max(max(value.x,value.y),value.z);if(peak>100.0){causticHot[10u+kind]+=vec3f(1.0,f32(samplingBounce),peak);}\n}\nfn causticEmitterRecord(si:SurfaceInteraction,path:Path,weight:f32,emission:vec3f){\n if(!${hot}){return;}\n let value=path.beta*weight*emission;if(max(max(value.x,value.y),value.z)<=100.0){return;}\n let material=materialsBuffer[si.materialIndex];\n causticHot[12]+=vec3f(1.0+dot(si.faceNormal,-path.ray.d),select(0.0,1.0,path.fromEye),material.doubleSided);\n causticHot[13]+=vec3f(weight,material.matType,rtUniform.lightWeightTotal);\n causticHot[14]+=vec3f(path.scatteringPdf,dot(material.emission,luminance),max(max(path.beta.x,path.beta.y),path.beta.z));\n}\nfn causticAdvance(path: ptr<function, Path>, m: OpenPbrResolvedMaterial, transmission: bool, surface: bool) {\n if (surface && isCausticSpecular(m)) {\n (*path).causticK++;\n (*path).causticSingleT = (*path).causticK == 1u && ((isCausticT(m) && transmission)||(isCausticR(m)&&!transmission));\n } else {\n (*path).causticK = 0u;\n (*path).causticSingleT = false;\n (*path).causticPhotonReceiver=surface&&samplingBounce<=${photonMaxDepth}u&&m.materialType!=SHADOW_CATCHER;\n (*path).causticHasReceiver = m.materialType != SHADOW_CATCHER;\n (*path).causticMneeReceiver = surface && samplingBounce<=${mneeMaxDepth}u &&\n m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0 && m.subsurfaceWeight==0.0;\n (*path).causticReceiverPrimary = (*path).fromEye && surface;\n }\n}\n`;\n}\n"]}
@@ -11,12 +11,12 @@ const ROUGHNESS_MIN = 0.001;
11
11
 
12
12
 
13
13
 
14
- fn sR(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
14
+ fn un(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
15
15
  let normal = select(-geometricNormal, geometricNormal, dot(geometricNormal, direction) >= 0.0);
16
- let rm = vec3i(256.0 * normal);
16
+ let st = vec3i(256.0 * normal);
17
17
  let bits = bitcast<vec3i>(position);
18
- let xC = bitcast<vec3f>(bits + select(rm, -rm, position < vec3f(0.0)));
19
- return select(xC, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
18
+ let Aa = bitcast<vec3f>(bits + select(st, -st, position < vec3f(0.0)));
19
+ return select(Aa, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
20
20
  }
21
21
 
22
22
  `;
@@ -11,40 +11,40 @@ fn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {
11
11
 
12
12
  let size = vec2f(textureDimensions(tex, 0));
13
13
 
14
- let yq = _uv * size - vec2f(0.5);
15
- let xI = floor(yq);
16
- let f = fract(yq);
17
- let xH = vec2i(xI);
14
+ let uv2f = _uv * size - vec2f(0.5);
15
+ let Ah = floor(uv2f);
16
+ let f = fract(uv2f);
17
+ let Ag = vec2i(Ah);
18
18
  let maximum = vec2i(size) - vec2i(1);
19
19
 
20
20
 
21
- let s1 = textureLoad(tex, clamp(xH + vec2i(0, 0), vec2i(0), maximum), 0);
22
- let s2 = textureLoad(tex, clamp(xH + vec2i(1, 0), vec2i(0), maximum), 0);
23
- let s3 = textureLoad(tex, clamp(xH + vec2i(0, 1), vec2i(0), maximum), 0);
24
- let s4 = textureLoad(tex, clamp(xH + vec2i(1, 1), vec2i(0), maximum), 0);
21
+ let s1 = textureLoad(tex, clamp(Ag + vec2i(0, 0), vec2i(0), maximum), 0);
22
+ let s2 = textureLoad(tex, clamp(Ag + vec2i(1, 0), vec2i(0), maximum), 0);
23
+ let s3 = textureLoad(tex, clamp(Ag + vec2i(0, 1), vec2i(0), maximum), 0);
24
+ let s4 = textureLoad(tex, clamp(Ag + vec2i(1, 1), vec2i(0), maximum), 0);
25
25
 
26
26
  return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);
27
27
 
28
28
  }
29
29
 
30
- fn eV(gx: vec3f) -> vec2f {
31
- var phi = atan2(-gx.z, -gx.x);
30
+ fn eP(gz: vec3f) -> vec2f {
31
+ var phi = atan2(-gz.z, -gz.x);
32
32
  if (phi < 0.0) {
33
33
  phi += TWOPI;
34
34
  }
35
- let theta = acos(clamp(gx.y, -1.0, 1.0));
35
+ let theta = acos(clamp(gz.y, -1.0, 1.0));
36
36
  return vec2f(phi * 0.5 * INVPI, theta * INVPI);
37
37
  }
38
38
 
39
- fn ko() -> mat3x3f {
39
+ fn ky() -> mat3x3f {
40
40
  return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);
41
41
  }
42
42
 
43
- fn dm(nO: vec3f) -> vec2f {
44
- return eV(transpose(ko()) * nO);
43
+ fn cU(oA: vec3f) -> vec2f {
44
+ return eP(transpose(ky()) * oA);
45
45
  }
46
46
 
47
- fn rE(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
47
+ fn sN(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
48
48
  let size = vec2i(textureDimensions(envMap, 0));
49
49
 
50
50
  var left = 0;
@@ -70,7 +70,7 @@ let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;
70
70
  return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);
71
71
  }
72
72
 
73
- fn rD(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
73
+ fn sM(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
74
74
  let size = vec2i(textureDimensions(envMap, 0));
75
75
 
76
76
  var left = 0;
@@ -84,57 +84,57 @@ left = mid + 1;
84
84
  right = mid;
85
85
  }
86
86
  }
87
- let pO = left - 1;
87
+ let qG = left - 1;
88
88
 
89
89
 
90
90
 
91
- let s0 = textureLoad(envMapDistribution, vec2i(1 + pO, vOffset), 0).xy;
92
- let s1 = textureLoad(envMapDistribution, vec2i(1 + pO + 1, vOffset), 0).xy;
91
+ let s0 = textureLoad(envMapDistribution, vec2i(1 + qG, vOffset), 0).xy;
92
+ let s1 = textureLoad(envMapDistribution, vec2i(1 + qG + 1, vOffset), 0).xy;
93
93
 
94
94
  (*pdf).x = s0.y;
95
95
 
96
- return (f32(pO) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
96
+ return (f32(qG) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
97
97
  }
98
98
 
99
99
 
100
100
 
101
- fn eW(ew: vec2f, v: f32) -> f32 {
101
+ fn envMapSolidAnglePdf(partialPdf: vec2f, v: f32) -> f32 {
102
102
  if (!(v > 0.0 && v < 1.0)) { return 0.0; }
103
103
  let sinTheta = sin(min(v, 1.0 - v) * PI);
104
- return ew.x * ew.y * INVPI2 / (2.0 * sinTheta);
104
+ return partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);
105
105
  }
106
106
 
107
107
 
108
- fn pI(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
109
- var ew: vec2f;
108
+ fn qx(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
109
+ var partialPdf: vec2f;
110
110
  var vOffset: i32;
111
111
 
112
- (*uv).y = rE(random.x, &vOffset, &ew);
113
- (*uv).x = rD(random.y, vOffset, &ew);
112
+ (*uv).y = sN(random.x, &vOffset, &partialPdf);
113
+ (*uv).x = sM(random.y, vOffset, &partialPdf);
114
114
 
115
115
  let phi = (*uv).x * TWOPI;
116
116
  let theta = (*uv).y * PI;
117
- let ci = cos(theta);
117
+ let cv = cos(theta);
118
118
  let sinTheta = sin(theta);
119
- let vM = cos(phi);
120
- let vX = sin(phi);
119
+ let xV = cos(phi);
120
+ let yo = sin(phi);
121
121
 
122
- let dir = vec3f(-sinTheta * vM, ci, -sinTheta * vX);
122
+ let dir = vec3f(-sinTheta * xV, cv, -sinTheta * yo);
123
123
 
124
- *pdf = eW(ew, (*uv).y);
124
+ *pdf = envMapSolidAnglePdf(partialPdf, (*uv).y);
125
125
 
126
- return ko() * dir;
126
+ return ky() * dir;
127
127
  }
128
128
 
129
- fn iT(_uv: vec2f) -> f32 {
129
+ fn envMapPdf(_uv: vec2f) -> f32 {
130
130
  let size = vec2f(textureDimensions(envMap, 0));
131
131
 
132
- let xO = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));
132
+ let Al = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));
133
133
 
134
- let ub = textureLoad(envMapDistribution, vec2i(1 + xO.x, xO.y), 0).y;
135
- let uc = textureLoad(envMapDistribution, vec2i(0, xO.y), 0).y;
134
+ let vO = textureLoad(envMapDistribution, vec2i(1 + Al.x, Al.y), 0).y;
135
+ let vP = textureLoad(envMapDistribution, vec2i(0, Al.y), 0).y;
136
136
 
137
- return eW(vec2f(ub, uc), _uv.y);
137
+ return envMapSolidAnglePdf(vec2f(vO, vP), _uv.y);
138
138
  }
139
139
 
140
140
 
@@ -1,5 +1,7 @@
1
1
  export declare function createSceneHitQueryWgsl(hasAnisotropyDirections?: boolean): string;
2
- export declare function createSceneIntersectionsWgsl({ hasDisplacement, hasAnisotropyDirections, hasCoatNormals, blasLayoutMask, closestName, shadowName, bevelName, closestHitHook }: {
2
+ export declare function createSceneIntersectionsWgsl({ perInstanceBounds, compactVertices, hasDisplacement, hasAnisotropyDirections, hasCoatNormals, blasLayoutMask, closestName, shadowName, bevelName, closestHitHook }: {
3
+ perInstanceBounds?: boolean;
4
+ compactVertices?: boolean;
3
5
  hasDisplacement: boolean;
4
6
  hasAnisotropyDirections?: boolean;
5
7
  hasCoatNormals?: boolean;
@@ -9,10 +11,12 @@ export declare function createSceneIntersectionsWgsl({ hasDisplacement, hasAniso
9
11
  bevelName?: string;
10
12
  closestHitHook?: string;
11
13
  }): string;
12
- export default function getIntersectCode({ hasDisplacement, hasAnisotropyDirections, hasCoatNormals, blasLayoutMask, sceneIntersections }: {
14
+ export default function getIntersectCode({ perInstanceBounds, compactVertices, hasDisplacement, hasAnisotropyDirections, hasCoatNormals, blasLayoutMask, sceneIntersections }: {
15
+ perInstanceBounds?: boolean;
13
16
  hasDisplacement: boolean;
14
17
  hasAnisotropyDirections?: boolean;
15
18
  hasCoatNormals?: boolean;
16
19
  blasLayoutMask?: number;
17
20
  sceneIntersections?: string;
21
+ compactVertices?: boolean;
18
22
  }): string;