@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":"WGPUPhotonMap.js","sourceRoot":"","sources":["../../src/renderer/WGPUPhotonMap.ts"],"names":[],"mappings":"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","sourcesContent":["import {causticDiagnostics} from './causticDiagnostics.js';\nimport {WGPUCausticLightPass} from './WGPUCausticLightPass.js';\nimport {PHOTON_BYTES, PHOTON_GRID_SIZE, photonLayout, photonGridCompute} from './wgsl/photonMap.compute.js';\nexport {photonRadius} from './wgsl/photonMap.compute.js';\ninterface Batch {\n grid: GPUBuffer;\n uniform: GPUBuffer;\n data: GPUTexture;\n headers: GPUTexture;\n count: number;\n buckets: number;\n perCasterRadius: boolean;\n group: GPUBindGroup;\n}\n/** Batch-local spatial hash; accumulated estimates live in the camera path target. */\nexport class WGPUPhotonMap {\n readonly placeholder: GPUTexture;\n readonly emission: WGPUCausticLightPass;\n private readonly targets = new Map<object, Batch>();\n private readonly layout: GPUBindGroupLayout;\n private readonly pipelines: GPUComputePipeline[];\n constructor(private readonly device: GPUDevice) {\n this.placeholder = device.createTexture({\n label: 'Inactive photon binding',\n size: [1, 1],\n format: 'r32uint',\n usage: GPUTextureUsage.TEXTURE_BINDING\n });\n this.emission = new WGPUCausticLightPass(device, true);\n this.layout = device.createBindGroupLayout({\n entries: [\n {binding: 0, visibility: 4, texture: {sampleType: 'uint'}},\n {binding: 1, visibility: 4, buffer: {type: 'storage'}},\n {binding: 2, visibility: 4, buffer: {type: 'uniform'}},\n {binding: 4, visibility: 4, storageTexture: {access: 'write-only', format: 'r32uint'}}\n ]\n });\n const module = device.createShaderModule({label: 'Photon hash grid', code: photonGridCompute}),\n layout = device.createPipelineLayout({bindGroupLayouts: [this.layout]});\n this.pipelines = ['count', 'scanBlocks', 'scanSums', 'scatter'].map((entryPoint) =>\n device.createComputePipeline({label: 'Photon ' + entryPoint, layout, compute: {module, entryPoint}})\n );\n }\n ensure(target: object, requested: number) {\n const device = this.device,\n limit = device.limits.maxTextureDimension2D;\n const budget = causticDiagnostics.photonBudgetBytes ?? 128 * 1024 * 1024;\n const perCasterRadius = !!causticDiagnostics.photonPerCasterRadius;\n const bytesPerPhoton = perCasterRadius ? 32 : 28;\n let count = Math.max(\n 1,\n Math.min(\n Math.round(requested),\n Math.floor(device.limits.maxStorageBufferBindingSize / PHOTON_BYTES),\n Math.floor((limit * limit - PHOTON_GRID_SIZE * 4 - 8) / (perCasterRadius ? 4 : 3)),\n Math.floor(((causticDiagnostics.photonBudgetBytes ?? 128 * 1024 * 1024) - 13 * 1024 * 1024) / bytesPerPhoton)\n )\n );\n // Include row padding instead of assuming every texture is tightly packed.\n const allocationBytes = (n: number) => {\n const {buckets, texels} = photonLayout(n, perCasterRadius);\n const capacity = (texels: number) => Math.min(texels, limit) * Math.ceil(texels / limit);\n return (buckets + buckets / 256) * 32 + capacity(n) * 16 + capacity(texels) * 4 + 32;\n };\n while (count > 1 && allocationBytes(count) > budget) {\n count = Math.max(1, count - Math.ceil((allocationBytes(count) - budget) / bytesPerPhoton));\n }\n const existing = this.targets.get(target);\n if (existing?.count === count && existing.perCasterRadius === perCasterRadius) return existing;\n this.release(target);\n const {buckets, texels: headerTexels} = photonLayout(count, perCasterRadius),\n texels = count,\n width = Math.min(texels, limit),\n height = Math.ceil(texels / width);\n // One rgba32uint texel holds position and flux. Direction words live after\n // both sorted indices in the integer grid texture: 20 B payload + 8 B indices.\n const batch = {\n count,\n buckets,\n perCasterRadius,\n grid: device.createBuffer({\n label: 'Photon hash buckets',\n size: (buckets + buckets / 256) * 32,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST\n }),\n uniform: device.createBuffer({\n label: 'Photon grid parameters',\n size: 32,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n }),\n data: device.createTexture({\n label: 'Packed photon positions and flux',\n size: [width, height],\n format: 'rgba32uint',\n usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC\n }),\n headers: device.createTexture({\n label: 'Photon grid headers',\n size: [\n Math.min(headerTexels, limit),\n Math.ceil((headerTexels) / limit)\n ],\n format: 'r32uint',\n usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC\n })\n } as Batch;\n batch.group = this.device.createBindGroup({\n layout: this.layout,\n entries: [\n {binding: 0, resource: batch.data.createView()},\n {binding: 1, resource: {buffer: batch.grid}},\n {binding: 2, resource: {buffer: batch.uniform}},\n {binding: 4, resource: batch.headers.createView()}\n ]\n });\n this.targets.set(target, batch);\n return batch;\n }\n get(target: object) {\n return this.targets.get(target);\n }\n encode(\n encoder: GPUCommandEncoder,\n groups: GPUBindGroup[],\n target: object,\n radius: number,\n options: Parameters<WGPUCausticLightPass['encode']>[3] & {progressiveBatch?: number}\n ) {\n const batch = this.targets.get(target)!;\n if (causticDiagnostics.capturePhotons)\n causticDiagnostics.photonBatch = {\n device: this.device,\n data: batch.headers,\n emitted: batch.count,\n packed: true\n };\n encoder.clearBuffer(batch.grid);\n this.emission.emit(encoder, groups, batch.data, {\n ...options,\n photons: batch.count,\n photonMapping: true,\n photonDirections: batch.headers\n });\n const bytes = new ArrayBuffer(32);\n new Float32Array(bytes)[0] = radius;\n new Uint32Array(bytes)[1] = batch.count;\n new Float32Array(bytes)[2] = causticDiagnostics.photonScreenRadius === false ? 0 : 2;\n new Float32Array(bytes)[3] = causticDiagnostics.photonSkipQuery\n ? 1\n : causticDiagnostics.photonSkipVisible\n ? 2\n : 0;\n new Uint32Array(bytes)[4] = batch.buckets;\n new Float32Array(bytes)[5] = photonVisibleRadius(radius, options, new Float32Array(bytes)[2]);\n new Uint32Array(bytes)[6] = (+batch.perCasterRadius) |\n (Math.min(65535, Math.max(0, Math.round(causticDiagnostics.photonDeepScreenPixels ?? 0))) << 8);\n this.device.queue.writeBuffer(batch.uniform, 0, bytes);\n const group = batch.group;\n // Dispatch boundaries synchronize storage accesses. Offline batches share one\n // compute pass; timestamp profiling keeps separate passes for stage timings.\n const combined = options.querySet ? undefined : encoder.beginComputePass({label: 'Photon grid'});\n this.pipelines.forEach((pipeline, index) => {\n const pass =\n combined ??\n encoder.beginComputePass({\n label: ['Photon count', 'Photon scan blocks', 'Photon scan sums', 'Photon scatter'][index],\n timestampWrites: {\n querySet: options.querySet!,\n beginningOfPassWriteIndex: 8 + index * 2,\n endOfPassWriteIndex: 9 + index * 2\n }\n });\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, group);\n const groups =\n index === 1\n ? batch.buckets / 256\n : index === 2\n ? 1\n : Math.ceil((index === 3 ? Math.max(batch.count, batch.buckets) : batch.count) / 64);\n pass.dispatchWorkgroups(Math.min(groups, 65535), index === 1 || index === 2 ? 2 : Math.ceil(groups / 65535));\n if (!combined) pass.end();\n });\n combined?.end();\n }\n release(target: object) {\n const b = this.targets.get(target);\n if (!b) return;\n b.grid.destroy();\n b.uniform.destroy();\n b.data.destroy();\n b.headers.destroy();\n this.targets.delete(target);\n }\n bytes(target: object) {\n const b = this.targets.get(target);\n return b\n ? b.grid.size +\n b.uniform.size +\n b.data.width * b.data.height * 16 +\n b.headers.width * b.headers.height * 4\n : 0;\n }\n dispose() {\n for (const target of this.targets.keys()) this.release(target);\n this.emission.dispose();\n this.placeholder.destroy();\n }\n}\n/** Typical first-receiver footprint at the caster center; query disks stay exact. */\nexport function photonVisibleRadius(radius: number, options: {viewProjection: ArrayLike<number>; casterSphere: readonly number[]; width: number; orthographic?: boolean}, screenPixels = 2) {\n const m = options.viewProjection, p = options.casterSphere;\n const depth = options.orthographic ? 1 : Math.abs(m[3]*p[0]+m[7]*p[1]+m[11]*p[2]+m[15]);\n const projection = Math.hypot(m[0], m[4], m[8]);\n const footprint = 2 * depth / (options.width * projection) * screenPixels;\n return screenPixels > 0 && Number.isFinite(footprint) && footprint > 0 ? Math.min(radius, Math.max(1e-8, footprint)) : radius;\n}\n"]}
@@ -1,7 +1,9 @@
1
- export declare function createNormalizeRayTraceOutputWGSL(layers?: boolean, catcher?: boolean): string;
1
+ export declare function createNormalizeRayTraceOutputWGSL(layers?: boolean, catcher?: boolean, caustics?: boolean): string;
2
2
  type RayTraceOutput = 'color' | 'normal' | 'albedo' | 'shadowCatcher' | 'foreground' | 'catcherBackground';
3
3
  type RayTraceBuffers = {
4
4
  color: GPUBuffer;
5
+ caustic?: GPUBuffer;
6
+ wideHdr?: boolean;
5
7
  normal: GPUBuffer;
6
8
  albedo: GPUBuffer;
7
9
  shadowCatcher: GPUBuffer;
@@ -23,6 +25,12 @@ export declare class WGPURayTraceOutputPass {
23
25
  private _width;
24
26
  private _height;
25
27
  private _hasCatcher;
28
+ private _hasCaustics;
29
+ private _hasWideHdr;
30
+ private _maskPipeline?;
31
+ private _wideColor?;
32
+ private _wideForeground?;
33
+ private _causticPipeline?;
26
34
  private _needsUpdatePipeline;
27
35
  constructor(device: GPUDevice, zeroTexture?: GPUTexture | undefined);
28
36
  private readonly _retainedOutputs;
@@ -37,8 +45,12 @@ export declare class WGPURayTraceOutputPass {
37
45
  setSampleTileGrid(columns: number, rows: number): void;
38
46
  createPass(encoder: GPUCommandEncoder, inputBuffers: RayTraceBuffers, separateCatcher?: boolean): void;
39
47
  private _createOutputPass;
48
+ private _resolveMask;
49
+ private _addCaustics;
40
50
  private _destroyTextures;
41
51
  getMemoryBytes(): number;
42
52
  dispose(): void;
43
53
  }
54
+ export declare const causticCompositeWGSL = "\n@group(0)@binding(0)var base:texture_2d<f32>;\n@group(0)@binding(1)var<storage,read>caustics:array<vec4f>;\n@fragment fn main(@builtin(position)position:vec4f)->@location(0)vec4f{\n let pixel=vec2u(position.xy);let size=textureDimensions(base);\n let c=textureLoad(base,vec2i(pixel),0);let photon=caustics[pixel.x+(size.y-pixel.y-1u)*size.x];\n return vec4f(c.rgb+photon.rgb/max(photon.a,1.0),c.a);\n}\n";
55
+ export declare const shadowMaskResolveWGSL: string;
44
56
  export {};
@@ -3,7 +3,7 @@ import { getTargetShaderCache } from './WGPUShaderCache.js';
3
3
  import { textureBytes } from './gpuMemory.js';
4
4
  import shadowCatcherAccumulationWGSL from './wgsl/chunks/shadowCatcherAccumulation.wgsl.js';
5
5
  import { fullScreenQuadVertexShaderWGSL } from './WGPUFullQuadPass.js';
6
- export function createNormalizeRayTraceOutputWGSL(layers = false, catcher = true) {
6
+ export function createNormalizeRayTraceOutputWGSL(layers = false, catcher = true, caustics = false) {
7
7
  return /* wgsl */ `
8
8
  ${hdrResolveWGSL}
9
9
  @group(0) @binding(0) var<storage, read> colorBuffer: array<vec4f>;
@@ -12,20 +12,21 @@ ${hdrResolveWGSL}
12
12
  ${shadowCatcherAccumulationWGSL}
13
13
  @group(0) @binding(3) var<storage, read> shadowCatcherBuffer: array<ShadowCatcherAccumulation>;
14
14
 
15
- @group(1) @binding(0) var<uniform> sampleCount: f32;
15
+ ${caustics ? /* wgsl */ `@group(0) @binding(4) var<storage, read> causticBuffer: array<vec4f>;
16
+ ` : ''}@group(1) @binding(0) var<uniform> sampleCount: f32;
16
17
  @group(1) @binding(1) var<uniform> sampleTileGrid: vec2u;
17
18
 
18
19
  override outputWidth: f32;
19
20
  override outputHeight: f32;
20
21
 
21
- struct qa {
22
+ struct qZ {
22
23
  ${layers ? `@location(0) foreground: vec4f,
23
24
  @location(1) catcherBackground: vec4f` : `@location(0) color: vec4f,
24
25
  @location(1) normal: vec4f,
25
26
  @location(2) albedo: vec4f${catcher ? ',\n @location(3) shadowCatcher: vec4f' : ''}`}
26
27
  }
27
28
  @fragment
28
- fn main(@builtin(position) coord: vec4f) -> qa {
29
+ fn main(@builtin(position) coord: vec4f) -> qZ {
29
30
  let size = vec2u(u32(outputWidth), u32(outputHeight));
30
31
  let pixel = vec2u(u32(coord.x), size.y - u32(coord.y) - 1u);
31
32
  var idx = pixel.x + pixel.y * size.x;
@@ -34,17 +35,17 @@ var idx = pixel.x + pixel.y * size.x;
34
35
 
35
36
 
36
37
  if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {
37
- let wU = max(sampleTileGrid, vec2u(1u));
38
- let wq = min(
39
- ((pixel + wU / 2u) / wU) * wU,
40
- ((size - vec2u(1u)) / wU) * wU
38
+ let grid = max(sampleTileGrid, vec2u(1u));
39
+ let nearest = min(
40
+ ((pixel + grid / 2u) / grid) * grid,
41
+ ((size - vec2u(1u)) / grid) * grid
41
42
  );
42
- let tW = wq.x + wq.y * size.x;
43
- if (normalBuffer[tW].a > 0.0) {
44
- idx = tW;
43
+ let vI = nearest.x + nearest.y * size.x;
44
+ if (normalBuffer[vI].a > 0.0) {
45
+ idx = vI;
45
46
  }
46
47
  }
47
- var output: qa;
48
+ var output: qZ;
48
49
  if (normalBuffer[idx].a <= 0.0) {
49
50
  ${layers ? `output.foreground = vec4f(0.0);
50
51
  output.catcherBackground = vec4f(0.0);` : `output.color = vec4f(0.0);
@@ -64,22 +65,22 @@ let hit = albedo.a;
64
65
  let total = max(normal.a, 1.0);
65
66
  ${layers ? `
66
67
  let shadow = shadowCatcherBuffer[idx];
67
- let jo = max(hit - shadow.mask.b, 0.0);
68
+ let jz = max(hit - shadow.mask.b, 0.0);
68
69
 
69
70
 
70
71
  output.foreground = vec4f(
71
72
  (color.rgb - shadow.background.rgb)
72
- / select(total, jo, jo > 0.0),
73
+ / select(total, jz, jz > 0.0),
73
74
  clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)
74
75
  );
75
76
  output.catcherBackground = shadow.background / total;
76
77
  ` : `output.color = vec4f(
77
78
 
78
79
 
79
- vec3f(fK(color.r,normal.a,hit,1.0,true),
80
- fK(color.g,normal.a,hit,1.0,true),
81
- fK(color.b,normal.a,hit,1.0,true)),
82
- fK(color.a,normal.a,hit,1.0,false)
80
+ vec3f(fF(color.r,normal.a,hit,1.0,true),
81
+ fF(color.g,normal.a,hit,1.0,true),
82
+ fF(color.b,normal.a,hit,1.0,true)),
83
+ fF(color.a,normal.a,hit,1.0,false)
83
84
  );
84
85
 
85
86
  output.normal = vec4f(0.0);
@@ -95,7 +96,9 @@ ${catcher ? `let shadow = shadowCatcherBuffer[idx];
95
96
  output.shadowCatcher = vec4f(shadow.mask.rgb / total,
96
97
  shadow.mask.r / total * select(0.0, shadow.moments.z / shadow.moments.w, shadow.moments.w > 0.0));` : ''}
97
98
  `}
98
- return output;
99
+ ${caustics ? /* wgsl */ ` let causticColor=causticBuffer[idx].rgb/max(causticBuffer[idx].a,1.0);
100
+ ${layers ? 'output.foreground = vec4f(output.foreground.rgb+causticColor,output.foreground.a);' : 'output.color = vec4f(output.color.rgb+causticColor,output.color.a);'}
101
+ ` : ''} return output;
99
102
  }
100
103
  `;
101
104
  }
@@ -115,6 +118,12 @@ export class WGPURayTraceOutputPass {
115
118
  _width = 1;
116
119
  _height = 1;
117
120
  _hasCatcher = false;
121
+ _hasCaustics = false;
122
+ _hasWideHdr = false;
123
+ _maskPipeline;
124
+ _wideColor;
125
+ _wideForeground;
126
+ _causticPipeline;
118
127
  _needsUpdatePipeline = true;
119
128
  constructor(device, zeroTexture) {
120
129
  this.zeroTexture = zeroTexture;
@@ -145,6 +154,10 @@ export class WGPURayTraceOutputPass {
145
154
  }
146
155
  }
147
156
  getOutput(label) {
157
+ if (this._hasCaustics && label === 'color' && this._wideColor)
158
+ return this._wideColor;
159
+ if (this._hasCaustics && label === 'foreground' && this._wideForeground)
160
+ return this._wideForeground;
148
161
  return this[`_${label}Texture`] ?? this.zeroTexture;
149
162
  }
150
163
  _createTextures() {
@@ -163,7 +176,7 @@ export class WGPURayTraceOutputPass {
163
176
  this._colorTexture = device.createTexture({
164
177
  ...textureDescriptor,
165
178
  label: 'Ray Trace Color',
166
- format: 'rgba16float',
179
+ format: this._hasWideHdr ? 'rgba32float' : 'rgba16float',
167
180
  usage: GPUTextureUsage.RENDER_ATTACHMENT |
168
181
  GPUTextureUsage.TEXTURE_BINDING |
169
182
  GPUTextureUsage.COPY_SRC
@@ -177,11 +190,17 @@ export class WGPURayTraceOutputPass {
177
190
  ...textureDescriptor,
178
191
  label: 'Ray Trace Albedo'
179
192
  });
193
+ this._wideColor = this._wideForeground = undefined;
194
+ if (this._hasCaustics) {
195
+ this._wideColor = device.createTexture({ ...textureDescriptor, label: 'Caustic HDR color', format: 'rgba32float' });
196
+ if (this._hasCatcher)
197
+ this._wideForeground = device.createTexture({ ...textureDescriptor, label: 'Caustic HDR foreground', format: 'rgba32float' });
198
+ }
180
199
  if (this._hasCatcher) {
181
200
  this._foregroundTexture = device.createTexture({
182
201
  ...textureDescriptor,
183
202
  label: 'Ray Trace Foreground',
184
- format: 'rgba16float'
203
+ format: this._hasWideHdr ? 'rgba32float' : 'rgba16float'
185
204
  });
186
205
  this._catcherBackgroundTexture = device.createTexture({
187
206
  ...textureDescriptor,
@@ -235,12 +254,12 @@ export class WGPURayTraceOutputPass {
235
254
  },
236
255
  fragment: {
237
256
  module: getTargetShaderCache(device).createShaderModule({
238
- code: createNormalizeRayTraceOutputWGSL(false, this._hasCatcher)
257
+ code: createNormalizeRayTraceOutputWGSL(false, this._hasCatcher && !this._hasWideHdr, false)
239
258
  }),
240
259
  entryPoint: 'main',
241
260
  targets: [
242
261
  {
243
- format: 'rgba16float'
262
+ format: this._hasWideHdr ? 'rgba32float' : 'rgba16float'
244
263
  },
245
264
  {
246
265
  format: 'rgba8unorm'
@@ -248,7 +267,7 @@ export class WGPURayTraceOutputPass {
248
267
  {
249
268
  format: 'rgba8unorm'
250
269
  },
251
- ...(this._hasCatcher ? [{ format: 'rgba16float' }] : [])
270
+ ...(this._hasCatcher && !this._hasWideHdr ? [{ format: 'rgba16float' }] : [])
252
271
  ],
253
272
  constants: {
254
273
  outputWidth: this._width,
@@ -265,9 +284,9 @@ export class WGPURayTraceOutputPass {
265
284
  entryPoint: 'main'
266
285
  },
267
286
  fragment: {
268
- module: getTargetShaderCache(device).createShaderModule({ code: createNormalizeRayTraceOutputWGSL(true) }),
287
+ module: getTargetShaderCache(device).createShaderModule({ code: createNormalizeRayTraceOutputWGSL(true, true, false) }),
269
288
  entryPoint: 'main',
270
- targets: [{ format: 'rgba16float' }, { format: 'rgba16float' }],
289
+ targets: [{ format: this._hasWideHdr ? 'rgba32float' : 'rgba16float' }, { format: 'rgba16float' }],
271
290
  constants: { outputWidth: this._width, outputHeight: this._height }
272
291
  }
273
292
  });
@@ -279,6 +298,7 @@ export class WGPURayTraceOutputPass {
279
298
  !this._colorTexture) {
280
299
  this._width = width;
281
300
  this._height = height;
301
+ this._maskPipeline = undefined;
282
302
  this._createTextures();
283
303
  this._needsUpdatePipeline = true;
284
304
  }
@@ -290,6 +310,16 @@ export class WGPURayTraceOutputPass {
290
310
  this._device.queue.writeBuffer(this._uniformsBuffers.sampleTileGrid, 0, new Uint32Array([columns, rows]));
291
311
  }
292
312
  createPass(encoder, inputBuffers, separateCatcher = false) {
313
+ if (this._hasWideHdr !== !!inputBuffers.wideHdr) {
314
+ this._hasWideHdr = !!inputBuffers.wideHdr;
315
+ this._createTextures();
316
+ this._needsUpdatePipeline = true;
317
+ }
318
+ if (this._hasCaustics !== !!inputBuffers.caustic) {
319
+ this._hasCaustics = !!inputBuffers.caustic;
320
+ this._createTextures();
321
+ this._needsUpdatePipeline = true;
322
+ }
293
323
  if (this._hasCatcher !== separateCatcher) {
294
324
  this._hasCatcher = separateCatcher;
295
325
  this._createTextures();
@@ -299,12 +329,19 @@ export class WGPURayTraceOutputPass {
299
329
  this._createOutputPass(encoder, inputBuffers, false);
300
330
  if (separateCatcher)
301
331
  this._createOutputPass(encoder, inputBuffers, true);
332
+ if (this._hasWideHdr && separateCatcher)
333
+ this._resolveMask(encoder, inputBuffers);
334
+ if (inputBuffers.caustic) {
335
+ this._addCaustics(encoder, this._colorTexture, this._wideColor, inputBuffers.caustic);
336
+ if (separateCatcher)
337
+ this._addCaustics(encoder, this._foregroundTexture, this._wideForeground, inputBuffers.caustic);
338
+ }
302
339
  }
303
340
  _createOutputPass(encoder, inputBuffers, layers) {
304
341
  const pipeline = layers ? this._layersPipeline : this._pipeline;
305
342
  const textures = layers
306
343
  ? [this._foregroundTexture, this._catcherBackgroundTexture]
307
- : [this._colorTexture, this._normalTexture, this._albedoTexture, ...(this._hasCatcher ? [this._shadowCatcherTexture] : [])];
344
+ : [this._colorTexture, this._normalTexture, this._albedoTexture, ...(this._hasCatcher && !this._hasWideHdr ? [this._shadowCatcherTexture] : [])];
308
345
  const pass = encoder.beginRenderPass({
309
346
  colorAttachments: textures.map((texture) => ({
310
347
  view: texture.createView(),
@@ -328,7 +365,7 @@ export class WGPURayTraceOutputPass {
328
365
  buffer,
329
366
  ...(idx === 3 ? { offset: inputBuffers.shadowCatcherOffset ?? 0 } : {})
330
367
  }
331
- })).filter(entry => entry.binding < 3 || this._hasCatcher || layers)
368
+ })).filter(entry => entry.binding < 3 || (this._hasCatcher && !this._hasWideHdr) || layers).concat([])
332
369
  }));
333
370
  pass.setBindGroup(1, layers ? this._device.createBindGroup({
334
371
  layout: pipeline.getBindGroupLayout(1),
@@ -339,6 +376,31 @@ export class WGPURayTraceOutputPass {
339
376
  pass.draw(6, 1, 0, 0);
340
377
  pass.end();
341
378
  }
379
+ _resolveMask(encoder, input) {
380
+ const device = this._device;
381
+ this._maskPipeline ??= device.createRenderPipeline({ label: 'Wide HDR catcher mask', layout: 'auto',
382
+ vertex: { module: device.createShaderModule({ code: fullScreenQuadVertexShaderWGSL }), entryPoint: 'main' },
383
+ fragment: { module: device.createShaderModule({ code: shadowMaskResolveWGSL }), entryPoint: 'main', constants: { IMAGE_WIDTH: this._width, IMAGE_HEIGHT: this._height }, targets: [{ format: 'rgba16float' }] } });
384
+ const pass = encoder.beginRenderPass({ label: 'Wide HDR catcher mask', colorAttachments: [{ view: this._shadowCatcherTexture.createView(), loadOp: 'clear', storeOp: 'store' }] });
385
+ pass.setPipeline(this._maskPipeline);
386
+ pass.setBindGroup(0, device.createBindGroup({ layout: this._maskPipeline.getBindGroupLayout(0), entries: [
387
+ { binding: 0, resource: { buffer: input.normal } }, { binding: 1, resource: { buffer: input.shadowCatcher } },
388
+ { binding: 2, resource: { buffer: this._uniformsBuffers.sampleTileGrid } }, { binding: 3, resource: { buffer: this._uniformsBuffers.sampleCount } }
389
+ ] }));
390
+ pass.draw(6);
391
+ pass.end();
392
+ }
393
+ _addCaustics(encoder, base, target, caustics) {
394
+ const device = this._device;
395
+ this._causticPipeline ??= device.createRenderPipeline({ label: 'Caustic HDR resolve', layout: 'auto',
396
+ vertex: { module: device.createShaderModule({ code: fullScreenQuadVertexShaderWGSL }), entryPoint: 'main' },
397
+ fragment: { module: device.createShaderModule({ code: causticCompositeWGSL }), entryPoint: 'main', targets: [{ format: 'rgba32float' }] } });
398
+ const pass = encoder.beginRenderPass({ label: 'Caustic HDR resolve', colorAttachments: [{ view: target.createView(), loadOp: 'clear', storeOp: 'store' }] });
399
+ pass.setPipeline(this._causticPipeline);
400
+ pass.setBindGroup(0, device.createBindGroup({ layout: this._causticPipeline.getBindGroupLayout(0), entries: [{ binding: 0, resource: base.createView() }, { binding: 1, resource: { buffer: caustics } }] }));
401
+ pass.draw(6);
402
+ pass.end();
403
+ }
342
404
  _destroyTextures() {
343
405
  if (!this._colorTexture)
344
406
  return;
@@ -348,6 +410,7 @@ export class WGPURayTraceOutputPass {
348
410
  // far has completed; destroying them synchronously can make Dawn validate
349
411
  // the pending submit against an already-destroyed texture.
350
412
  const textures = [
413
+ this._wideColor, this._wideForeground,
351
414
  this._colorTexture,
352
415
  this._normalTexture,
353
416
  this._albedoTexture,
@@ -376,4 +439,35 @@ export class WGPURayTraceOutputPass {
376
439
  });
377
440
  }
378
441
  }
442
+ // A separate color attachment preserves float32 caustics within the baseline
443
+ // 32-byte MRT budget, including when the catcher needs its fourth attachment.
444
+ export const causticCompositeWGSL = /* wgsl */ `
445
+ @group(0)@binding(0)var base:texture_2d<f32>;
446
+ @group(0)@binding(1)var<storage,read>caustics:array<vec4f>;
447
+ @fragment fn main(@builtin(position)position:vec4f)->@location(0)vec4f{
448
+ let pixel=vec2u(position.xy);let size=textureDimensions(base);
449
+ let c=textureLoad(base,vec2i(pixel),0);let photon=caustics[pixel.x+(size.y-pixel.y-1u)*size.x];
450
+ return vec4f(c.rgb+photon.rgb/max(photon.a,1.0),c.a);
451
+ }
452
+ `;
453
+ export const shadowMaskResolveWGSL = /* wgsl */ `
454
+ ${shadowCatcherAccumulationWGSL}
455
+ override IMAGE_WIDTH:u32;override IMAGE_HEIGHT:u32;
456
+ @group(0)@binding(0)var<storage,read>normal:array<vec4f>;
457
+ @group(0)@binding(1)var<storage,read>shadow:array<ShadowCatcherAccumulation>;
458
+ @group(0)@binding(2)var<uniform>grid:vec2u;
459
+ @group(0)@binding(3)var<uniform>samples:f32;
460
+ @fragment fn main(@builtin(position)position:vec4f)->@location(0)vec4f{
461
+
462
+ let size=vec2u(IMAGE_WIDTH,IMAGE_HEIGHT);
463
+ let pixel=vec2u(u32(position.x),size.y-u32(position.y)-1u);var index=pixel.x+pixel.y*size.x;
464
+ if(samples<1.0&&normal[index].a<=0.0){
465
+ let tile=max(grid,vec2u(1u));let nearest=min(((pixel+tile/2u)/tile)*tile,((size-vec2u(1u))/tile)*tile);
466
+ let candidate=nearest.x+nearest.y*size.x;if(normal[candidate].a>0.0){index=candidate;}
467
+ }
468
+ if(normal[index].a<=0.0){return vec4f(0.0);}
469
+ let s=shadow[index];let total=max(normal[index].a,1.0);
470
+ return vec4f(s.mask.rgb/total,s.mask.r/total*select(0.0,s.moments.z/s.moments.w,s.moments.w>0.0));
471
+ }
472
+ `;
379
473
  //# sourceMappingURL=WGPURayTraceOutput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WGPURayTraceOutput.js","sourceRoot":"","sources":["../../src/renderer/WGPURayTraceOutput.ts"],"names":[],"mappings":"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","sourcesContent":["import {hdrResolveWGSL} from './wgsl/compose.frag.wgsl.js';\nimport { getTargetShaderCache } from './WGPUShaderCache.js';\nimport { textureBytes } from './gpuMemory.js';\nimport shadowCatcherAccumulationWGSL from './wgsl/chunks/shadowCatcherAccumulation.wgsl.js';\nimport { fullScreenQuadVertexShaderWGSL } from './WGPUFullQuadPass.js';\n\nexport function createNormalizeRayTraceOutputWGSL(layers = false, catcher = true) {\n return /* wgsl */ `\n${hdrResolveWGSL}\n@group(0) @binding(0) var<storage, read> colorBuffer: array<vec4f>;\n@group(0) @binding(1) var<storage, read> normalBuffer: array<vec4f>;\n@group(0) @binding(2) var<storage, read> albedoBuffer: array<vec4f>;\n${shadowCatcherAccumulationWGSL}\n@group(0) @binding(3) var<storage, read> shadowCatcherBuffer: array<ShadowCatcherAccumulation>;\n\n@group(1) @binding(0) var<uniform> sampleCount: f32;\n@group(1) @binding(1) var<uniform> sampleTileGrid: vec2u;\n\noverride outputWidth: f32;\noverride outputHeight: f32;\n\nstruct FSOutput {\n ${layers ? `@location(0) foreground: vec4f,\n @location(1) catcherBackground: vec4f` : `@location(0) color: vec4f,\n @location(1) normal: vec4f,\n @location(2) albedo: vec4f${catcher ? ',\\n @location(3) shadowCatcher: vec4f' : ''}`}\n}\n@fragment\nfn main(@builtin(position) coord: vec4f) -> FSOutput {\n let size = vec2u(u32(outputWidth), u32(outputHeight));\n let pixel = vec2u(u32(coord.x), size.y - u32(coord.y) - 1u);\n var idx = pixel.x + pixel.y * size.x;\n // Tiles are interleaved pixel grids, not contiguous rectangles. The first\n // tile samples (0, 0) of every grid cell across the current camera image.\n // Reconstruct only pixels not yet sampled, until the first sweep completes;\n // never write these display estimates back into the accumulated ray buffers.\n if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {\n let grid = max(sampleTileGrid, vec2u(1u));\n let nearest = min(\n ((pixel + grid / 2u) / grid) * grid,\n ((size - vec2u(1u)) / grid) * grid\n );\n let nearestIdx = nearest.x + nearest.y * size.x;\n if (normalBuffer[nearestIdx].a > 0.0) {\n idx = nearestIdx;\n }\n }\n var output: FSOutput;\n if (normalBuffer[idx].a <= 0.0) {\n ${layers ? `output.foreground = vec4f(0.0);\n output.catcherBackground = vec4f(0.0);` : `output.color = vec4f(0.0);\n output.normal = vec4f(0.0);\n output.albedo = vec4f(0.0);\n ${catcher ? 'output.shadowCatcher = vec4f(0.0);' : ''}`}\n return output;\n }\n let color = colorBuffer[idx];\n let normal = normalBuffer[idx];\n let albedo = albedoBuffer[idx];\n let hit = albedo.a;\n // The CPU count covers completed sweeps and is still zero during the first\n // interleaved sample. Use the actual per-pixel count, including for misses.\n // Empty pixels must remain finite: NaN alpha can poison float HDR output\n // even when its canvas uses opaque compositing.\n let total = max(normal.a, 1.0);\n ${layers ? `\n let shadow = shadowCatcherBuffer[idx];\n let foregroundHit = max(hit - shadow.mask.b, 0.0);\n // Separated background includes flat primary misses as well as catcher\n // samples. Neither belongs in the hit-normalized geometry color/alpha.\n output.foreground = vec4f(\n (color.rgb - shadow.background.rgb)\n / select(total, foregroundHit, foregroundHit > 0.0),\n clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)\n );\n output.catcherBackground = shadow.background / total;\n ` : `output.color = vec4f(\n // average the color by hit count.\n // So the antialised edge color will be correct when having transparent background\n vec3f(hdr_resolve_component(color.r,normal.a,hit,1.0,true),\n hdr_resolve_component(color.g,normal.a,hit,1.0,true),\n hdr_resolve_component(color.b,normal.a,hit,1.0,true)),\n hdr_resolve_component(color.a,normal.a,hit,1.0,false)\n );\n\n output.normal = vec4f(0.0);\n // Normalize to 0 - 1\n if (dot(normal.rgb, normal.rgb) > 0.1) {\n output.normal = vec4f(normal.rgb / total * 0.5 + 0.5, 1.0);\n }\n output.albedo = vec4f(albedo.rgb / total, clamp(hit / total, 0.0, 1.0));\n ${catcher ? `let shadow = shadowCatcherBuffer[idx];\n // Opacity is the ratio of the summed occluded and total light sample\n // counts; a per-sample ratio average would keep its low-sample bias. Alpha\n // carries it scaled by coverage, as composition expects.\n output.shadowCatcher = vec4f(shadow.mask.rgb / total,\n shadow.mask.r / total * select(0.0, shadow.moments.z / shadow.moments.w, shadow.moments.w > 0.0));` : ''}\n `}\n return output;\n}\n`;\n}\n\ntype RayTraceOutput = 'color' | 'normal' | 'albedo' | 'shadowCatcher'\n | 'foreground' | 'catcherBackground';\ntype RayTraceBuffers = {\n color: GPUBuffer;\n normal: GPUBuffer;\n albedo: GPUBuffer;\n shadowCatcher: GPUBuffer;\n shadowCatcherOffset?: number;\n};\n\nexport class WGPURayTraceOutputPass {\n private _device: GPUDevice;\n\n private _pipeline!: GPURenderPipeline;\n private _layersPipeline!: GPURenderPipeline;\n private _foregroundTexture!: GPUTexture;\n private _catcherBackgroundTexture!: GPUTexture;\n private _colorTexture!: GPUTexture;\n private _normalTexture!: GPUTexture;\n private _albedoTexture!: GPUTexture;\n private _shadowCatcherTexture!: GPUTexture;\n private _uniformBindGroup!: GPUBindGroup;\n\n private _uniformsBuffers;\n\n private _width = 1;\n private _height = 1;\n\n private _hasCatcher = false;\n private _needsUpdatePipeline = true;\n\n constructor(device: GPUDevice, private readonly zeroTexture?: GPUTexture) {\n this._device = device;\n this._uniformsBuffers = {\n sampleCount: device.createBuffer({\n size: 4,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n }),\n sampleTileGrid: device.createBuffer({\n size: 8,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n })\n };\n }\n\n private readonly _retainedOutputs = new Set<GPUTexture>();\n retainOutput(texture: GPUTexture) {\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (owned.some(label => this.getOutput(label) === texture)) this._retainedOutputs.add(texture);\n }\n releaseOutput(texture: GPUTexture) {\n if (!this._retainedOutputs.delete(texture)) return;\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (!owned.some(label => this.getOutput(label) === texture)) {\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => texture.destroy());\n }\n }\n\n getOutput(label: RayTraceOutput): GPUTexture {\n\n return this[`_${label}Texture`] ?? this.zeroTexture!;\n }\n\n private _createTextures() {\n const { _device: device, _width: width, _height: height } = this;\n const textureDescriptor: GPUTextureDescriptor = {\n size: {\n width,\n height,\n depthOrArrayLayers: 1\n },\n format: 'rgba8unorm',\n usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n };\n this._destroyTextures();\n this._colorTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Color',\n format: 'rgba16float',\n usage:\n GPUTextureUsage.RENDER_ATTACHMENT |\n GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n });\n this._normalTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Normal',\n usage: textureDescriptor.usage | GPUTextureUsage.COPY_SRC\n });\n this._albedoTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Albedo'\n });\n if (this._hasCatcher) {\n this._foregroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Foreground',\n format: 'rgba16float'\n });\n this._catcherBackgroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Catcher Background',\n format: 'rgba16float'\n });\n this._shadowCatcherTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Shadow Catcher',\n format: 'rgba16float'\n });\n } else {\n this._foregroundTexture = this._catcherBackgroundTexture = this._shadowCatcherTexture = undefined!;\n }\n }\n\n private _updateBindGroups() {\n const device = this._device;\n this._uniformBindGroup = device.createBindGroup({\n layout: this._pipeline.getBindGroupLayout(1),\n entries: [\n {\n binding: 0,\n resource: {\n buffer: this._uniformsBuffers.sampleCount\n }\n },\n {\n binding: 1,\n resource: {\n buffer: this._uniformsBuffers.sampleTileGrid\n }\n }\n ]\n });\n }\n\n private _updatePipeline() {\n if (!this._needsUpdatePipeline) {\n return;\n }\n this._needsUpdatePipeline = false;\n const device = this._device;\n\n this._pipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceOutput',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({\n code: fullScreenQuadVertexShaderWGSL\n }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({\n code: createNormalizeRayTraceOutputWGSL(false, this._hasCatcher)\n }),\n entryPoint: 'main',\n targets: [\n {\n format: 'rgba16float'\n },\n {\n format: 'rgba8unorm'\n },\n {\n format: 'rgba8unorm'\n },\n ...(this._hasCatcher ? [{format: 'rgba16float' as const}] : [])\n ],\n constants: {\n outputWidth: this._width,\n outputHeight: this._height\n }\n }\n });\n\n if (this._hasCatcher) this._layersPipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceLayers',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({ code: fullScreenQuadVertexShaderWGSL }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({ code: createNormalizeRayTraceOutputWGSL(true) }),\n entryPoint: 'main',\n targets: [{ format: 'rgba16float' }, { format: 'rgba16float' }],\n constants: { outputWidth: this._width, outputHeight: this._height }\n }\n });\n this._updateBindGroups();\n }\n\n setSize(width: number, height: number) {\n if (\n this._width !== width ||\n this._height !== height ||\n !this._colorTexture\n ) {\n this._width = width;\n this._height = height;\n this._createTextures();\n this._needsUpdatePipeline = true;\n }\n }\n\n setSampleCount(sampleCount: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleCount,\n 0,\n new Float32Array([sampleCount])\n );\n }\n\n setSampleTileGrid(columns: number, rows: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleTileGrid,\n 0,\n new Uint32Array([columns, rows])\n );\n }\n\n createPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n separateCatcher = false\n ) {\n if (this._hasCatcher !== separateCatcher) {\n this._hasCatcher = separateCatcher; this._createTextures(); this._needsUpdatePipeline = true;\n }\n this._updatePipeline();\n this._createOutputPass(encoder, inputBuffers, false);\n if (separateCatcher) this._createOutputPass(encoder, inputBuffers, true);\n }\n\n private _createOutputPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n layers: boolean\n ) {\n const pipeline = layers ? this._layersPipeline : this._pipeline;\n const textures = layers\n ? [this._foregroundTexture, this._catcherBackgroundTexture]\n : [this._colorTexture, this._normalTexture, this._albedoTexture, ...(this._hasCatcher ? [this._shadowCatcherTexture] : [])];\n const pass = encoder.beginRenderPass({\n colorAttachments: textures.map((texture) => ({\n view: texture.createView(),\n loadValue: { r: 0, g: 0, b: 0, a: 0 },\n storeOp: 'store',\n loadOp: 'clear'\n }))\n });\n pass.setPipeline(pipeline);\n\n pass.setBindGroup(\n 0,\n this._device.createBindGroup({\n label: 'rayTraceOutput',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n inputBuffers.color,\n inputBuffers.normal,\n inputBuffers.albedo,\n inputBuffers.shadowCatcher\n ].map((buffer, idx) => ({\n binding: idx,\n resource: {\n buffer,\n ...(idx === 3 ? { offset: inputBuffers.shadowCatcherOffset ?? 0 } : {})\n }\n })).filter(entry => entry.binding < 3 || this._hasCatcher || layers)\n })\n );\n pass.setBindGroup(1, layers ? this._device.createBindGroup({\n layout: pipeline.getBindGroupLayout(1),\n entries: Object.values(this._uniformsBuffers).map((buffer, binding) => ({\n binding, resource: { buffer }\n }))\n }) : this._uniformBindGroup);\n\n pass.draw(6, 1, 0, 0);\n pass.end();\n\n }\n\n private _destroyTextures() {\n if (!this._colorTexture) return;\n\n // These textures are also OIDN inputs. A resolution or preview-mode\n // change can replace them immediately after a denoising command buffer\n // was submitted. Keep the old resources alive until all work submitted so\n // far has completed; destroying them synchronously can make Dawn validate\n // the pending submit against an already-destroyed texture.\n const textures = [\n this._colorTexture,\n this._normalTexture,\n this._albedoTexture,\n this._shadowCatcherTexture,\n this._foregroundTexture,\n this._catcherBackgroundTexture\n ].filter((texture): texture is GPUTexture => !!texture && !this._retainedOutputs.has(texture));\n void this._device.queue\n .onSubmittedWorkDone()\n .catch(() => undefined)\n .then(() => textures.forEach((texture) => texture.destroy()));\n }\n\n getMemoryBytes() {\n const textures = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n return Object.values(this._uniformsBuffers).reduce((sum, buffer) => sum + buffer.size, 0)\n + Array.from(new Set([...textures.map(label => this[`_${label}Texture`]), ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + textureBytes(texture), 0);\n }\n\n dispose() {\n const retained = Array.from(this._retainedOutputs);\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => retained.forEach(texture => texture.destroy()));\n this._destroyTextures();\n this._retainedOutputs.clear();\n Object.keys(this._uniformsBuffers).forEach((key) => {\n (this._uniformsBuffers as any)[key].destroy();\n });\n }\n}\n"]}
1
+ {"version":3,"file":"WGPURayTraceOutput.js","sourceRoot":"","sources":["../../src/renderer/WGPURayTraceOutput.ts"],"names":[],"mappings":"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","sourcesContent":["import {hdrResolveWGSL} from './wgsl/compose.frag.wgsl.js';\nimport { getTargetShaderCache } from './WGPUShaderCache.js';\nimport { textureBytes } from './gpuMemory.js';\nimport shadowCatcherAccumulationWGSL from './wgsl/chunks/shadowCatcherAccumulation.wgsl.js';\nimport { fullScreenQuadVertexShaderWGSL } from './WGPUFullQuadPass.js';\n\nexport function createNormalizeRayTraceOutputWGSL(layers = false, catcher = true, caustics = false) {\n return /* wgsl */ `\n${hdrResolveWGSL}\n@group(0) @binding(0) var<storage, read> colorBuffer: array<vec4f>;\n@group(0) @binding(1) var<storage, read> normalBuffer: array<vec4f>;\n@group(0) @binding(2) var<storage, read> albedoBuffer: array<vec4f>;\n${shadowCatcherAccumulationWGSL}\n@group(0) @binding(3) var<storage, read> shadowCatcherBuffer: array<ShadowCatcherAccumulation>;\n\n${caustics ? /* wgsl */ `@group(0) @binding(4) var<storage, read> causticBuffer: array<vec4f>;\n` : ''}@group(1) @binding(0) var<uniform> sampleCount: f32;\n@group(1) @binding(1) var<uniform> sampleTileGrid: vec2u;\n\noverride outputWidth: f32;\noverride outputHeight: f32;\n\nstruct FSOutput {\n ${layers ? `@location(0) foreground: vec4f,\n @location(1) catcherBackground: vec4f` : `@location(0) color: vec4f,\n @location(1) normal: vec4f,\n @location(2) albedo: vec4f${catcher ? ',\\n @location(3) shadowCatcher: vec4f' : ''}`}\n}\n@fragment\nfn main(@builtin(position) coord: vec4f) -> FSOutput {\n let size = vec2u(u32(outputWidth), u32(outputHeight));\n let pixel = vec2u(u32(coord.x), size.y - u32(coord.y) - 1u);\n var idx = pixel.x + pixel.y * size.x;\n // Tiles are interleaved pixel grids, not contiguous rectangles. The first\n // tile samples (0, 0) of every grid cell across the current camera image.\n // Reconstruct only pixels not yet sampled, until the first sweep completes;\n // never write these display estimates back into the accumulated ray buffers.\n if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {\n let grid = max(sampleTileGrid, vec2u(1u));\n let nearest = min(\n ((pixel + grid / 2u) / grid) * grid,\n ((size - vec2u(1u)) / grid) * grid\n );\n let nearestIdx = nearest.x + nearest.y * size.x;\n if (normalBuffer[nearestIdx].a > 0.0) {\n idx = nearestIdx;\n }\n }\n var output: FSOutput;\n if (normalBuffer[idx].a <= 0.0) {\n ${layers ? `output.foreground = vec4f(0.0);\n output.catcherBackground = vec4f(0.0);` : `output.color = vec4f(0.0);\n output.normal = vec4f(0.0);\n output.albedo = vec4f(0.0);\n ${catcher ? 'output.shadowCatcher = vec4f(0.0);' : ''}`}\n return output;\n }\n let color = colorBuffer[idx];\n let normal = normalBuffer[idx];\n let albedo = albedoBuffer[idx];\n let hit = albedo.a;\n // The CPU count covers completed sweeps and is still zero during the first\n // interleaved sample. Use the actual per-pixel count, including for misses.\n // Empty pixels must remain finite: NaN alpha can poison float HDR output\n // even when its canvas uses opaque compositing.\n let total = max(normal.a, 1.0);\n ${layers ? `\n let shadow = shadowCatcherBuffer[idx];\n let foregroundHit = max(hit - shadow.mask.b, 0.0);\n // Separated background includes flat primary misses as well as catcher\n // samples. Neither belongs in the hit-normalized geometry color/alpha.\n output.foreground = vec4f(\n (color.rgb - shadow.background.rgb)\n / select(total, foregroundHit, foregroundHit > 0.0),\n clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)\n );\n output.catcherBackground = shadow.background / total;\n ` : `output.color = vec4f(\n // average the color by hit count.\n // So the antialised edge color will be correct when having transparent background\n vec3f(hdr_resolve_component(color.r,normal.a,hit,1.0,true),\n hdr_resolve_component(color.g,normal.a,hit,1.0,true),\n hdr_resolve_component(color.b,normal.a,hit,1.0,true)),\n hdr_resolve_component(color.a,normal.a,hit,1.0,false)\n );\n\n output.normal = vec4f(0.0);\n // Normalize to 0 - 1\n if (dot(normal.rgb, normal.rgb) > 0.1) {\n output.normal = vec4f(normal.rgb / total * 0.5 + 0.5, 1.0);\n }\n output.albedo = vec4f(albedo.rgb / total, clamp(hit / total, 0.0, 1.0));\n ${catcher ? `let shadow = shadowCatcherBuffer[idx];\n // Opacity is the ratio of the summed occluded and total light sample\n // counts; a per-sample ratio average would keep its low-sample bias. Alpha\n // carries it scaled by coverage, as composition expects.\n output.shadowCatcher = vec4f(shadow.mask.rgb / total,\n shadow.mask.r / total * select(0.0, shadow.moments.z / shadow.moments.w, shadow.moments.w > 0.0));` : ''}\n `}\n${caustics ? /* wgsl */ ` let causticColor=causticBuffer[idx].rgb/max(causticBuffer[idx].a,1.0);\n ${layers ? 'output.foreground = vec4f(output.foreground.rgb+causticColor,output.foreground.a);' : 'output.color = vec4f(output.color.rgb+causticColor,output.color.a);'}\n` : ''} return output;\n}\n`;\n}\n\ntype RayTraceOutput = 'color' | 'normal' | 'albedo' | 'shadowCatcher'\n | 'foreground' | 'catcherBackground';\ntype RayTraceBuffers = {\n color: GPUBuffer;\n caustic?: GPUBuffer;\n wideHdr?:boolean;\n normal: GPUBuffer;\n albedo: GPUBuffer;\n shadowCatcher: GPUBuffer;\n shadowCatcherOffset?: number;\n};\n\nexport class WGPURayTraceOutputPass {\n private _device: GPUDevice;\n\n private _pipeline!: GPURenderPipeline;\n private _layersPipeline!: GPURenderPipeline;\n private _foregroundTexture!: GPUTexture;\n private _catcherBackgroundTexture!: GPUTexture;\n private _colorTexture!: GPUTexture;\n private _normalTexture!: GPUTexture;\n private _albedoTexture!: GPUTexture;\n private _shadowCatcherTexture!: GPUTexture;\n private _uniformBindGroup!: GPUBindGroup;\n\n private _uniformsBuffers;\n\n private _width = 1;\n private _height = 1;\n\n private _hasCatcher = false;\n private _hasCaustics = false;\n private _hasWideHdr=false;\n private _maskPipeline?:GPURenderPipeline;\n private _wideColor?:GPUTexture;\n private _wideForeground?:GPUTexture;\n private _causticPipeline?:GPURenderPipeline;\n private _needsUpdatePipeline = true;\n\n constructor(device: GPUDevice, private readonly zeroTexture?: GPUTexture) {\n this._device = device;\n this._uniformsBuffers = {\n sampleCount: device.createBuffer({\n size: 4,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n }),\n sampleTileGrid: device.createBuffer({\n size: 8,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n })\n };\n }\n\n private readonly _retainedOutputs = new Set<GPUTexture>();\n retainOutput(texture: GPUTexture) {\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (owned.some(label => this.getOutput(label) === texture)) this._retainedOutputs.add(texture);\n }\n releaseOutput(texture: GPUTexture) {\n if (!this._retainedOutputs.delete(texture)) return;\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (!owned.some(label => this.getOutput(label) === texture)) {\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => texture.destroy());\n }\n }\n\n getOutput(label: RayTraceOutput): GPUTexture {\n\n if(this._hasCaustics&&label==='color'&&this._wideColor)return this._wideColor;\n if(this._hasCaustics&&label==='foreground'&&this._wideForeground)return this._wideForeground;\n return this[`_${label}Texture`] ?? this.zeroTexture!;\n }\n\n private _createTextures() {\n const { _device: device, _width: width, _height: height } = this;\n const textureDescriptor: GPUTextureDescriptor = {\n size: {\n width,\n height,\n depthOrArrayLayers: 1\n },\n format: 'rgba8unorm',\n usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n };\n this._destroyTextures();\n this._colorTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Color',\n format: this._hasWideHdr?'rgba32float':'rgba16float',\n usage:\n GPUTextureUsage.RENDER_ATTACHMENT |\n GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n });\n this._normalTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Normal',\n usage: textureDescriptor.usage | GPUTextureUsage.COPY_SRC\n });\n this._albedoTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Albedo'\n });\n this._wideColor=this._wideForeground=undefined;\n if(this._hasCaustics){\n this._wideColor=device.createTexture({...textureDescriptor,label:'Caustic HDR color',format:'rgba32float'});\n if(this._hasCatcher)this._wideForeground=device.createTexture({...textureDescriptor,label:'Caustic HDR foreground',format:'rgba32float'});\n }\n if (this._hasCatcher) {\n this._foregroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Foreground',\n format: this._hasWideHdr?'rgba32float':'rgba16float'\n });\n this._catcherBackgroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Catcher Background',\n format: 'rgba16float'\n });\n this._shadowCatcherTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Shadow Catcher',\n format: 'rgba16float'\n });\n } else {\n this._foregroundTexture = this._catcherBackgroundTexture = this._shadowCatcherTexture = undefined!;\n }\n }\n\n private _updateBindGroups() {\n const device = this._device;\n this._uniformBindGroup = device.createBindGroup({\n layout: this._pipeline.getBindGroupLayout(1),\n entries: [\n {\n binding: 0,\n resource: {\n buffer: this._uniformsBuffers.sampleCount\n }\n },\n {\n binding: 1,\n resource: {\n buffer: this._uniformsBuffers.sampleTileGrid\n }\n }\n ]\n });\n }\n\n private _updatePipeline() {\n if (!this._needsUpdatePipeline) {\n return;\n }\n this._needsUpdatePipeline = false;\n const device = this._device;\n\n this._pipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceOutput',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({\n code: fullScreenQuadVertexShaderWGSL\n }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({\n code: createNormalizeRayTraceOutputWGSL(false, this._hasCatcher&&!this._hasWideHdr, false)\n }),\n entryPoint: 'main',\n targets: [\n {\n format: this._hasWideHdr?'rgba32float':'rgba16float'\n },\n {\n format: 'rgba8unorm'\n },\n {\n format: 'rgba8unorm'\n },\n ...(this._hasCatcher&&!this._hasWideHdr ? [{format: 'rgba16float' as const}] : [])\n ],\n constants: {\n outputWidth: this._width,\n outputHeight: this._height\n }\n }\n });\n\n if (this._hasCatcher) this._layersPipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceLayers',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({ code: fullScreenQuadVertexShaderWGSL }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({ code: createNormalizeRayTraceOutputWGSL(true, true, false) }),\n entryPoint: 'main',\n targets: [{ format: this._hasWideHdr?'rgba32float':'rgba16float' }, { format: 'rgba16float' }],\n constants: { outputWidth: this._width, outputHeight: this._height }\n }\n });\n this._updateBindGroups();\n }\n\n setSize(width: number, height: number) {\n if (\n this._width !== width ||\n this._height !== height ||\n !this._colorTexture\n ) {\n this._width = width;\n this._height = height;this._maskPipeline=undefined;\n this._createTextures();\n this._needsUpdatePipeline = true;\n }\n }\n\n setSampleCount(sampleCount: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleCount,\n 0,\n new Float32Array([sampleCount])\n );\n }\n\n setSampleTileGrid(columns: number, rows: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleTileGrid,\n 0,\n new Uint32Array([columns, rows])\n );\n }\n\n createPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n separateCatcher = false\n ) {\n if(this._hasWideHdr!==!!inputBuffers.wideHdr){this._hasWideHdr=!!inputBuffers.wideHdr;this._createTextures();this._needsUpdatePipeline=true;}\n if (this._hasCaustics !== !!inputBuffers.caustic) {\n this._hasCaustics=!!inputBuffers.caustic;this._createTextures();this._needsUpdatePipeline=true;\n }\n if (this._hasCatcher !== separateCatcher) {\n this._hasCatcher = separateCatcher; this._createTextures(); this._needsUpdatePipeline = true;\n }\n this._updatePipeline();\n this._createOutputPass(encoder, inputBuffers, false);\n if (separateCatcher) this._createOutputPass(encoder, inputBuffers, true);\n if(this._hasWideHdr&&separateCatcher)this._resolveMask(encoder,inputBuffers);\n if(inputBuffers.caustic){\n this._addCaustics(encoder,this._colorTexture,this._wideColor!,inputBuffers.caustic);\n if(separateCatcher)this._addCaustics(encoder,this._foregroundTexture,this._wideForeground!,inputBuffers.caustic);\n }\n }\n\n private _createOutputPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n layers: boolean\n ) {\n const pipeline = layers ? this._layersPipeline : this._pipeline;\n const textures = layers\n ? [this._foregroundTexture, this._catcherBackgroundTexture]\n : [this._colorTexture, this._normalTexture, this._albedoTexture, ...(this._hasCatcher&&!this._hasWideHdr ? [this._shadowCatcherTexture] : [])];\n const pass = encoder.beginRenderPass({\n colorAttachments: textures.map((texture) => ({\n view: texture.createView(),\n loadValue: { r: 0, g: 0, b: 0, a: 0 },\n storeOp: 'store',\n loadOp: 'clear'\n }))\n });\n pass.setPipeline(pipeline);\n\n pass.setBindGroup(\n 0,\n this._device.createBindGroup({\n label: 'rayTraceOutput',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n inputBuffers.color,\n inputBuffers.normal,\n inputBuffers.albedo,\n inputBuffers.shadowCatcher\n ].map((buffer, idx) => ({\n binding: idx,\n resource: {\n buffer,\n ...(idx === 3 ? { offset: inputBuffers.shadowCatcherOffset ?? 0 } : {})\n }\n })).filter(entry => entry.binding < 3 || (this._hasCatcher&&!this._hasWideHdr) || layers).concat(\n []\n )\n })\n );\n pass.setBindGroup(1, layers ? this._device.createBindGroup({\n layout: pipeline.getBindGroupLayout(1),\n entries: Object.values(this._uniformsBuffers).map((buffer, binding) => ({\n binding, resource: { buffer }\n }))\n }) : this._uniformBindGroup);\n\n pass.draw(6, 1, 0, 0);\n pass.end();\n\n }\n\n private _resolveMask(encoder:GPUCommandEncoder,input:RayTraceBuffers){\n const device=this._device;\n this._maskPipeline??=device.createRenderPipeline({label:'Wide HDR catcher mask',layout:'auto',\n vertex:{module:device.createShaderModule({code:fullScreenQuadVertexShaderWGSL}),entryPoint:'main'},\n fragment:{module:device.createShaderModule({code:shadowMaskResolveWGSL}),entryPoint:'main',constants:{IMAGE_WIDTH:this._width,IMAGE_HEIGHT:this._height},targets:[{format:'rgba16float'}]}});\n const pass=encoder.beginRenderPass({label:'Wide HDR catcher mask',colorAttachments:[{view:this._shadowCatcherTexture.createView(),loadOp:'clear',storeOp:'store'}]});\n pass.setPipeline(this._maskPipeline);pass.setBindGroup(0,device.createBindGroup({layout:this._maskPipeline.getBindGroupLayout(0),entries:[\n {binding:0,resource:{buffer:input.normal}},{binding:1,resource:{buffer:input.shadowCatcher}},\n {binding:2,resource:{buffer:this._uniformsBuffers.sampleTileGrid}},{binding:3,resource:{buffer:this._uniformsBuffers.sampleCount}}]}));\n pass.draw(6);pass.end();\n }\n\n private _addCaustics(encoder:GPUCommandEncoder,base:GPUTexture,target:GPUTexture,caustics:GPUBuffer){\n const device=this._device;\n this._causticPipeline??=device.createRenderPipeline({label:'Caustic HDR resolve',layout:'auto',\n vertex:{module:device.createShaderModule({code:fullScreenQuadVertexShaderWGSL}),entryPoint:'main'},\n fragment:{module:device.createShaderModule({code:causticCompositeWGSL}),entryPoint:'main',targets:[{format:'rgba32float'}]}});\n const pass=encoder.beginRenderPass({label:'Caustic HDR resolve',colorAttachments:[{view:target.createView(),loadOp:'clear',storeOp:'store'}]});\n pass.setPipeline(this._causticPipeline);pass.setBindGroup(0,device.createBindGroup({layout:this._causticPipeline.getBindGroupLayout(0),entries:[{binding:0,resource:base.createView()},{binding:1,resource:{buffer:caustics}}]}));\n pass.draw(6);pass.end();\n }\n\n private _destroyTextures() {\n if (!this._colorTexture) return;\n\n // These textures are also OIDN inputs. A resolution or preview-mode\n // change can replace them immediately after a denoising command buffer\n // was submitted. Keep the old resources alive until all work submitted so\n // far has completed; destroying them synchronously can make Dawn validate\n // the pending submit against an already-destroyed texture.\n const textures = [\n this._wideColor,this._wideForeground,\n this._colorTexture,\n this._normalTexture,\n this._albedoTexture,\n this._shadowCatcherTexture,\n this._foregroundTexture,\n this._catcherBackgroundTexture\n ].filter((texture): texture is GPUTexture => !!texture && !this._retainedOutputs.has(texture));\n void this._device.queue\n .onSubmittedWorkDone()\n .catch(() => undefined)\n .then(() => textures.forEach((texture) => texture.destroy()));\n }\n\n getMemoryBytes() {\n const textures = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n return Object.values(this._uniformsBuffers).reduce((sum, buffer) => sum + buffer.size, 0)\n + Array.from(new Set([...textures.map(label => this[`_${label}Texture`]), ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + textureBytes(texture), 0);\n }\n\n dispose() {\n const retained = Array.from(this._retainedOutputs);\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => retained.forEach(texture => texture.destroy()));\n this._destroyTextures();\n this._retainedOutputs.clear();\n Object.keys(this._uniformsBuffers).forEach((key) => {\n (this._uniformsBuffers as any)[key].destroy();\n });\n }\n}\n\n// A separate color attachment preserves float32 caustics within the baseline\n// 32-byte MRT budget, including when the catcher needs its fourth attachment.\nexport const causticCompositeWGSL=/* wgsl */ `\n@group(0)@binding(0)var base:texture_2d<f32>;\n@group(0)@binding(1)var<storage,read>caustics:array<vec4f>;\n@fragment fn main(@builtin(position)position:vec4f)->@location(0)vec4f{\n let pixel=vec2u(position.xy);let size=textureDimensions(base);\n let c=textureLoad(base,vec2i(pixel),0);let photon=caustics[pixel.x+(size.y-pixel.y-1u)*size.x];\n return vec4f(c.rgb+photon.rgb/max(photon.a,1.0),c.a);\n}\n`;\n\nexport const shadowMaskResolveWGSL=/* wgsl */ `\n${shadowCatcherAccumulationWGSL}\noverride IMAGE_WIDTH:u32;override IMAGE_HEIGHT:u32;\n@group(0)@binding(0)var<storage,read>normal:array<vec4f>;\n@group(0)@binding(1)var<storage,read>shadow:array<ShadowCatcherAccumulation>;\n@group(0)@binding(2)var<uniform>grid:vec2u;\n@group(0)@binding(3)var<uniform>samples:f32;\n@fragment fn main(@builtin(position)position:vec4f)->@location(0)vec4f{\n // Image dimensions are supplied by the actual attachment through a uniform.\n let size=vec2u(IMAGE_WIDTH,IMAGE_HEIGHT);\n let pixel=vec2u(u32(position.x),size.y-u32(position.y)-1u);var index=pixel.x+pixel.y*size.x;\n if(samples<1.0&&normal[index].a<=0.0){\n let tile=max(grid,vec2u(1u));let nearest=min(((pixel+tile/2u)/tile)*tile,((size-vec2u(1u))/tile)*tile);\n let candidate=nearest.x+nearest.y*size.x;if(normal[candidate].a>0.0){index=candidate;}\n }\n if(normal[index].a<=0.0){return vec4f(0.0);}\n let s=shadow[index];let total=max(normal[index].a,1.0);\n return vec4f(s.mask.rgb/total,s.mask.r/total*select(0.0,s.moments.z/s.moments.w,s.moments.w>0.0));\n}\n`;\n"]}