@meimu/mutracer 0.1.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (590) hide show
  1. package/LICENSES/Classroom-CC0.txt +121 -0
  2. package/README.md +10 -7
  3. package/THIRD_PARTY_NOTICES.md +13 -8
  4. package/dist/assets/bvh.worker.js +1 -1
  5. package/dist/mutracer.umd.js +12316 -9228
  6. package/docs/api.md +232 -21
  7. package/docs/caustics.md +80 -0
  8. package/docs/denoising.md +30 -15
  9. package/docs/materials.md +6 -5
  10. package/docs/performance.md +5 -2
  11. package/docs/progressive-rendering.md +73 -1
  12. package/docs/technical/continuous-spectrum.md +93 -0
  13. package/docs/threejs.md +14 -5
  14. package/docs/updates.md +46 -2
  15. package/docs/viewer-checklist.md +65 -0
  16. package/docs/viewer.md +15 -8
  17. package/lib/Display.d.ts +13 -2
  18. package/lib/Display.js +28 -7
  19. package/lib/Display.js.map +1 -1
  20. package/lib/Engine.d.ts +4 -0
  21. package/lib/Engine.js +99 -37
  22. package/lib/Engine.js.map +1 -1
  23. package/lib/Render.d.ts +98 -15
  24. package/lib/Render.js +275 -27
  25. package/lib/Render.js.map +1 -1
  26. package/lib/RenderLoop.d.ts +11 -1
  27. package/lib/RenderLoop.js +120 -15
  28. package/lib/RenderLoop.js.map +1 -1
  29. package/lib/main.d.ts +6 -3
  30. package/lib/main.js +1 -0
  31. package/lib/main.js.map +1 -1
  32. package/lib/math/access.d.ts +4 -0
  33. package/lib/math/access.js +10 -0
  34. package/lib/math/access.js.map +1 -0
  35. package/lib/math/mat3.d.ts +4 -0
  36. package/lib/math/mat3.js +54 -0
  37. package/lib/math/mat3.js.map +1 -0
  38. package/lib/math/mat4.d.ts +19 -0
  39. package/lib/math/mat4.js +413 -0
  40. package/lib/math/mat4.js.map +1 -0
  41. package/lib/math/storage.d.ts +6 -0
  42. package/lib/math/storage.js +22 -0
  43. package/lib/math/storage.js.map +1 -0
  44. package/lib/math/types.d.ts +3 -0
  45. package/lib/math/types.js +2 -0
  46. package/lib/math/types.js.map +1 -0
  47. package/lib/math/vec2.d.ts +13 -0
  48. package/lib/math/vec2.js +52 -0
  49. package/lib/math/vec2.js.map +1 -0
  50. package/lib/math/vec3.d.ts +23 -0
  51. package/lib/math/vec3.js +139 -0
  52. package/lib/math/vec3.js.map +1 -0
  53. package/lib/math.d.ts +5 -17
  54. package/lib/math.js +5 -55
  55. package/lib/math.js.map +1 -1
  56. package/lib/oidn.d.ts +1 -1
  57. package/lib/oidn.js +4 -2
  58. package/lib/oidn.js.map +1 -1
  59. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  60. package/lib/renderer/AovPrimitiveCache.d.ts +10 -0
  61. package/lib/renderer/AovPrimitiveCache.js +48 -0
  62. package/lib/renderer/AovPrimitiveCache.js.map +1 -0
  63. package/lib/renderer/Box3.d.ts +5 -0
  64. package/lib/renderer/Box3.js +9 -0
  65. package/lib/renderer/Box3.js.map +1 -0
  66. package/lib/renderer/GPUTraceQueue.d.ts +11 -0
  67. package/lib/renderer/GPUTraceQueue.js +33 -0
  68. package/lib/renderer/GPUTraceQueue.js.map +1 -0
  69. package/lib/renderer/MaterialData.d.ts +15 -0
  70. package/lib/renderer/MaterialData.js +61 -0
  71. package/lib/renderer/MaterialData.js.map +1 -0
  72. package/lib/renderer/MaterialTable.d.ts +11 -98
  73. package/lib/renderer/MaterialTable.js +34 -412
  74. package/lib/renderer/MaterialTable.js.map +1 -1
  75. package/lib/renderer/RenderingPipeline.d.ts +36 -13
  76. package/lib/renderer/RenderingPipeline.js +1 -17
  77. package/lib/renderer/RenderingPipeline.js.map +1 -1
  78. package/lib/renderer/TileRender.d.ts +0 -1
  79. package/lib/renderer/TileRender.js +14 -1
  80. package/lib/renderer/TileRender.js.map +1 -1
  81. package/lib/renderer/WGPUAov.d.ts +39 -0
  82. package/lib/renderer/WGPUAov.js +239 -0
  83. package/lib/renderer/WGPUAov.js.map +1 -0
  84. package/lib/renderer/WGPUBindlessMaterialData.d.ts +17 -0
  85. package/lib/renderer/WGPUBindlessMaterialData.js +48 -0
  86. package/lib/renderer/WGPUBindlessMaterialData.js.map +1 -0
  87. package/lib/renderer/WGPUBindlessTextures.d.ts +47 -0
  88. package/lib/renderer/WGPUBindlessTextures.js +180 -0
  89. package/lib/renderer/WGPUBindlessTextures.js.map +1 -0
  90. package/lib/renderer/WGPUBloomPass.js +17 -97
  91. package/lib/renderer/WGPUBloomPass.js.map +1 -1
  92. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  93. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  94. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  95. package/lib/renderer/WGPUComputePass.d.ts +1 -1
  96. package/lib/renderer/WGPUComputePass.js.map +1 -1
  97. package/lib/renderer/WGPUEnvMapDistribution.d.ts +12 -0
  98. package/lib/renderer/WGPUEnvMapDistribution.js +150 -0
  99. package/lib/renderer/WGPUEnvMapDistribution.js.map +1 -0
  100. package/lib/renderer/WGPUFullQuadPass.js +10 -9
  101. package/lib/renderer/WGPUFullQuadPass.js.map +1 -1
  102. package/lib/renderer/WGPUJNLMDenoiser.d.ts +1 -20
  103. package/lib/renderer/WGPUJNLMDenoiser.js +4 -267
  104. package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -1
  105. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  106. package/lib/renderer/WGPUPhotonMap.js +191 -0
  107. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  108. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  109. package/lib/renderer/WGPURayTraceOutput.js +132 -29
  110. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  111. package/lib/renderer/WGPURayTracePass.d.ts +83 -56
  112. package/lib/renderer/WGPURayTracePass.js +884 -837
  113. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  114. package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
  115. package/lib/renderer/WGPURenderingPipeline.js +297 -82
  116. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  117. package/lib/renderer/WGPUShaderCache.d.ts +2 -2
  118. package/lib/renderer/WGPUShaderCache.js +10 -5
  119. package/lib/renderer/WGPUShaderCache.js.map +1 -1
  120. package/lib/renderer/WGPUShaderCapabilities.d.ts +10 -0
  121. package/lib/renderer/WGPUShaderCapabilities.js +54 -0
  122. package/lib/renderer/WGPUShaderCapabilities.js.map +1 -0
  123. package/lib/renderer/WGPUSkyBaker.d.ts +13 -0
  124. package/lib/renderer/WGPUSkyBaker.js +85 -0
  125. package/lib/renderer/WGPUSkyBaker.js.map +1 -0
  126. package/lib/renderer/WebGLAov.d.ts +41 -0
  127. package/lib/renderer/WebGLAov.js +106 -0
  128. package/lib/renderer/WebGLAov.js.map +1 -0
  129. package/lib/renderer/WebGLFullQuadPass.d.ts +7 -4
  130. package/lib/renderer/WebGLFullQuadPass.js +22 -2
  131. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  132. package/lib/renderer/WebGLJNLMDenoiser.d.ts +1 -1
  133. package/lib/renderer/WebGLJNLMDenoiser.js +83 -74
  134. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  135. package/lib/renderer/WebGLRayTraceOutputPass.js +7 -4
  136. package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -1
  137. package/lib/renderer/WebGLRayTracePass.d.ts +18 -3
  138. package/lib/renderer/WebGLRayTracePass.js +121 -9
  139. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  140. package/lib/renderer/WebGLRenderingPipeline.js +126 -22
  141. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  142. package/lib/renderer/WebGLSkyBaker.d.ts +39 -0
  143. package/lib/renderer/WebGLSkyBaker.js +422 -0
  144. package/lib/renderer/WebGLSkyBaker.js.map +1 -0
  145. package/lib/renderer/WebGLSkySource.d.ts +9 -0
  146. package/lib/renderer/WebGLSkySource.js +28 -0
  147. package/lib/renderer/WebGLSkySource.js.map +1 -0
  148. package/lib/renderer/accumulationTarget.d.ts +6 -0
  149. package/lib/renderer/accumulationTarget.js.map +1 -1
  150. package/lib/renderer/aov.d.ts +42 -0
  151. package/lib/renderer/aov.js +50 -0
  152. package/lib/renderer/aov.js.map +1 -0
  153. package/lib/renderer/aovDisplay.d.ts +14 -0
  154. package/lib/renderer/aovDisplay.js +32 -0
  155. package/lib/renderer/aovDisplay.js.map +1 -0
  156. package/lib/renderer/aovScene.d.ts +21 -0
  157. package/lib/renderer/aovScene.js +139 -0
  158. package/lib/renderer/aovScene.js.map +1 -0
  159. package/lib/renderer/binnedSahBvh.js +2 -1
  160. package/lib/renderer/binnedSahBvh.js.map +1 -1
  161. package/lib/renderer/bvhAccel.d.ts +20 -10
  162. package/lib/renderer/bvhAccel.js +168 -58
  163. package/lib/renderer/bvhAccel.js.map +1 -1
  164. package/lib/renderer/bvhWorkerBuild.d.ts +1 -0
  165. package/lib/renderer/cameraSnapshot.js +2 -1
  166. package/lib/renderer/cameraSnapshot.js.map +1 -1
  167. package/lib/renderer/cameraUniform.d.ts +2 -0
  168. package/lib/renderer/cameraUniform.js +12 -0
  169. package/lib/renderer/cameraUniform.js.map +1 -0
  170. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  171. package/lib/renderer/causticDiagnostics.js +5 -0
  172. package/lib/renderer/causticDiagnostics.js.map +1 -0
  173. package/lib/renderer/causticEmission.d.ts +10 -0
  174. package/lib/renderer/causticEmission.js +40 -0
  175. package/lib/renderer/causticEmission.js.map +1 -0
  176. package/lib/renderer/causticUniform.d.ts +12 -0
  177. package/lib/renderer/causticUniform.js +22 -0
  178. package/lib/renderer/causticUniform.js.map +1 -0
  179. package/lib/renderer/caustics.d.ts +16 -0
  180. package/lib/renderer/caustics.js +93 -0
  181. package/lib/renderer/caustics.js.map +1 -0
  182. package/lib/renderer/committedScene.js +4 -0
  183. package/lib/renderer/committedScene.js.map +1 -1
  184. package/lib/renderer/denoiser.d.ts +3 -11
  185. package/lib/renderer/denoiser.js.map +1 -1
  186. package/lib/renderer/depthQuery.js +4 -1
  187. package/lib/renderer/depthQuery.js.map +1 -1
  188. package/lib/renderer/displacementPreparation.d.ts +11 -0
  189. package/lib/renderer/displacementPreparation.js +351 -0
  190. package/lib/renderer/displacementPreparation.js.map +1 -0
  191. package/lib/renderer/displacementRange.d.ts +1 -0
  192. package/lib/renderer/displacementRange.js +9 -0
  193. package/lib/renderer/displacementRange.js.map +1 -0
  194. package/lib/renderer/displayParityDiagnostics.d.ts +11 -0
  195. package/lib/renderer/displayParityDiagnostics.js +2 -0
  196. package/lib/renderer/displayParityDiagnostics.js.map +1 -0
  197. package/lib/renderer/envMapCreation.d.ts +9 -8
  198. package/lib/renderer/envMapCreation.js +36 -12
  199. package/lib/renderer/envMapCreation.js.map +1 -1
  200. package/lib/renderer/envMapDistribution.d.ts +12 -2
  201. package/lib/renderer/envMapDistribution.js +43 -34
  202. package/lib/renderer/envMapDistribution.js.map +1 -1
  203. package/lib/renderer/geometryBvhBounds.d.ts +4 -0
  204. package/lib/renderer/geometryBvhBounds.js +82 -0
  205. package/lib/renderer/geometryBvhBounds.js.map +1 -0
  206. package/lib/renderer/geometryUpdateState.d.ts +32 -0
  207. package/lib/renderer/geometryUpdateState.js +2 -0
  208. package/lib/renderer/geometryUpdateState.js.map +1 -0
  209. package/lib/renderer/geometryUpdates.d.ts +17 -9
  210. package/lib/renderer/geometryUpdates.js +92 -33
  211. package/lib/renderer/geometryUpdates.js.map +1 -1
  212. package/lib/renderer/glsl/aovDisplay.frag.d.ts +3 -0
  213. package/lib/renderer/glsl/aovDisplay.frag.js +54 -0
  214. package/lib/renderer/glsl/aovDisplay.frag.js.map +1 -0
  215. package/lib/renderer/glsl/aovReflectance.glsl.d.ts +2 -0
  216. package/lib/renderer/glsl/aovReflectance.glsl.js +87 -0
  217. package/lib/renderer/glsl/aovReflectance.glsl.js.map +1 -0
  218. package/lib/renderer/glsl/aovReflectanceSamples.glsl.d.ts +2 -0
  219. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +135 -0
  220. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js.map +1 -0
  221. package/lib/renderer/glsl/aovTrace.frag.d.ts +2 -0
  222. package/lib/renderer/glsl/aovTrace.frag.js +121 -0
  223. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -0
  224. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
  225. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  226. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  227. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  228. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -67
  229. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
  230. package/lib/renderer/glsl/chunks/intersect.glsl.js +432 -434
  231. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  232. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  233. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +160 -157
  234. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  235. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +802 -802
  236. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  237. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  238. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  239. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +72 -67
  240. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  241. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
  242. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  243. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  244. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +143 -120
  245. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  246. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +21 -18
  247. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
  248. package/lib/renderer/glsl/chunks/sampling.glsl.js +91 -94
  249. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  250. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  251. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  252. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +12 -12
  253. package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -1
  254. package/lib/renderer/glsl/depthQuery.frag.js +7 -7
  255. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +17 -9
  256. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -1
  257. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  258. package/lib/renderer/glsl/rayTrace.frag.js +271 -248
  259. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  260. package/lib/renderer/glsl/shadowCatcher.frag.js +37 -32
  261. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  262. package/lib/renderer/glsl/webglPipeline.frag.js +65 -60
  263. package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -1
  264. package/lib/renderer/lightConstants.d.ts +10 -0
  265. package/lib/renderer/lightConstants.js +11 -0
  266. package/lib/renderer/lightConstants.js.map +1 -0
  267. package/lib/renderer/lightCore.d.ts +12 -0
  268. package/lib/renderer/lightCore.js +13 -0
  269. package/lib/renderer/lightCore.js.map +1 -0
  270. package/lib/renderer/lightSampling.d.ts +22 -18
  271. package/lib/renderer/lightSampling.js +135 -62
  272. package/lib/renderer/lightSampling.js.map +1 -1
  273. package/lib/renderer/lightsData.d.ts +21 -0
  274. package/lib/renderer/lightsData.js +192 -0
  275. package/lib/renderer/lightsData.js.map +1 -0
  276. package/lib/renderer/lightsUtil.d.ts +3 -26
  277. package/lib/renderer/lightsUtil.js +3 -153
  278. package/lib/renderer/lightsUtil.js.map +1 -1
  279. package/lib/renderer/materialBufferData.d.ts +70 -0
  280. package/lib/renderer/materialBufferData.js +2 -0
  281. package/lib/renderer/materialBufferData.js.map +1 -0
  282. package/lib/renderer/materialConstants.d.ts +11 -0
  283. package/lib/renderer/materialConstants.js +11 -0
  284. package/lib/renderer/materialConstants.js.map +1 -1
  285. package/lib/renderer/materialCore.d.ts +8 -0
  286. package/lib/renderer/materialCore.js +9 -0
  287. package/lib/renderer/materialCore.js.map +1 -0
  288. package/lib/renderer/materialEmission.d.ts +2 -2
  289. package/lib/renderer/materialEmission.js +3 -3
  290. package/lib/renderer/materialEmission.js.map +1 -1
  291. package/lib/renderer/materialLayout.d.ts +2 -101
  292. package/lib/renderer/materialLayout.js +110 -172
  293. package/lib/renderer/materialLayout.js.map +1 -1
  294. package/lib/renderer/materialLayoutSchema.d.ts +26 -0
  295. package/lib/renderer/materialLayoutSchema.js +172 -0
  296. package/lib/renderer/materialLayoutSchema.js.map +1 -0
  297. package/lib/renderer/materialParams.d.ts +69 -0
  298. package/lib/renderer/materialParams.js +272 -0
  299. package/lib/renderer/materialParams.js.map +1 -0
  300. package/lib/renderer/materialTextureSlots.d.ts +14 -324
  301. package/lib/renderer/materialTextureSlots.js +21 -8
  302. package/lib/renderer/materialTextureSlots.js.map +1 -1
  303. package/lib/renderer/materialTextures.d.ts +6 -0
  304. package/lib/renderer/{texturesFromMaterials.js → materialTextures.js} +1 -2
  305. package/lib/renderer/materialTextures.js.map +1 -0
  306. package/lib/renderer/mergeMeshesToGeometry.js +6 -147
  307. package/lib/renderer/mergeMeshesToGeometry.js.map +1 -1
  308. package/lib/renderer/meshInstances.d.ts +4 -21
  309. package/lib/renderer/meshInstances.js +10 -56
  310. package/lib/renderer/meshInstances.js.map +1 -1
  311. package/lib/renderer/oidnNetwork.d.ts +2 -2
  312. package/lib/renderer/oidnNetwork.js +1 -1
  313. package/lib/renderer/oidnNetwork.js.map +1 -1
  314. package/lib/renderer/openPbrEnergyLut.js +850 -846
  315. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  316. package/lib/renderer/ownedDenoiser.d.ts +9 -0
  317. package/lib/renderer/ownedDenoiser.js +2 -0
  318. package/lib/renderer/ownedDenoiser.js.map +1 -0
  319. package/lib/renderer/packedMeshInstances.d.ts +23 -0
  320. package/lib/renderer/packedMeshInstances.js +80 -0
  321. package/lib/renderer/packedMeshInstances.js.map +1 -0
  322. package/lib/renderer/prepareMeshBVH.d.ts +12 -47
  323. package/lib/renderer/prepareMeshBVH.js +21 -642
  324. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  325. package/lib/renderer/proceduralEnvironmentPower.d.ts +3 -0
  326. package/lib/renderer/proceduralEnvironmentPower.js +8 -0
  327. package/lib/renderer/proceduralEnvironmentPower.js.map +1 -0
  328. package/lib/renderer/progressiveScheduler.d.ts +1 -0
  329. package/lib/renderer/progressiveScheduler.js +7 -3
  330. package/lib/renderer/progressiveScheduler.js.map +1 -1
  331. package/lib/renderer/renderPipeline.d.ts +4 -1
  332. package/lib/renderer/renderPipeline.js.map +1 -1
  333. package/lib/renderer/renderingLimits.d.ts +9 -0
  334. package/lib/renderer/renderingLimits.js +18 -0
  335. package/lib/renderer/renderingLimits.js.map +1 -0
  336. package/lib/renderer/researchTransport.d.ts +31 -0
  337. package/lib/renderer/researchTransport.js +5 -0
  338. package/lib/renderer/researchTransport.js.map +1 -0
  339. package/lib/renderer/sceneAssembly.d.ts +73 -0
  340. package/lib/renderer/sceneAssembly.js +109 -0
  341. package/lib/renderer/sceneAssembly.js.map +1 -0
  342. package/lib/renderer/sceneChangeCore.d.ts +39 -0
  343. package/lib/renderer/sceneChangeCore.js +307 -0
  344. package/lib/renderer/sceneChangeCore.js.map +1 -0
  345. package/lib/renderer/sceneChangeDetector.d.ts +3 -6
  346. package/lib/renderer/sceneChangeDetector.js +24 -150
  347. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  348. package/lib/renderer/sceneLayoutSchema.d.ts +119 -0
  349. package/lib/renderer/sceneLayoutSchema.js +111 -0
  350. package/lib/renderer/sceneLayoutSchema.js.map +1 -0
  351. package/lib/renderer/sceneLightChanges.d.ts +3 -3
  352. package/lib/renderer/sceneLightChanges.js.map +1 -1
  353. package/lib/renderer/scenePreparation.d.ts +55 -0
  354. package/lib/renderer/scenePreparation.js +360 -0
  355. package/lib/renderer/scenePreparation.js.map +1 -0
  356. package/lib/renderer/scratchSampling.js +18 -18
  357. package/lib/renderer/scratchSampling.js.map +1 -1
  358. package/lib/renderer/shader.d.ts +2 -0
  359. package/lib/renderer/shader.js +2 -0
  360. package/lib/renderer/shader.js.map +1 -1
  361. package/lib/renderer/shaderCapabilities.d.ts +23 -0
  362. package/lib/renderer/shaderCapabilities.js +55 -0
  363. package/lib/renderer/shaderCapabilities.js.map +1 -0
  364. package/lib/renderer/shaderCapacity.d.ts +2 -0
  365. package/lib/renderer/shaderCapacity.js +5 -0
  366. package/lib/renderer/shaderCapacity.js.map +1 -0
  367. package/lib/renderer/skyModel.d.ts +9 -0
  368. package/lib/renderer/skyModel.js +10 -0
  369. package/lib/renderer/skyModel.js.map +1 -0
  370. package/lib/renderer/spectrum.d.ts +21 -0
  371. package/lib/renderer/spectrum.js +154 -0
  372. package/lib/renderer/spectrum.js.map +1 -0
  373. package/lib/renderer/textureAtlas.d.ts +60 -0
  374. package/lib/renderer/textureAtlas.js +145 -0
  375. package/lib/renderer/textureAtlas.js.map +1 -0
  376. package/lib/renderer/textureAtlasPixels.d.ts +7 -0
  377. package/lib/renderer/textureAtlasPixels.js +68 -0
  378. package/lib/renderer/textureAtlasPixels.js.map +1 -0
  379. package/lib/renderer/util.d.ts +1 -1
  380. package/lib/renderer/util.js.map +1 -1
  381. package/lib/renderer/webgl.d.ts +9 -2
  382. package/lib/renderer/webgl.js +54 -9
  383. package/lib/renderer/webgl.js.map +1 -1
  384. package/lib/renderer/webglLightSampling.d.ts +39 -0
  385. package/lib/renderer/webglLightSampling.js +15 -0
  386. package/lib/renderer/webglLightSampling.js.map +1 -0
  387. package/lib/renderer/wgpuBindless.d.ts +26 -0
  388. package/lib/renderer/wgpuBindless.js +95 -0
  389. package/lib/renderer/wgpuBindless.js.map +1 -0
  390. package/lib/renderer/wgpuBindlessSource.d.ts +2 -0
  391. package/lib/renderer/wgpuBindlessSource.js +51 -0
  392. package/lib/renderer/wgpuBindlessSource.js.map +1 -0
  393. package/lib/renderer/wgpuMaterialConstants.d.ts +4 -0
  394. package/lib/renderer/wgpuMaterialConstants.js +52 -0
  395. package/lib/renderer/wgpuMaterialConstants.js.map +1 -0
  396. package/lib/renderer/wgpuSceneUniform.d.ts +42 -0
  397. package/lib/renderer/wgpuSceneUniform.js +125 -0
  398. package/lib/renderer/wgpuSceneUniform.js.map +1 -0
  399. package/lib/renderer/wgpuShaderSource.d.ts +22 -0
  400. package/lib/renderer/wgpuShaderSource.js +33 -0
  401. package/lib/renderer/wgpuShaderSource.js.map +1 -0
  402. package/lib/renderer/wgsl/aovDisplay.wgsl.d.ts +1 -0
  403. package/lib/renderer/wgsl/aovDisplay.wgsl.js +70 -0
  404. package/lib/renderer/wgsl/aovDisplay.wgsl.js.map +1 -0
  405. package/lib/renderer/wgsl/aovReflectance.wgsl.d.ts +2 -0
  406. package/lib/renderer/wgsl/aovReflectance.wgsl.js +98 -0
  407. package/lib/renderer/wgsl/aovReflectance.wgsl.js.map +1 -0
  408. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.d.ts +2 -0
  409. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +135 -0
  410. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js.map +1 -0
  411. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +5 -0
  412. package/lib/renderer/wgsl/aovResolve.wgsl.js +38 -0
  413. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -0
  414. package/lib/renderer/wgsl/aovSnapshot.wgsl.d.ts +4 -0
  415. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +21 -0
  416. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -0
  417. package/lib/renderer/wgsl/aovTrace.wgsl.d.ts +2 -0
  418. package/lib/renderer/wgsl/aovTrace.wgsl.js +115 -0
  419. package/lib/renderer/wgsl/aovTrace.wgsl.js.map +1 -0
  420. package/lib/renderer/wgsl/bloom.wgsl.d.ts +13 -0
  421. package/lib/renderer/wgsl/bloom.wgsl.js +92 -0
  422. package/lib/renderer/wgsl/bloom.wgsl.js.map +1 -0
  423. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  424. package/lib/renderer/wgsl/causticLight.compute.js +537 -0
  425. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  426. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  427. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  428. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  429. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  430. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  431. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  432. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  433. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  434. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  435. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  436. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  437. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  438. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  439. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
  440. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +41 -35
  441. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
  442. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +13 -1
  443. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +747 -704
  444. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  445. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +16 -16
  446. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  447. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +4 -1
  448. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +83 -79
  449. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  450. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +855 -857
  451. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -1
  452. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +137 -137
  453. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  454. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +3 -1
  455. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +52 -32
  456. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  457. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  458. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +152 -144
  459. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  460. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  461. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +269 -245
  462. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  463. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  464. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +27 -14
  465. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  466. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  467. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -95
  468. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  469. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +1 -1
  470. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +1 -0
  471. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
  472. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  473. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +12 -12
  474. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -1
  475. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +8 -3
  476. package/lib/renderer/wgsl/compose.frag.wgsl.js +143 -118
  477. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  478. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  479. package/lib/renderer/wgsl/depthQuery.wgsl.js +7 -7
  480. package/lib/renderer/wgsl/jnlm.compute.d.ts +25 -0
  481. package/lib/renderer/wgsl/jnlm.compute.js +315 -0
  482. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -0
  483. package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
  484. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.d.ts +1 -0
  485. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +17 -0
  486. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js.map +1 -0
  487. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  488. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  489. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  490. package/lib/renderer/wgsl/proceduralSky.compute.d.ts +1 -0
  491. package/lib/renderer/wgsl/proceduralSky.compute.js +198 -0
  492. package/lib/renderer/wgsl/proceduralSky.compute.js.map +1 -0
  493. package/lib/renderer/wgsl/rayTrace.compute.d.ts +25 -1
  494. package/lib/renderer/wgsl/rayTrace.compute.js +645 -500
  495. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  496. package/lib/scene/Camera.js +7 -3
  497. package/lib/scene/Camera.js.map +1 -1
  498. package/lib/scene/EnvironmentLight.d.ts +5 -9
  499. package/lib/scene/EnvironmentLight.js +4 -14
  500. package/lib/scene/EnvironmentLight.js.map +1 -1
  501. package/lib/scene/EnvironmentLightState.d.ts +18 -0
  502. package/lib/scene/EnvironmentLightState.js +19 -0
  503. package/lib/scene/EnvironmentLightState.js.map +1 -0
  504. package/lib/scene/Geometry.d.ts +12 -6
  505. package/lib/scene/Geometry.js +37 -13
  506. package/lib/scene/Geometry.js.map +1 -1
  507. package/lib/scene/InstanceState.d.ts +39 -0
  508. package/lib/scene/InstanceState.js +77 -0
  509. package/lib/scene/InstanceState.js.map +1 -0
  510. package/lib/scene/InstancedMesh.d.ts +1 -1
  511. package/lib/scene/InstancedMesh.js +3 -0
  512. package/lib/scene/InstancedMesh.js.map +1 -1
  513. package/lib/scene/MaterialState.d.ts +209 -0
  514. package/lib/scene/MaterialState.js +231 -0
  515. package/lib/scene/MaterialState.js.map +1 -0
  516. package/lib/scene/Mesh.d.ts +4 -6
  517. package/lib/scene/Mesh.js +3 -11
  518. package/lib/scene/Mesh.js.map +1 -1
  519. package/lib/scene/MeshState.d.ts +20 -0
  520. package/lib/scene/MeshState.js +35 -0
  521. package/lib/scene/MeshState.js.map +1 -0
  522. package/lib/scene/OpenPBRMaterial.d.ts +6 -168
  523. package/lib/scene/OpenPBRMaterial.js +5 -223
  524. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  525. package/lib/scene/PixelTexture.d.ts +6 -0
  526. package/lib/scene/PixelTexture.js +10 -0
  527. package/lib/scene/PixelTexture.js.map +1 -0
  528. package/lib/scene/ProceduralSky.d.ts +24 -0
  529. package/lib/scene/ProceduralSky.js +40 -0
  530. package/lib/scene/ProceduralSky.js.map +1 -0
  531. package/lib/scene/RectLight.d.ts +2 -13
  532. package/lib/scene/RectLight.js +3 -21
  533. package/lib/scene/RectLight.js.map +1 -1
  534. package/lib/scene/RectLightState.d.ts +31 -0
  535. package/lib/scene/RectLightState.js +26 -0
  536. package/lib/scene/RectLightState.js.map +1 -0
  537. package/lib/scene/Scene.d.ts +15 -4
  538. package/lib/scene/Scene.js.map +1 -1
  539. package/lib/scene/SceneNode.js +7 -6
  540. package/lib/scene/SceneNode.js.map +1 -1
  541. package/lib/scene/Texture.d.ts +10 -41
  542. package/lib/scene/Texture.js +4 -33
  543. package/lib/scene/Texture.js.map +1 -1
  544. package/lib/scene/TextureState.d.ts +35 -0
  545. package/lib/scene/TextureState.js +35 -0
  546. package/lib/scene/TextureState.js.map +1 -0
  547. package/lib/scene/attributeData.d.ts +4 -0
  548. package/lib/scene/attributeData.js +10 -0
  549. package/lib/scene/attributeData.js.map +1 -0
  550. package/lib/scene/lightState.d.ts +8 -0
  551. package/lib/scene/lightState.js +2 -0
  552. package/lib/scene/lightState.js.map +1 -0
  553. package/lib/scene/openPbrSchema.d.ts +7 -12
  554. package/lib/scene/openPbrSchema.js +273 -28
  555. package/lib/scene/openPbrSchema.js.map +1 -1
  556. package/lib/scene/skyParameters.d.ts +20 -0
  557. package/lib/scene/skyParameters.js +28 -0
  558. package/lib/scene/skyParameters.js.map +1 -0
  559. package/lib/scene/textureData.d.ts +9 -0
  560. package/lib/scene/textureData.js +2 -0
  561. package/lib/scene/textureData.js.map +1 -0
  562. package/lib/scene/texturePixels.d.ts +6 -0
  563. package/lib/scene/texturePixels.js +10 -0
  564. package/lib/scene/texturePixels.js.map +1 -0
  565. package/lib/settings/display.d.ts +33 -0
  566. package/lib/settings/display.js +7 -0
  567. package/lib/settings/display.js.map +1 -1
  568. package/lib/settings/render.d.ts +36 -3
  569. package/lib/settings/render.js +4 -1
  570. package/lib/settings/render.js.map +1 -1
  571. package/lib/tinybvh/tinybvh.wasm +0 -0
  572. package/lib/util/commonGeometry.js +7 -7
  573. package/lib/util/commonGeometry.js.map +1 -1
  574. package/lib/util/fromTHREE.d.ts +4 -1
  575. package/lib/util/fromTHREE.js +20 -7
  576. package/lib/util/fromTHREE.js.map +1 -1
  577. package/lib/util/geometry.js +42 -29
  578. package/lib/util/geometry.js.map +1 -1
  579. package/lib/util/loadRGBE.js +3 -4
  580. package/lib/util/loadRGBE.js.map +1 -1
  581. package/lib/util/studioLighting.d.ts +18 -0
  582. package/lib/util/studioLighting.js +36 -0
  583. package/lib/util/studioLighting.js.map +1 -0
  584. package/lib/version.d.ts +1 -1
  585. package/lib/version.js +1 -1
  586. package/lib/version.js.map +1 -1
  587. package/llms.txt +5 -0
  588. package/package.json +33 -7
  589. package/lib/renderer/texturesFromMaterials.d.ts +0 -6
  590. package/lib/renderer/texturesFromMaterials.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WebGLFullQuadPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLFullQuadPass.ts"],"names":[],"mappings":"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","sourcesContent":["import {scratchGLSLFunctions} from './scratchSampling.js';\nimport {setTextureRegion, textureRegion} from './textureRegion.js';\nimport { FragmentShader, ShaderDefineValue } from './shader.js';\nimport {\n FrameBuffer,\n WebGLDevice,\n Texture2D,\n TextureOptions,\n WebGLProgramBindings\n} from './webgl.js';\n\nexport interface WebGLFullQuadPassOutput extends TextureOptions {}\n\nexport interface WebGLPassOptions {\n clear?: boolean;\n blend?: boolean;\n viewport?: { x: number; y: number; width: number; height: number };\n scissor?: { x: number; y: number; width: number; height: number };\n}\n\n/**\n * Explicit WebGL 2.0 render pass matching the lifecycle of WGPUFullQuadPass.\n * It owns its output textures and framebuffer; there is no render graph.\n */\nexport class WebGLFullQuadPass<I extends string, O extends string> {\n private readonly _renderer: WebGLDevice;\n private _bindings: WebGLProgramBindings;\n private readonly _sourceShader: FragmentShader;\n private readonly _outputs: O[];\n private readonly _frameBuffer = new FrameBuffer();\n private _outputTextures = {} as Record<O, Texture2D>;\n private readonly _targetOutputs = new Map<object, Record<O, Texture2D>>();\n useTarget(target: object) {\n let outputs = this._targetOutputs.get(target);\n if (!outputs) this._targetOutputs.set(target, outputs = {} as Record<O, Texture2D>);\n this._outputTextures = outputs;\n }\n\n private _outputParams = {} as Record<O, WebGLFullQuadPassOutput>;\n private _reserveCapacity = false;\n private _capacityWidth = 1;\n private _capacityHeight = 1;\n private _width = 1;\n private _height = 1;\n private _renderToScreen = false;\n\n constructor(\n _label: string,\n renderer: WebGLDevice,\n options: {\n shader: FragmentShader;\n outputs?: O[];\n outputParams?: Partial<Record<O, WebGLFullQuadPassOutput>>;\n }\n ) {\n this._renderer = renderer;\n this._sourceShader = options.shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(options.shader));\n this._outputs = options.outputs || (options.shader.outputs as O[]);\n this.setOutputParams(\n Object.fromEntries(\n this._outputs.map((name) => [\n name,\n options.outputParams?.[name] || {}\n ])\n ) as Record<O, WebGLFullQuadPassOutput>\n );\n }\n\n reserveCapacity() {\n if (this._reserveCapacity) return;\n this._reserveCapacity = true;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n this._sourceShader, true, this._bindings.uniforms, this._bindings.defines\n ));\n }\n\n private _samplingShader(\n shader: FragmentShader,\n scratch = false,\n uniforms = shader.uniforms,\n defines = shader.defines\n ) {\n const textures = Object.keys(shader.uniforms).filter(name => shader.uniforms[name].type === 'sampler2D');\n uniforms = {...uniforms};\n if (scratch) for (const name of textures) uniforms[`${name}RegionSize`] = {type: 'ivec2', value: [1, 1]};\n const sampled = new FragmentShader({name: shader.name, outputs: shader.outputs, defines, uniforms,\n includes: [{defines: {}, uniforms: {}, main: '', functions: [() => scratchGLSLFunctions(textures, scratch), ...shader.functions]}],\n main: shader.main});\n sampled.parallelCompile = shader.parallelCompile;\n return sampled;\n }\n\n setSize(width: number, height: number) {\n if (this._width === width && this._height === height) return;\n this._width = Math.max(1, width);\n this._height = Math.max(1, height);\n this._capacityWidth = Math.max(this._capacityWidth, this._width);\n this._capacityHeight = Math.max(this._capacityHeight, this._height);\n this.setUniform('viewportSize', [this._width, this._height]);\n }\n\n setOutputs(outputs: readonly O[]) {\n for (const name of this._outputs) if (!outputs.includes(name)) {\n this._outputTextures[name]?.dispose(this._renderer.gl); delete this._outputTextures[name];\n }\n this._outputs.splice(0, this._outputs.length, ...outputs);\n }\n setOutputParams(params: Record<O, WebGLFullQuadPassOutput>) {\n this._outputParams = params;\n }\n\n setRenderToScreen(renderToScreen = true) {\n this._renderToScreen = renderToScreen;\n }\n\n setUniform(label: string, data: unknown) {\n return this._bindings.set(label, data);\n }\n\n setUniforms(values: Record<string, unknown>) {\n this._bindings.setUniforms(values);\n }\n\n getUniform(label: string) {\n return this._bindings.get(label);\n }\n\n setDefines(\n defines: Record<\n string,\n ShaderDefineValue | undefined\n >\n ) {\n let changed = false;\n for (const [name, value] of Object.entries(defines)) {\n const oldValue = this._bindings.defines[name];\n if (!value) {\n if (name in this._bindings.defines) {\n this._bindings.deleteDefine(name);\n changed = true;\n }\n } else if (oldValue !== value) {\n this._bindings.setDefine(name, value);\n changed = true;\n }\n }\n return changed;\n }\n\n private readonly _retainedOutputs = new Set<Texture2D>();\n retainOutput(texture: Texture2D) { if (Object.values(this._outputTextures).includes(texture)) this._retainedOutputs.add(texture); }\n releaseOutput(texture: Texture2D) {\n if (!this._retainedOutputs.delete(texture)) return;\n if (!Object.values(this._outputTextures).includes(texture)) texture.dispose(this._renderer.gl);\n }\n\n getOutput(name: O) {\n return this._outputTextures[name];\n }\n\n private _prepareOutputs(explicitOutputs?: Partial<Record<O, Texture2D>>) {\n const gl = this._renderer.gl;\n for (const name of this._outputs) {\n const explicit = explicitOutputs?.[name];\n const current = this._outputTextures[name];\n const retainedResize = current && this._retainedOutputs.has(current) &&\n (current.width !== this._width || current.height !== this._height);\n const texture =\n explicit ||\n (retainedResize ? new Texture2D(this._outputParams[name]) : undefined) ||\n this._outputTextures[name] ||\n new Texture2D(this._outputParams[name]);\n texture.ensureStorage(\n gl,\n this._reserveCapacity ? this._capacityWidth : this._width,\n this._reserveCapacity ? this._capacityHeight : this._height,\n this._outputParams[name]\n );\n this._outputTextures[name] = texture;\n setTextureRegion(texture, this._width, this._height);\n }\n }\n\n createPass(\n inputs: Record<I, Texture2D>,\n explicitOutputs?: Partial<Record<O, Texture2D>>,\n options: WebGLPassOptions = {}\n ) {\n const renderer = this._renderer;\n const gl = renderer.gl;\n\n if (this._renderToScreen) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n } else {\n this._prepareOutputs(explicitOutputs);\n this._frameBuffer.bind(\n renderer,\n this._outputs.map((name) => this._outputTextures[name])\n );\n }\n\n const viewport = options.viewport || {\n x: 0,\n y: 0,\n width: this._width,\n height: this._height\n };\n renderer.setViewport(\n viewport.x,\n viewport.y,\n viewport.width,\n viewport.height\n );\n\n // Clear the full accumulation target before enabling the tile scissor.\n // Otherwise every tile outside the first one retains stale camera data.\n if (options.clear) {\n gl.disable(gl.SCISSOR_TEST);\n gl.clearColor(0, 0, 0, 0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n if (options.scissor) {\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(\n options.scissor.x,\n options.scissor.y,\n options.scissor.width,\n options.scissor.height\n );\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n\n if (this._reserveCapacity) for (const [name, texture] of Object.entries(inputs) as [string, Texture2D][]) {\n const region = textureRegion(texture);\n this.setUniform(`${name}RegionSize`, [region.width, region.height]);\n }\n this._bindings.setUniforms(inputs);\n this._bindings.bind(renderer);\n gl.disable(gl.DEPTH_TEST);\n if (options.blend) {\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE);\n } else {\n gl.disable(gl.BLEND);\n }\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n gl.disable(gl.SCISSOR_TEST);\n }\n\n releaseTarget(target: object) {\n const outputs = this._targetOutputs.get(target);\n if (!outputs) return;\n this._targetOutputs.delete(target);\n for (const texture of (Object.values(outputs) as Texture2D[])) texture.dispose(this._renderer.gl);\n if (outputs === this._outputTextures) this._outputTextures = {} as Record<O, Texture2D>;\n }\n\n getMemoryBytes(target?: object): number {\n const outputs = target ? this._targetOutputs.get(target) ?? {} : this._outputTextures;\n return Array.from(new Set([...Object.values(outputs) as Texture2D[], ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + texture.getMemoryBytes(), 0);\n }\n\n dispose() {\n const gl = this._renderer.gl;\n (Array.from(new Set([this._outputTextures, ...this._targetOutputs.values()])).flatMap(outputs => Object.values(outputs)) as Texture2D[]).forEach((texture) =>\n texture.dispose(gl)\n );\n this._retainedOutputs.forEach(texture => texture.dispose(gl));\n this._retainedOutputs.clear();\n this._frameBuffer.dispose(this._renderer);\n }\n}\n"]}
1
+ {"version":3,"file":"WebGLFullQuadPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLFullQuadPass.ts"],"names":[],"mappings":"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","sourcesContent":["import {scratchGLSLFunctions} from './scratchSampling.js';\nimport {setTextureRegion, textureRegion} from './textureRegion.js';\nimport { FragmentShader, type ShaderDefineValue } from './shader.js';\nimport {\n FrameBuffer,\n WebGLDevice,\n Texture2D,\n type TextureOptions,\n WebGLProgramBindings\n} from './webgl.js';\n\nexport interface WebGLFullQuadPassOutput extends TextureOptions {}\n\nexport interface WebGLPassOptions {\n clear?: boolean;\n blend?: boolean;\n viewport?: { x: number; y: number; width: number; height: number };\n scissor?: { x: number; y: number; width: number; height: number };\n}\n\n/**\n * Explicit WebGL 2.0 render pass matching the lifecycle of WGPUFullQuadPass.\n * It owns its output textures and framebuffer; there is no render graph.\n */\nexport class WebGLFullQuadPass<I extends string, O extends string> {\n private readonly _renderer: WebGLDevice;\n private _bindings: WebGLProgramBindings;\n private _sourceShader: FragmentShader;\n private readonly _outputs: O[];\n private readonly _frameBuffer = new FrameBuffer();\n private _outputTextures = {} as Record<O, Texture2D>;\n private readonly _targetOutputs = new Map<object, Record<O, Texture2D>>();\n useTarget(target: object) {\n let outputs = this._targetOutputs.get(target);\n if (!outputs) this._targetOutputs.set(target, outputs = {} as Record<O, Texture2D>);\n this._outputTextures = outputs;\n }\n\n private _outputParams = {} as Record<O, WebGLFullQuadPassOutput>;\n private _reserveCapacity = false;\n private _capacityWidth = 1;\n private _capacityHeight = 1;\n private _width = 1;\n private _height = 1;\n private _renderToScreen = false;\n\n constructor(\n _label: string,\n renderer: WebGLDevice,\n options: {\n shader: FragmentShader;\n outputs?: O[];\n outputParams?: Partial<Record<O, WebGLFullQuadPassOutput>>;\n }\n ) {\n this._renderer = renderer;\n this._sourceShader = options.shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(options.shader));\n this._outputs = options.outputs || (options.shader.outputs as O[]);\n this.setOutputParams(\n Object.fromEntries(\n this._outputs.map((name) => [\n name,\n options.outputParams?.[name] || {}\n ])\n ) as Record<O, WebGLFullQuadPassOutput>\n );\n }\n\n setShader(shader: FragmentShader) {\n this._sourceShader = shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n shader, this._reserveCapacity, {...shader.uniforms, ...this._bindings.uniforms}, this._bindings.defines\n ));\n }\n\n reserveCapacity() {\n if (this._reserveCapacity) return;\n this._reserveCapacity = true;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n this._sourceShader, true, this._bindings.uniforms, this._bindings.defines\n ));\n }\n\n private _samplingShader(\n shader: FragmentShader,\n scratch = false,\n uniforms = shader.uniforms,\n defines = shader.defines\n ) {\n const textures = Object.keys(shader.uniforms).filter(name => shader.uniforms[name].type === 'sampler2D');\n uniforms = {...uniforms};\n if (scratch) for (const name of textures) uniforms[`${name}RegionSize`] = {type: 'ivec2', value: [1, 1]};\n const sampled = new FragmentShader({name: shader.name, outputs: shader.outputs, outputTypes: shader.outputTypes, defines, uniforms,\n includes: [{defines: {}, uniforms: {}, main: '', functions: [() => scratchGLSLFunctions(textures, scratch), ...shader.functions]}],\n main: shader.main});\n sampled.parallelCompile = shader.parallelCompile;\n return sampled;\n }\n\n setSize(width: number, height: number) {\n if (this._width === width && this._height === height) return;\n this._width = Math.max(1, width);\n this._height = Math.max(1, height);\n this._capacityWidth = Math.max(this._capacityWidth, this._width);\n this._capacityHeight = Math.max(this._capacityHeight, this._height);\n this.setUniform('viewportSize', [this._width, this._height]);\n }\n\n setOutputs(outputs: readonly O[]) {\n for (const name of this._outputs) if (!outputs.includes(name)) {\n this._outputTextures[name]?.dispose(this._renderer.gl); delete this._outputTextures[name];\n }\n this._outputs.splice(0, this._outputs.length, ...outputs);\n }\n setOutputParams(params: Record<O, WebGLFullQuadPassOutput>) {\n this._outputParams = params;\n }\n\n setRenderToScreen(renderToScreen = true) {\n this._renderToScreen = renderToScreen;\n }\n\n setUniform(label: string, data: unknown) {\n return this._bindings.set(label, data);\n }\n\n setUniforms(values: Record<string, unknown>) {\n this._bindings.setUniforms(values);\n }\n\n getUniform(label: string) {\n return this._bindings.get(label);\n }\n\n setDefines(\n defines: Record<\n string,\n ShaderDefineValue | undefined\n >\n ) {\n let changed = false;\n for (const [name, value] of Object.entries(defines)) {\n const oldValue = this._bindings.defines[name];\n if (!value) {\n if (name in this._bindings.defines) {\n this._bindings.deleteDefine(name);\n changed = true;\n }\n } else if (oldValue !== value) {\n this._bindings.setDefine(name, value);\n changed = true;\n }\n }\n return changed;\n }\n\n private readonly _retainedOutputs = new Set<Texture2D>();\n retainOutput(texture: Texture2D) { if (Object.values(this._outputTextures).includes(texture)) this._retainedOutputs.add(texture); }\n releaseOutput(texture: Texture2D) {\n if (!this._retainedOutputs.delete(texture)) return;\n if (!Object.values(this._outputTextures).includes(texture)) texture.dispose(this._renderer.gl);\n }\n\n // Internal fixed-accumulation loader; transfer ownership to the selected target.\n loadDiagnosticOutputs(outputs: Partial<Record<O, Texture2D>>) {\n for (const name of Object.keys(outputs) as O[]) {\n this._outputTextures[name]?.dispose(this._renderer.gl);\n this._outputTextures[name] = outputs[name]!;\n }\n }\n\n getOutput(name: O) {\n return this._outputTextures[name];\n }\n\n private _prepareOutputs(explicitOutputs?: Partial<Record<O, Texture2D>>) {\n const gl = this._renderer.gl;\n for (const name of this._outputs) {\n const explicit = explicitOutputs?.[name];\n const current = this._outputTextures[name];\n const retainedResize = current && this._retainedOutputs.has(current) &&\n (current.width !== this._width || current.height !== this._height);\n const texture =\n explicit ||\n (retainedResize ? new Texture2D(this._outputParams[name]) : undefined) ||\n this._outputTextures[name] ||\n new Texture2D(this._outputParams[name]);\n texture.ensureStorage(\n gl,\n this._reserveCapacity ? this._capacityWidth : this._width,\n this._reserveCapacity ? this._capacityHeight : this._height,\n this._outputParams[name]\n );\n this._outputTextures[name] = texture;\n setTextureRegion(texture, this._width, this._height);\n }\n }\n\n isProgramReady(inputs?: Record<I, Texture2D>) {\n if (inputs) this._bindings.setUniforms(inputs);\n return this._renderer.isProgramCompiled(this._bindings.getProgram(this._renderer));\n }\n\n createPass(\n inputs: Record<I, Texture2D>,\n explicitOutputs?: Partial<Record<O, Texture2D>>,\n options: WebGLPassOptions = {}\n ) {\n const renderer = this._renderer;\n const gl = renderer.gl;\n\n if (this._renderToScreen) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n } else {\n this._prepareOutputs(explicitOutputs);\n this._frameBuffer.bind(\n renderer,\n this._outputs.map((name) => this._outputTextures[name])\n );\n }\n\n const viewport = options.viewport || {\n x: 0,\n y: 0,\n width: this._width,\n height: this._height\n };\n renderer.setViewport(\n viewport.x,\n viewport.y,\n viewport.width,\n viewport.height\n );\n\n // Clear the full accumulation target before enabling the tile scissor.\n // Otherwise every tile outside the first one retains stale camera data.\n if (options.clear) {\n gl.disable(gl.SCISSOR_TEST);\n gl.clearColor(0, 0, 0, 0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n if (options.scissor) {\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(\n options.scissor.x,\n options.scissor.y,\n options.scissor.width,\n options.scissor.height\n );\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n\n if (this._reserveCapacity) for (const [name, texture] of Object.entries(inputs) as [string, Texture2D][]) {\n const region = textureRegion(texture);\n this.setUniform(`${name}RegionSize`, [region.width, region.height]);\n }\n this._bindings.setUniforms(inputs);\n if (!this._bindings.bind(renderer)) {\n gl.disable(gl.SCISSOR_TEST);\n return false;\n }\n gl.disable(gl.DEPTH_TEST);\n if (options.blend) {\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE);\n } else {\n gl.disable(gl.BLEND);\n }\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n gl.disable(gl.SCISSOR_TEST);\n return true;\n }\n\n releaseTarget(target: object) {\n const outputs = this._targetOutputs.get(target);\n if (!outputs) return;\n this._targetOutputs.delete(target);\n for (const texture of (Object.values(outputs) as Texture2D[])) texture.dispose(this._renderer.gl);\n if (outputs === this._outputTextures) this._outputTextures = {} as Record<O, Texture2D>;\n }\n\n getMemoryBytes(target?: object): number {\n const outputs = target ? this._targetOutputs.get(target) ?? {} : this._outputTextures;\n return Array.from(new Set([...Object.values(outputs) as Texture2D[], ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + texture.getMemoryBytes(), 0);\n }\n\n dispose() {\n const gl = this._renderer.gl;\n (Array.from(new Set([this._outputTextures, ...this._targetOutputs.values()])).flatMap(outputs => Object.values(outputs)) as Texture2D[]).forEach((texture) =>\n texture.dispose(gl)\n );\n this._retainedOutputs.forEach(texture => texture.dispose(gl));\n this._retainedOutputs.clear();\n this._frameBuffer.dispose(this._renderer);\n }\n}\n"]}
@@ -23,7 +23,7 @@ export declare class WebGLJNLMDenoisePass {
23
23
  private _filterPasses;
24
24
  constructor(renderer: WebGLDevice);
25
25
  /** Runs the denoiser and returns the display-encoded result. */
26
- render(inputs: WebGLJNLMInputs): Texture2D;
26
+ render(inputs: WebGLJNLMInputs, trace?: string[]): Texture2D;
27
27
  reserveCapacity(): void;
28
28
  retainOutput(texture: Texture2D): void;
29
29
  releaseOutput(texture: Texture2D): void;
@@ -45,27 +45,27 @@ void main() {
45
45
  ivec2 p = ivec2(gl_FragCoord.xy);
46
46
  ivec2 size = rawGuideTexRegion();
47
47
  vec2 center = load_rawGuideTex(p, 0).xy;
48
- float lu = 0.0;
49
- float jc = 0.0;
50
- float mY = 0.0;
51
- float iX = 0.0;
48
+ float lM = 0.0;
49
+ float je = 0.0;
50
+ float nM = 0.0;
51
+ float iV = 0.0;
52
52
  for (int dy = -1; dy <= 1; dy++) {
53
53
  for (int dx = -1; dx <= 1; dx++) {
54
54
  vec2 value = load_rawGuideTex(clamp(p + ivec2(dx, dy), ivec2(0), size - 1), 0).xy;
55
- mY += value.x;
56
- iX += value.x * value.x;
55
+ nM += value.x;
56
+ iV += value.x * value.x;
57
57
  if (value.y >= 0.0) {
58
- lu += value.y;
59
- jc += 1.0;
58
+ lM += value.y;
59
+ je += 1.0;
60
60
  }
61
61
  }
62
62
  }
63
63
  float variance;
64
64
  if (center.y >= 0.0) {
65
- variance = lu / jc;
65
+ variance = lM / je;
66
66
  } else {
67
- float lt = mY / 9.0;
68
- variance = max(iX / 9.0 - lt * lt, 0.0) * 9.0 / 8.0;
67
+ float lL = nM / 9.0;
68
+ variance = max(iV / 9.0 - lL * lL, 0.0) * 9.0 / 8.0;
69
69
  }
70
70
  out_guide = vec4(center.x, variance, 0.0, 1.0);
71
71
  }`
@@ -105,68 +105,70 @@ const filterFragment = new FragmentShader({
105
105
 
106
106
  ivec2 imageSize;
107
107
 
108
- vec2 nH(ivec2 p) {
108
+ vec2 loadGuide(ivec2 p) {
109
109
  return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;
110
110
  }
111
111
 
112
112
 
113
- vec4 rL(ivec2 p) {
113
+ vec4 sI(ivec2 p) {
114
114
  vec4 c = load_colorTex(p, 0);
115
- if (decodeInput) c.rgb = pow(max(c.rgb, 0.0), vec3(2.2));
115
+ if (decodeInput) c.rgb = mix(pow((max(c.rgb, 0.0) + 0.055) / 1.055, vec3(2.4)),
116
+ c.rgb / 12.92, lessThanEqual(c.rgb, vec3(0.04045)));
116
117
  return vec4(c.rgb * c.a, c.a);
117
118
  }
118
119
 
119
- float lw(ivec2 q, vec4 bs, vec3 gT) {
120
+ float lP(ivec2 q, vec4 bo, vec3 gO) {
120
121
  vec4 albedo = load_albedoTex(q, 0);
121
122
 
122
123
 
123
- vec3 pf = max((albedo.rgb + bs.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));
124
- vec3 ld = (albedo.rgb - bs.rgb) / pf;
125
- float iU = albedo.a - bs.a;
126
- vec3 lp = load_normalTex(q, 0).rgb - gT;
124
+ vec3 pY = max((albedo.rgb + bo.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));
125
+ vec3 lu = (albedo.rgb - bo.rgb) / pY;
126
+ float iQ = albedo.a - bo.a;
127
+ vec3 lG = load_normalTex(q, 0).rgb - gO;
127
128
  return max(
128
- dot(ld, ld) * INV_ALBEDO_BANDWIDTH2
129
- + iU * iU * INV_COVERAGE_BANDWIDTH2,
130
- dot(lp, lp) * INV_NORMAL_BANDWIDTH2
129
+ dot(lu, lu) * INV_ALBEDO_BANDWIDTH2
130
+ + iQ * iQ * INV_COVERAGE_BANDWIDTH2,
131
+ dot(lG, lG) * INV_NORMAL_BANDWIDTH2
131
132
  );
132
133
  }
133
134
 
134
135
  void main() {
135
136
  imageSize = guideTexRegion();
136
137
  ivec2 p = ivec2(gl_FragCoord.xy);
137
- vec4 bs = load_albedoTex(p, 0);
138
- vec4 fD = load_normalTex(p, 0);
139
- vec3 gT = fD.rgb;
138
+ vec4 bo = load_albedoTex(p, 0);
139
+ vec4 fC = load_normalTex(p, 0);
140
+ vec3 gO = fC.rgb;
140
141
 
141
142
 
142
- if (fD.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {
143
- vec4 c = rL(p);
143
+ if (fC.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {
144
+ vec4 c = sI(p);
144
145
  vec3 rgb = c.rgb / max(c.a, 1e-6);
145
- if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.2));
146
+ if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,
147
+ rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));
146
148
  out_color = vec4(rgb, c.a);
147
- out_guide = vec4(nH(p), 0.0, 1.0);
149
+ out_guide = vec4(loadGuide(p), 0.0, 1.0);
148
150
  return;
149
151
  }
150
152
 
151
- vec2 lf[PATCH_SIZE];
153
+ vec2 lA[PATCH_SIZE];
152
154
  int k = 0;
153
155
  for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
154
156
  for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
155
- lf[k] = nH(p + ivec2(dx, dy) * dilation);
157
+ lA[k] = loadGuide(p + ivec2(dx, dy) * dilation);
156
158
  k++;
157
159
  }
158
160
  }
159
161
  float k2 = colorSensitivity * colorSensitivity;
160
162
 
161
163
  vec4 sum = vec4(0.0);
162
- vec3 gW = max(bs.rgb, vec3(${JNLM_ALBEDO_FLOOR}));
163
- vec3 mp = vec3(0.0);
164
- vec3 gy = vec3(0.0);
165
- vec3 hs = vec3(0.0);
166
- float ps = 0.0;
167
- float gA = 0.0;
168
- float nU = 0.0;
169
- float kM = 0.0;
164
+ vec3 gR = max(bo.rgb, vec3(${JNLM_ALBEDO_FLOOR}));
165
+ vec3 mQ = vec3(0.0);
166
+ vec3 gv = vec3(0.0);
167
+ vec3 hm = vec3(0.0);
168
+ float qf = 0.0;
169
+ float gx = 0.0;
170
+ float oE = 0.0;
171
+ float kX = 0.0;
170
172
  for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {
171
173
  for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {
172
174
  ivec2 q = p + ivec2(sx, sy) * dilation;
@@ -174,68 +176,69 @@ if (
174
176
  (sx == 0 && sy == 0) ||
175
177
  q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y
176
178
  ) continue;
177
- float features = lw(q, bs, gT);
179
+ float features = lP(q, bo, gO);
178
180
  if (features > 16.0) continue;
179
181
 
180
- float fY = 0.0;
182
+ float fW = 0.0;
181
183
  k = 0;
182
184
  for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
183
185
  for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
184
- vec2 a = lf[k];
185
- vec2 b = nH(q + ivec2(dx, dy) * dilation);
186
- float qU = a.x - b.x;
187
- fY += (qU * qU
186
+ vec2 a = lA[k];
187
+ vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);
188
+ float rV = a.x - b.x;
189
+ fW += (rV * rV
188
190
  - VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))
189
191
  / (1e-10 + k2 * (a.y + b.y));
190
192
  k++;
191
193
  }
192
194
  }
193
- fY /= float(PATCH_SIZE);
195
+ fW /= float(PATCH_SIZE);
194
196
 
195
- float weight = exp(-max(max(fY, 0.0), features));
196
- vec2 g = nH(q);
197
+ float weight = exp(-max(max(fW, 0.0), features));
198
+ vec2 g = loadGuide(q);
197
199
 
198
- vec3 a = (load_albedoTex(q, 0).rgb - bs.rgb) / gW;
199
- vec4 value = rL(q);
200
+ vec3 a = (load_albedoTex(q, 0).rgb - bo.rgb) / gR;
201
+ vec4 value = sI(q);
200
202
  sum += value * weight;
201
- mp += a * weight;
202
- gy += a * a * weight;
203
- hs += a * value.rgb * weight;
204
- ps += g.x * weight;
205
- gA += g.y * weight * weight;
206
- nU += weight;
207
- kM = max(kM, weight);
203
+ mQ += a * weight;
204
+ gv += a * a * weight;
205
+ hm += a * value.rgb * weight;
206
+ qf += g.x * weight;
207
+ gx += g.y * weight * weight;
208
+ oE += weight;
209
+ kX = max(kX, weight);
208
210
  }
209
211
  }
210
212
 
211
213
 
212
214
 
213
- vec4 center = rL(p);
214
- vec2 le = nH(p);
215
- float dG = max(kM, CENTER_WEIGHT_MIN);
216
- float totalWeight = nU + dG;
217
- vec4 mean = (sum + center * dG) / totalWeight;
215
+ vec4 center = sI(p);
216
+ vec2 lw = loadGuide(p);
217
+ float dE = max(kX, CENTER_WEIGHT_MIN);
218
+ float totalWeight = oE + dE;
219
+ vec4 mean = (sum + center * dE) / totalWeight;
218
220
 
219
221
 
220
- vec3 ez = mp / totalWeight;
221
- vec3 lA = max(gy / totalWeight - ez * ez, vec3(0.0));
222
- vec3 qu = hs / totalWeight - ez * mean.rgb;
222
+ vec3 er = mQ / totalWeight;
223
+ vec3 lQ = max(gv / totalWeight - er * er, vec3(0.0));
224
+ vec3 rq = hm / totalWeight - er * mean.rgb;
223
225
 
224
226
 
225
227
 
226
- vec3 qE = bs.rgb + ez * gW;
227
- vec3 oz = mean.rgb * gW / max(qE, vec3(${JNLM_ALBEDO_FLOOR}));
228
- vec3 vB = clamp(qu / (lA + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), oz);
229
- vec3 rD = mean.rgb - vB * ez;
230
- vec4 filtered = vec4(max(rD, vec3(0.0)), max(mean.a, 0.0));
228
+ vec3 rD = bo.rgb + er * gR;
229
+ vec3 pd = mean.rgb * gR / max(rD, vec3(${JNLM_ALBEDO_FLOOR}));
230
+ vec3 xI = clamp(rq / (lQ + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), pd);
231
+ vec3 sz = mean.rgb - xI * er;
232
+ vec4 filtered = vec4(max(sz, vec3(0.0)), max(mean.a, 0.0));
231
233
  vec3 rgb = filtered.a > 1e-6
232
234
  ? filtered.rgb / max(filtered.a, 1e-6)
233
235
  : center.rgb / max(center.a, 1e-6);
234
- if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.2));
236
+ if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,
237
+ rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));
235
238
  out_color = vec4(rgb, filtered.a);
236
239
  out_guide = vec4(
237
- (ps + le.x * dG) / totalWeight,
238
- (gA + le.y * dG * dG)
240
+ (qf + lw.x * dE) / totalWeight,
241
+ (gx + lw.y * dE * dE)
239
242
  / (totalWeight * totalWeight),
240
243
  0.0,
241
244
  1.0
@@ -272,7 +275,7 @@ export class WebGLJNLMDenoisePass {
272
275
  }));
273
276
  }
274
277
  /** Runs the denoiser and returns the display-encoded result. */
275
- render(inputs) {
278
+ render(inputs, trace) {
276
279
  const { width, height, shape } = inputs;
277
280
  const passes = [this._guidePass, this._variancePass, ...this._filterPasses];
278
281
  passes.forEach((pass) => pass.setSize(width, height));
@@ -300,6 +303,12 @@ export class WebGLJNLMDenoisePass {
300
303
  decodeInput: i === 0,
301
304
  encodeOutput: i === iterations - 1
302
305
  });
306
+ if (trace) {
307
+ if (i === 0)
308
+ trace.push('Decode:DisplayLinear', 'Denoise:DisplayLinear');
309
+ if (i === iterations - 1)
310
+ trace.push('Encode:DisplayEncoded');
311
+ }
303
312
  pass.createPass({
304
313
  guideTex: guide,
305
314
  colorTex: color,
@@ -1 +1 @@
1
- {"version":3,"file":"WebGLJNLMDenoiser.js","sourceRoot":"","sources":["../../src/renderer/WebGLJNLMDenoiser.ts"],"names":[],"mappings":"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","sourcesContent":["import { FragmentShader, glsl, Shader } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport {\n JNLM_DEFAULT_COLOR_SENSITIVITY,\n JNLM_ALBEDO_FLOOR,\n JNLM_ALBEDO_REGULARIZATION,\n JNLM_DEFAULT_SHAPE,\n JNLM_COVERAGE_BANDWIDTH,\n JNLM_MAX_ITERATIONS,\n jnlmPassDilation,\n type JNLMFilterShape\n} from './jnlm.js';\n\n/**\n * WebGL 2 passes of the JNLM denoiser described in `jnlm.ts`, matching\n * WGPUJNLMDenoiser. Textures replace its storage buffers.\n */\n\n/**\n * The guide mean and the variance of that mean. The main and catcher trace\n * passes each accumulate (sum, sum of squares, count) for their own samples.\n */\nconst guideFragment = new FragmentShader({\n name: 'jnlmGuide',\n outputs: ['guide'],\n uniforms: {\n momentsTex: Shader.uniform('sampler2D'),\n catcherMomentsTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 moments = load_momentsTex(p, 0) + load_catcherMomentsTex(p, 0);\n float n = moments.z;\n float mean = moments.x / max(n, 1.0);\n // Variance of the mean, or -1 when one sample cannot estimate it.\n float variance = n >= 2.0\n ? max(moments.y - n * mean * mean, 0.0) / (n * (n - 1.0))\n : -1.0;\n out_guide = vec4(mean, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * Smooths the noisy per-pixel variance over 3 x 3 pixels. Pixels with a\n * single sample take the spatial variance of their neighborhood instead.\n */\nconst varianceFragment = new FragmentShader({\n name: 'jnlmVariance',\n outputs: ['guide'],\n uniforms: {\n rawGuideTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n ivec2 size = rawGuideTexRegion();\n vec2 center = load_rawGuideTex(p, 0).xy;\n float varianceSum = 0.0;\n float varianceCount = 0.0;\n float meanSum = 0.0;\n float meanSquareSum = 0.0;\n for (int dy = -1; dy <= 1; dy++) {\n for (int dx = -1; dx <= 1; dx++) {\n vec2 value = load_rawGuideTex(clamp(p + ivec2(dx, dy), ivec2(0), size - 1), 0).xy;\n meanSum += value.x;\n meanSquareSum += value.x * value.x;\n if (value.y >= 0.0) {\n varianceSum += value.y;\n varianceCount += 1.0;\n }\n }\n }\n float variance;\n if (center.y >= 0.0) {\n variance = varianceSum / varianceCount;\n } else {\n float spatialMean = meanSum / 9.0;\n variance = max(meanSquareSum / 9.0 - spatialMean * spatialMean, 0.0) * 9.0 / 8.0;\n }\n out_guide = vec4(center.x, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * One joint NL-means pass; see createJNLMFilterWGSL. The first pass decodes\n * the display-encoded composition to linear light, the last encodes it again.\n */\nconst filterFragment = new FragmentShader({\n name: 'jnlmFilter',\n outputs: ['color', 'guide'],\n defines: {\n SEARCH_RADIUS: JNLM_DEFAULT_SHAPE.searchRadius,\n PATCH_RADIUS: JNLM_DEFAULT_SHAPE.patchRadius,\n INV_ALBEDO_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.normalBandwidth ** 2).toFixed(6)\n },\n uniforms: {\n guideTex: Shader.uniform('sampler2D'),\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n colorSensitivity: Shader.uniform('float', JNLM_DEFAULT_COLOR_SENSITIVITY),\n dilation: Shader.uniform('int', 1),\n decodeInput: Shader.uniform('bool', 0),\n encodeOutput: Shader.uniform('bool', 0)\n },\n main: glsl`\n#define PATCH_SIZE ((2 * PATCH_RADIUS + 1) * (2 * PATCH_RADIUS + 1))\n// Variance cancellation strength alpha of the paper.\n#define VARIANCE_CANCELLATION 1.0\n// Lower bound of the center weight, so a pixel unlike all of its neighbors\n// (a thin highlight) is kept rather than replaced by them.\n#define CENTER_WEIGHT_MIN 0.01\n#define INV_COVERAGE_BANDWIDTH2 ${(1 / JNLM_COVERAGE_BANDWIDTH ** 2).toFixed(6)}\n\nivec2 imageSize;\n\nvec2 loadGuide(ivec2 p) {\n return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;\n}\n\n// Premultiplied linear color.\nvec4 loadColor(ivec2 p) {\n vec4 c = load_colorTex(p, 0);\n if (decodeInput) c.rgb = pow(max(c.rgb, 0.0), vec3(2.2));\n return vec4(c.rgb * c.a, c.a);\n}\n\nfloat featureDistance(ivec2 q, vec4 centerAlbedo, vec3 centerNormal) {\n vec4 albedo = load_albedoTex(q, 0);\n // Match WebGPU: protect relative RGB contrast, including dark textures,\n // while keeping coverage differences in absolute units.\n vec3 albedoScale = max((albedo.rgb + centerAlbedo.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 albedoDelta = (albedo.rgb - centerAlbedo.rgb) / albedoScale;\n float coverageDelta = albedo.a - centerAlbedo.a;\n vec3 normalDelta = load_normalTex(q, 0).rgb - centerNormal;\n return max(\n dot(albedoDelta, albedoDelta) * INV_ALBEDO_BANDWIDTH2\n + coverageDelta * coverageDelta * INV_COVERAGE_BANDWIDTH2,\n dot(normalDelta, normalDelta) * INV_NORMAL_BANDWIDTH2\n );\n}\n\nvoid main() {\n imageSize = guideTexRegion();\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 centerAlbedo = load_albedoTex(p, 0);\n vec4 centerNormalTexel = load_normalTex(p, 0);\n vec3 centerNormal = centerNormalTexel.rgb;\n // Primary misses show the background directly. It has no features that\n // protect its detail and no noise beyond antialiasing, so keep it.\n if (centerNormalTexel.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {\n vec4 c = loadColor(p);\n vec3 rgb = c.rgb / max(c.a, 1e-6);\n if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.2));\n out_color = vec4(rgb, c.a);\n out_guide = vec4(loadGuide(p), 0.0, 1.0);\n return;\n }\n\n vec2 centerPatch[PATCH_SIZE];\n int k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n centerPatch[k] = loadGuide(p + ivec2(dx, dy) * dilation);\n k++;\n }\n }\n float k2 = colorSensitivity * colorSensitivity;\n\n vec4 sum = vec4(0.0);\n vec3 featureScale = max(centerAlbedo.rgb, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 featureSum = vec3(0.0);\n vec3 featureSquareSum = vec3(0.0);\n vec3 featureColorSum = vec3(0.0);\n float guideSum = 0.0;\n float guideVarianceSum = 0.0;\n float weightSum = 0.0;\n float maxWeight = 0.0;\n for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {\n for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {\n ivec2 q = p + ivec2(sx, sy) * dilation;\n if (\n (sx == 0 && sy == 0) ||\n q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y\n ) continue;\n float features = featureDistance(q, centerAlbedo, centerNormal);\n if (features > 16.0) continue;\n\n float colorDistance = 0.0;\n k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n vec2 a = centerPatch[k];\n vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);\n float delta = a.x - b.x;\n colorDistance += (delta * delta\n - VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))\n / (1e-10 + k2 * (a.y + b.y));\n k++;\n }\n }\n colorDistance /= float(PATCH_SIZE);\n\n float weight = exp(-max(max(colorDistance, 0.0), features));\n vec2 g = loadGuide(q);\n // Filter premultiplied color so coverage and color stay consistent.\n vec3 a = (load_albedoTex(q, 0).rgb - centerAlbedo.rgb) / featureScale;\n vec4 value = loadColor(q);\n sum += value * weight;\n featureSum += a * weight;\n featureSquareSum += a * a * weight;\n featureColorSum += a * value.rgb * weight;\n guideSum += g.x * weight;\n guideVarianceSum += g.y * weight * weight;\n weightSum += weight;\n maxWeight = max(maxWeight, weight);\n }\n }\n\n // Weight the center like its most similar neighbor (Buades et al. 2005)\n // instead of 1, so isolated outliers are not kept unfiltered.\n vec4 center = loadColor(p);\n vec2 centerGuide = loadGuide(p);\n float centerWeight = max(maxWeight, CENTER_WEIGHT_MIN);\n float totalWeight = weightSum + centerWeight;\n vec4 mean = (sum + center * centerWeight) / totalWeight;\n // Fit each color channel against relative albedo with the same JNLM weights.\n // Centering at this pixel avoids cancellation when the feature is constant.\n vec3 meanFeature = featureSum / totalWeight;\n vec3 featureVariance = max(featureSquareSum / totalWeight - meanFeature * meanFeature, vec3(0.0));\n vec3 covariance = featureColorSum / totalWeight - meanFeature * mean.rgb;\n // A 1% contrast ridge stabilizes flat guides. Bound the response between no\n // texture dependence and multiplicative albedo modulation; specular color\n // with an unrelated albedo falls back to the weighted mean.\n vec3 meanAlbedo = centerAlbedo.rgb + meanFeature * featureScale;\n vec3 maximumSlope = mean.rgb * featureScale / max(meanAlbedo, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 slope = clamp(covariance / (featureVariance + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), maximumSlope);\n vec3 corrected = mean.rgb - slope * meanFeature;\n vec4 filtered = vec4(max(corrected, vec3(0.0)), max(mean.a, 0.0));\n vec3 rgb = filtered.a > 1e-6\n ? filtered.rgb / max(filtered.a, 1e-6)\n : center.rgb / max(center.a, 1e-6);\n if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.2));\n out_color = vec4(rgb, filtered.a);\n out_guide = vec4(\n (guideSum + centerGuide.x * centerWeight) / totalWeight,\n (guideVarianceSum + centerGuide.y * centerWeight * centerWeight)\n / (totalWeight * totalWeight),\n 0.0,\n 1.0\n );\n}`\n});\n\nexport interface WebGLJNLMInputs {\n width: number;\n height: number;\n /** Main trace pass moments: guide sum, sum of squares and count. */\n moments: Texture2D;\n /** Catcher trace pass moments, when the scene has a shadow catcher. */\n catcherMoments?: Texture2D;\n /** Display-encoded composition to filter. */\n color: Texture2D;\n albedo: Texture2D;\n normal: Texture2D;\n /** Normalized shadow-catcher mask; red is the catcher coverage. */\n shadowCatcher: Texture2D;\n strength: number;\n shape: JNLMFilterShape;\n}\n\nconst floatOutput = {\n type: constants.FLOAT,\n minFilter: constants.NEAREST,\n magFilter: constants.NEAREST\n};\n\nexport class WebGLJNLMDenoisePass {\n private _renderer: WebGLDevice;\n private _guidePass: WebGLFullQuadPass<'momentsTex' | 'catcherMomentsTex', 'guide'>;\n private _variancePass: WebGLFullQuadPass<'rawGuideTex', 'guide'>;\n // Two instances so consecutive passes ping-pong between their outputs.\n private _filterPasses: WebGLFullQuadPass<\n 'guideTex' | 'colorTex' | 'albedoTex' | 'normalTex' | 'shadowCatcherTex',\n 'color' | 'guide'\n >[];\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._guidePass = new WebGLFullQuadPass('jnlmGuide', renderer, {\n shader: guideFragment,\n outputParams: { guide: floatOutput }\n });\n this._variancePass = new WebGLFullQuadPass('jnlmVariance', renderer, {\n shader: varianceFragment,\n outputParams: { guide: floatOutput }\n });\n this._filterPasses = [0, 1].map(() =>\n new WebGLFullQuadPass('jnlmFilter', renderer, {\n shader: filterFragment,\n outputParams: {\n color: { type: constants.HALF_FLOAT },\n guide: floatOutput\n }\n })\n );\n }\n\n /** Runs the denoiser and returns the display-encoded result. */\n render(inputs: WebGLJNLMInputs): Texture2D {\n const { width, height, shape } = inputs;\n const passes = [this._guidePass, this._variancePass, ...this._filterPasses];\n passes.forEach((pass) => pass.setSize(width, height));\n this._guidePass.createPass({\n momentsTex: inputs.moments,\n catcherMomentsTex: inputs.catcherMoments ?? this._renderer.emptyTexture\n });\n this._variancePass.createPass({ rawGuideTex: this._guidePass.getOutput('guide') });\n\n const sensitivity = JNLM_DEFAULT_COLOR_SENSITIVITY * Math.max(inputs.strength, 1e-3);\n const iterations = Math.min(JNLM_MAX_ITERATIONS, Math.max(1, Math.round(shape.iterations)));\n let guide = this._variancePass.getOutput('guide');\n let color = inputs.color;\n for (let i = 0; i < iterations; i++) {\n const pass = this._filterPasses[i % 2];\n pass.setDefines({\n SEARCH_RADIUS: shape.searchRadius,\n // Numeric zero removes a define in the WebGL shader builder.\n PATCH_RADIUS: String(shape.patchRadius),\n INV_ALBEDO_BANDWIDTH2: (1 / shape.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / shape.normalBandwidth ** 2).toFixed(6)\n });\n pass.setUniforms({\n colorSensitivity: sensitivity,\n dilation: jnlmPassDilation(i),\n decodeInput: i === 0,\n encodeOutput: i === iterations - 1\n });\n pass.createPass({\n guideTex: guide,\n colorTex: color,\n albedoTex: inputs.albedo,\n normalTex: inputs.normal,\n shadowCatcherTex: inputs.shadowCatcher\n });\n guide = pass.getOutput('guide');\n color = pass.getOutput('color');\n }\n return color;\n }\n\n reserveCapacity() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach(pass => pass.reserveCapacity());\n }\n\n retainOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.retainOutput(texture)); }\n releaseOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.releaseOutput(texture)); }\n\n getMemoryBytes() {\n return [this._guidePass, this._variancePass, ...this._filterPasses]\n .reduce((sum, pass) => sum + pass.getMemoryBytes(), 0);\n }\n\n dispose() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach((pass) =>\n pass.dispose()\n );\n }\n}\n"]}
1
+ {"version":3,"file":"WebGLJNLMDenoiser.js","sourceRoot":"","sources":["../../src/renderer/WebGLJNLMDenoiser.ts"],"names":[],"mappings":"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","sourcesContent":["import { FragmentShader, glsl, Shader } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport {\n JNLM_DEFAULT_COLOR_SENSITIVITY,\n JNLM_ALBEDO_FLOOR,\n JNLM_ALBEDO_REGULARIZATION,\n JNLM_DEFAULT_SHAPE,\n JNLM_COVERAGE_BANDWIDTH,\n JNLM_MAX_ITERATIONS,\n jnlmPassDilation,\n type JNLMFilterShape\n} from './jnlm.js';\n\n/**\n * WebGL 2 passes of the JNLM denoiser described in `jnlm.ts`, matching\n * WGPUJNLMDenoiser. Textures replace its storage buffers.\n */\n\n/**\n * The guide mean and the variance of that mean. The main and catcher trace\n * passes each accumulate (sum, sum of squares, count) for their own samples.\n */\nconst guideFragment = new FragmentShader({\n name: 'jnlmGuide',\n outputs: ['guide'],\n uniforms: {\n momentsTex: Shader.uniform('sampler2D'),\n catcherMomentsTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 moments = load_momentsTex(p, 0) + load_catcherMomentsTex(p, 0);\n float n = moments.z;\n float mean = moments.x / max(n, 1.0);\n // Variance of the mean, or -1 when one sample cannot estimate it.\n float variance = n >= 2.0\n ? max(moments.y - n * mean * mean, 0.0) / (n * (n - 1.0))\n : -1.0;\n out_guide = vec4(mean, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * Smooths the noisy per-pixel variance over 3 x 3 pixels. Pixels with a\n * single sample take the spatial variance of their neighborhood instead.\n */\nconst varianceFragment = new FragmentShader({\n name: 'jnlmVariance',\n outputs: ['guide'],\n uniforms: {\n rawGuideTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n ivec2 size = rawGuideTexRegion();\n vec2 center = load_rawGuideTex(p, 0).xy;\n float varianceSum = 0.0;\n float varianceCount = 0.0;\n float meanSum = 0.0;\n float meanSquareSum = 0.0;\n for (int dy = -1; dy <= 1; dy++) {\n for (int dx = -1; dx <= 1; dx++) {\n vec2 value = load_rawGuideTex(clamp(p + ivec2(dx, dy), ivec2(0), size - 1), 0).xy;\n meanSum += value.x;\n meanSquareSum += value.x * value.x;\n if (value.y >= 0.0) {\n varianceSum += value.y;\n varianceCount += 1.0;\n }\n }\n }\n float variance;\n if (center.y >= 0.0) {\n variance = varianceSum / varianceCount;\n } else {\n float spatialMean = meanSum / 9.0;\n variance = max(meanSquareSum / 9.0 - spatialMean * spatialMean, 0.0) * 9.0 / 8.0;\n }\n out_guide = vec4(center.x, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * One joint NL-means pass; see createJNLMFilterWGSL. The first pass decodes\n * the display-encoded composition to linear light, the last encodes it again.\n */\nconst filterFragment = new FragmentShader({\n name: 'jnlmFilter',\n outputs: ['color', 'guide'],\n defines: {\n SEARCH_RADIUS: JNLM_DEFAULT_SHAPE.searchRadius,\n PATCH_RADIUS: JNLM_DEFAULT_SHAPE.patchRadius,\n INV_ALBEDO_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.normalBandwidth ** 2).toFixed(6)\n },\n uniforms: {\n guideTex: Shader.uniform('sampler2D'),\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n colorSensitivity: Shader.uniform('float', JNLM_DEFAULT_COLOR_SENSITIVITY),\n dilation: Shader.uniform('int', 1),\n decodeInput: Shader.uniform('bool', 0),\n encodeOutput: Shader.uniform('bool', 0)\n },\n main: glsl`\n#define PATCH_SIZE ((2 * PATCH_RADIUS + 1) * (2 * PATCH_RADIUS + 1))\n// Variance cancellation strength alpha of the paper.\n#define VARIANCE_CANCELLATION 1.0\n// Lower bound of the center weight, so a pixel unlike all of its neighbors\n// (a thin highlight) is kept rather than replaced by them.\n#define CENTER_WEIGHT_MIN 0.01\n#define INV_COVERAGE_BANDWIDTH2 ${(1 / JNLM_COVERAGE_BANDWIDTH ** 2).toFixed(6)}\n\nivec2 imageSize;\n\nvec2 loadGuide(ivec2 p) {\n return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;\n}\n\n// Premultiplied linear color.\nvec4 loadColor(ivec2 p) {\n vec4 c = load_colorTex(p, 0);\n if (decodeInput) c.rgb = mix(pow((max(c.rgb, 0.0) + 0.055) / 1.055, vec3(2.4)),\n c.rgb / 12.92, lessThanEqual(c.rgb, vec3(0.04045)));\n return vec4(c.rgb * c.a, c.a);\n}\n\nfloat featureDistance(ivec2 q, vec4 centerAlbedo, vec3 centerNormal) {\n vec4 albedo = load_albedoTex(q, 0);\n // Match WebGPU: protect relative RGB contrast, including dark textures,\n // while keeping coverage differences in absolute units.\n vec3 albedoScale = max((albedo.rgb + centerAlbedo.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 albedoDelta = (albedo.rgb - centerAlbedo.rgb) / albedoScale;\n float coverageDelta = albedo.a - centerAlbedo.a;\n vec3 normalDelta = load_normalTex(q, 0).rgb - centerNormal;\n return max(\n dot(albedoDelta, albedoDelta) * INV_ALBEDO_BANDWIDTH2\n + coverageDelta * coverageDelta * INV_COVERAGE_BANDWIDTH2,\n dot(normalDelta, normalDelta) * INV_NORMAL_BANDWIDTH2\n );\n}\n\nvoid main() {\n imageSize = guideTexRegion();\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 centerAlbedo = load_albedoTex(p, 0);\n vec4 centerNormalTexel = load_normalTex(p, 0);\n vec3 centerNormal = centerNormalTexel.rgb;\n // Primary misses show the background directly. It has no features that\n // protect its detail and no noise beyond antialiasing, so keep it.\n if (centerNormalTexel.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {\n vec4 c = loadColor(p);\n vec3 rgb = c.rgb / max(c.a, 1e-6);\n if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,\n rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));\n out_color = vec4(rgb, c.a);\n out_guide = vec4(loadGuide(p), 0.0, 1.0);\n return;\n }\n\n vec2 centerPatch[PATCH_SIZE];\n int k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n centerPatch[k] = loadGuide(p + ivec2(dx, dy) * dilation);\n k++;\n }\n }\n float k2 = colorSensitivity * colorSensitivity;\n\n vec4 sum = vec4(0.0);\n vec3 featureScale = max(centerAlbedo.rgb, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 featureSum = vec3(0.0);\n vec3 featureSquareSum = vec3(0.0);\n vec3 featureColorSum = vec3(0.0);\n float guideSum = 0.0;\n float guideVarianceSum = 0.0;\n float weightSum = 0.0;\n float maxWeight = 0.0;\n for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {\n for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {\n ivec2 q = p + ivec2(sx, sy) * dilation;\n if (\n (sx == 0 && sy == 0) ||\n q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y\n ) continue;\n float features = featureDistance(q, centerAlbedo, centerNormal);\n if (features > 16.0) continue;\n\n float colorDistance = 0.0;\n k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n vec2 a = centerPatch[k];\n vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);\n float delta = a.x - b.x;\n colorDistance += (delta * delta\n - VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))\n / (1e-10 + k2 * (a.y + b.y));\n k++;\n }\n }\n colorDistance /= float(PATCH_SIZE);\n\n float weight = exp(-max(max(colorDistance, 0.0), features));\n vec2 g = loadGuide(q);\n // Filter premultiplied color so coverage and color stay consistent.\n vec3 a = (load_albedoTex(q, 0).rgb - centerAlbedo.rgb) / featureScale;\n vec4 value = loadColor(q);\n sum += value * weight;\n featureSum += a * weight;\n featureSquareSum += a * a * weight;\n featureColorSum += a * value.rgb * weight;\n guideSum += g.x * weight;\n guideVarianceSum += g.y * weight * weight;\n weightSum += weight;\n maxWeight = max(maxWeight, weight);\n }\n }\n\n // Weight the center like its most similar neighbor (Buades et al. 2005)\n // instead of 1, so isolated outliers are not kept unfiltered.\n vec4 center = loadColor(p);\n vec2 centerGuide = loadGuide(p);\n float centerWeight = max(maxWeight, CENTER_WEIGHT_MIN);\n float totalWeight = weightSum + centerWeight;\n vec4 mean = (sum + center * centerWeight) / totalWeight;\n // Fit each color channel against relative albedo with the same JNLM weights.\n // Centering at this pixel avoids cancellation when the feature is constant.\n vec3 meanFeature = featureSum / totalWeight;\n vec3 featureVariance = max(featureSquareSum / totalWeight - meanFeature * meanFeature, vec3(0.0));\n vec3 covariance = featureColorSum / totalWeight - meanFeature * mean.rgb;\n // A 1% contrast ridge stabilizes flat guides. Bound the response between no\n // texture dependence and multiplicative albedo modulation; specular color\n // with an unrelated albedo falls back to the weighted mean.\n vec3 meanAlbedo = centerAlbedo.rgb + meanFeature * featureScale;\n vec3 maximumSlope = mean.rgb * featureScale / max(meanAlbedo, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 slope = clamp(covariance / (featureVariance + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), maximumSlope);\n vec3 corrected = mean.rgb - slope * meanFeature;\n vec4 filtered = vec4(max(corrected, vec3(0.0)), max(mean.a, 0.0));\n vec3 rgb = filtered.a > 1e-6\n ? filtered.rgb / max(filtered.a, 1e-6)\n : center.rgb / max(center.a, 1e-6);\n if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,\n rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));\n out_color = vec4(rgb, filtered.a);\n out_guide = vec4(\n (guideSum + centerGuide.x * centerWeight) / totalWeight,\n (guideVarianceSum + centerGuide.y * centerWeight * centerWeight)\n / (totalWeight * totalWeight),\n 0.0,\n 1.0\n );\n}`\n});\n\nexport interface WebGLJNLMInputs {\n width: number;\n height: number;\n /** Main trace pass moments: guide sum, sum of squares and count. */\n moments: Texture2D;\n /** Catcher trace pass moments, when the scene has a shadow catcher. */\n catcherMoments?: Texture2D;\n /** Display-encoded composition to filter. */\n color: Texture2D;\n albedo: Texture2D;\n normal: Texture2D;\n /** Normalized shadow-catcher mask; red is the catcher coverage. */\n shadowCatcher: Texture2D;\n strength: number;\n shape: JNLMFilterShape;\n}\n\nconst floatOutput = {\n type: constants.FLOAT,\n minFilter: constants.NEAREST,\n magFilter: constants.NEAREST\n};\n\nexport class WebGLJNLMDenoisePass {\n private _renderer: WebGLDevice;\n private _guidePass: WebGLFullQuadPass<'momentsTex' | 'catcherMomentsTex', 'guide'>;\n private _variancePass: WebGLFullQuadPass<'rawGuideTex', 'guide'>;\n // Two instances so consecutive passes ping-pong between their outputs.\n private _filterPasses: WebGLFullQuadPass<\n 'guideTex' | 'colorTex' | 'albedoTex' | 'normalTex' | 'shadowCatcherTex',\n 'color' | 'guide'\n >[];\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._guidePass = new WebGLFullQuadPass('jnlmGuide', renderer, {\n shader: guideFragment,\n outputParams: { guide: floatOutput }\n });\n this._variancePass = new WebGLFullQuadPass('jnlmVariance', renderer, {\n shader: varianceFragment,\n outputParams: { guide: floatOutput }\n });\n this._filterPasses = [0, 1].map(() =>\n new WebGLFullQuadPass('jnlmFilter', renderer, {\n shader: filterFragment,\n outputParams: {\n color: { type: constants.HALF_FLOAT },\n guide: floatOutput\n }\n })\n );\n }\n\n /** Runs the denoiser and returns the display-encoded result. */\n render(inputs: WebGLJNLMInputs, trace?: string[]): Texture2D {\n const { width, height, shape } = inputs;\n const passes = [this._guidePass, this._variancePass, ...this._filterPasses];\n passes.forEach((pass) => pass.setSize(width, height));\n this._guidePass.createPass({\n momentsTex: inputs.moments,\n catcherMomentsTex: inputs.catcherMoments ?? this._renderer.emptyTexture\n });\n this._variancePass.createPass({ rawGuideTex: this._guidePass.getOutput('guide') });\n\n const sensitivity = JNLM_DEFAULT_COLOR_SENSITIVITY * Math.max(inputs.strength, 1e-3);\n const iterations = Math.min(JNLM_MAX_ITERATIONS, Math.max(1, Math.round(shape.iterations)));\n let guide = this._variancePass.getOutput('guide');\n let color = inputs.color;\n for (let i = 0; i < iterations; i++) {\n const pass = this._filterPasses[i % 2];\n pass.setDefines({\n SEARCH_RADIUS: shape.searchRadius,\n // Numeric zero removes a define in the WebGL shader builder.\n PATCH_RADIUS: String(shape.patchRadius),\n INV_ALBEDO_BANDWIDTH2: (1 / shape.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / shape.normalBandwidth ** 2).toFixed(6)\n });\n pass.setUniforms({\n colorSensitivity: sensitivity,\n dilation: jnlmPassDilation(i),\n decodeInput: i === 0,\n encodeOutput: i === iterations - 1\n });\n if (trace) {\n if (i === 0) trace.push('Decode:DisplayLinear', 'Denoise:DisplayLinear');\n if (i === iterations - 1) trace.push('Encode:DisplayEncoded');\n }\n pass.createPass({\n guideTex: guide,\n colorTex: color,\n albedoTex: inputs.albedo,\n normalTex: inputs.normal,\n shadowCatcherTex: inputs.shadowCatcher\n });\n guide = pass.getOutput('guide');\n color = pass.getOutput('color');\n }\n return color;\n }\n\n reserveCapacity() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach(pass => pass.reserveCapacity());\n }\n\n retainOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.retainOutput(texture)); }\n releaseOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.releaseOutput(texture)); }\n\n getMemoryBytes() {\n return [this._guidePass, this._variancePass, ...this._filterPasses]\n .reduce((sum, pass) => sum + pass.getMemoryBytes(), 0);\n }\n\n dispose() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach((pass) =>\n pass.dispose()\n );\n }\n}\n"]}
@@ -42,11 +42,11 @@ vec4 mask = sample_shadowCatcherTex(v_Texcoord);
42
42
  vec4 background = sample_catcherBackgroundTex(v_Texcoord);
43
43
  float hit = sample_albedoTex(v_Texcoord).a;
44
44
 
45
- float qi = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;
46
- float iV = max(hit - mask.b * qi, 0.0);
45
+ float qZ = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;
46
+ float iT = max(hit - mask.b * qZ, 0.0);
47
47
  out_foreground = vec4(
48
- (light.rgb - background.rgb * qi)
49
- / (iV > 0.0 ? iV : sampleCount),
48
+ (light.rgb - background.rgb * qZ)
49
+ / (iT > 0.0 ? iT : sampleCount),
50
50
  clamp((light.a - background.a) / sampleCount, 0.0, 1.0)
51
51
  );
52
52
  out_catcherBackground = background / sampleCount;
@@ -75,6 +75,9 @@ out_catcherBackground = background / sampleCount;
75
75
  normalTex: rayTracePass.getOutput('normal'),
76
76
  shadowCatcherTex: rayTracePass.hasShadowCatcher()
77
77
  ? rayTracePass.getOutput('shadowCatcher')
78
+ : this._renderer.emptyTexture,
79
+ catcherMomentsTex: rayTracePass.hasShadowCatcher()
80
+ ? rayTracePass.getOutput('catcherMoments')
78
81
  : this._renderer.emptyTexture
79
82
  }, undefined, { clear: true });
80
83
  if (rayTracePass.hasShadowCatcher()) {
@@ -1 +1 @@
1
- {"version":3,"file":"WebGLRayTraceOutputPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLRayTraceOutputPass.ts"],"names":[],"mappings":"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","sourcesContent":["import { FragmentShader, Shader, glsl } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport normalizeRayTraceOutput from './glsl/normalizeRayTraceOutput.frag.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport WebGLRayTracePass from './WebGLRayTracePass.js';\n\ntype RayTraceInput =\n | 'colorTex'\n | 'albedoTex'\n | 'normalTex'\n | 'shadowCatcherTex';\ntype LayerOutput = 'foreground' | 'catcherBackground';\ntype RayTraceOutput = 'color' | 'albedo' | 'normal' | 'shadowCatcher';\n\n/** Converts the additive ray tracing buffers into display/denoise textures. */\nexport class WebGLRayTraceOutputPass {\n private readonly _renderer: WebGLDevice;\n private readonly _pass: WebGLFullQuadPass<RayTraceInput, RayTraceOutput>;\n\n private readonly _layersPass: WebGLFullQuadPass<\n RayTraceInput | 'catcherBackgroundTex', LayerOutput\n >;\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._pass = new WebGLFullQuadPass('rayTraceOutput', renderer, {\n shader: normalizeRayTraceOutput,\n outputs: ['color', 'albedo', 'normal', 'shadowCatcher'],\n outputParams: {\n color: {\n type: constants.HALF_FLOAT,\n minFilter: constants.LINEAR,\n magFilter: constants.LINEAR\n },\n albedo: { type: constants.UNSIGNED_BYTE },\n normal: { type: constants.UNSIGNED_BYTE },\n shadowCatcher: { type: constants.HALF_FLOAT }\n }\n });\n this._layersPass = new WebGLFullQuadPass('rayTraceLayers', renderer, {\n shader: new FragmentShader({\n name: 'normalizeRayTraceLayers',\n outputs: ['foreground', 'catcherBackground'],\n uniforms: {\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n catcherBackgroundTex: Shader.uniform('sampler2D'),\n sampleCount: Shader.uniform('float', 1)\n },\n main: glsl`\nvoid main() {\n vec4 light = sample_colorTex(v_Texcoord);\n vec4 mask = sample_shadowCatcherTex(v_Texcoord);\n vec4 background = sample_catcherBackgroundTex(v_Texcoord);\n float hit = sample_albedoTex(v_Texcoord).a;\n // Full spectral beauty has three wavelength contributions per shadow sample.\n float contributions = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;\n float foregroundHit = max(hit - mask.b * contributions, 0.0);\n out_foreground = vec4(\n (light.rgb - background.rgb * contributions)\n / (foregroundHit > 0.0 ? foregroundHit : sampleCount),\n clamp((light.a - background.a) / sampleCount, 0.0, 1.0)\n );\n out_catcherBackground = background / sampleCount;\n}`\n }),\n outputs: ['foreground', 'catcherBackground'],\n outputParams: {\n foreground: { type: constants.HALF_FLOAT },\n catcherBackground: { type: constants.HALF_FLOAT }\n }\n });\n }\n\n setSize(width: number, height: number) {\n this._pass.setSize(width, height);\n this._layersPass.setSize(width, height);\n }\n\n setSampleCount(sampleCount: number) {\n this._pass.setUniform('sampleCount', Math.max(sampleCount, 1));\n this._layersPass.setUniform('sampleCount', Math.max(sampleCount, 1));\n }\n\n createPass(rayTracePass: WebGLRayTracePass) {\n this._pass.setOutputs(rayTracePass.hasShadowCatcher() ? ['color', 'albedo', 'normal', 'shadowCatcher'] : ['color', 'albedo', 'normal']);\n this._pass.createPass(\n {\n colorTex: rayTracePass.getOutput('color'),\n albedoTex: rayTracePass.getOutput('albedo'),\n normalTex: rayTracePass.getOutput('normal'),\n shadowCatcherTex: rayTracePass.hasShadowCatcher()\n ? rayTracePass.getOutput('shadowCatcher')\n : this._renderer.emptyTexture\n },\n undefined,\n { clear: true }\n );\n if (rayTracePass.hasShadowCatcher()) {\n this._layersPass.setOutputs(['foreground', 'catcherBackground']);\n this._layersPass.createPass({\n colorTex: rayTracePass.getOutput('color'),\n albedoTex: rayTracePass.getOutput('albedo'),\n normalTex: rayTracePass.getOutput('normal'),\n shadowCatcherTex: rayTracePass.getOutput('shadowCatcher'),\n catcherBackgroundTex: rayTracePass.getOutput('catcherBackground')\n }, undefined, { clear: true });\n } else {\n this._layersPass.setOutputs([]);\n }\n }\n\n getOutput(label: RayTraceOutput | LayerOutput): Texture2D {\n return label === 'foreground' || label === 'catcherBackground'\n ? this._layersPass.getOutput(label) ?? this._renderer.emptyTexture : this._pass.getOutput(label) ?? this._renderer.emptyTexture;\n }\n\n retainOutput(texture: Texture2D) { this._pass.retainOutput(texture); this._layersPass.retainOutput(texture); }\n releaseOutput(texture: Texture2D) { this._pass.releaseOutput(texture); this._layersPass.releaseOutput(texture); }\n\n getMemoryBytes() { return this._pass.getMemoryBytes() + this._layersPass.getMemoryBytes(); }\n\n dispose() {\n this._pass.dispose();\n this._layersPass.dispose();\n }\n}\n\n"]}
1
+ {"version":3,"file":"WebGLRayTraceOutputPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLRayTraceOutputPass.ts"],"names":[],"mappings":"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","sourcesContent":["import { FragmentShader, Shader, glsl } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport normalizeRayTraceOutput from './glsl/normalizeRayTraceOutput.frag.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport WebGLRayTracePass from './WebGLRayTracePass.js';\n\ntype RayTraceInput =\n | 'colorTex'\n | 'albedoTex'\n | 'normalTex'\n | 'shadowCatcherTex';\ntype LayerOutput = 'foreground' | 'catcherBackground';\ntype RayTraceOutput = 'color' | 'albedo' | 'normal' | 'shadowCatcher';\n\n/** Converts the additive ray tracing buffers into display/denoise textures. */\nexport class WebGLRayTraceOutputPass {\n private readonly _renderer: WebGLDevice;\n private readonly _pass: WebGLFullQuadPass<RayTraceInput | 'catcherMomentsTex', RayTraceOutput>;\n\n private readonly _layersPass: WebGLFullQuadPass<\n RayTraceInput | 'catcherBackgroundTex', LayerOutput\n >;\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._pass = new WebGLFullQuadPass('rayTraceOutput', renderer, {\n shader: normalizeRayTraceOutput,\n outputs: ['color', 'albedo', 'normal', 'shadowCatcher'],\n outputParams: {\n color: {\n type: constants.HALF_FLOAT,\n minFilter: constants.LINEAR,\n magFilter: constants.LINEAR\n },\n albedo: { type: constants.UNSIGNED_BYTE },\n normal: { type: constants.UNSIGNED_BYTE },\n shadowCatcher: { type: constants.HALF_FLOAT }\n }\n });\n this._layersPass = new WebGLFullQuadPass('rayTraceLayers', renderer, {\n shader: new FragmentShader({\n name: 'normalizeRayTraceLayers',\n outputs: ['foreground', 'catcherBackground'],\n uniforms: {\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n catcherBackgroundTex: Shader.uniform('sampler2D'),\n sampleCount: Shader.uniform('float', 1)\n },\n main: glsl`\nvoid main() {\n vec4 light = sample_colorTex(v_Texcoord);\n vec4 mask = sample_shadowCatcherTex(v_Texcoord);\n vec4 background = sample_catcherBackgroundTex(v_Texcoord);\n float hit = sample_albedoTex(v_Texcoord).a;\n // Full spectral beauty has three wavelength contributions per shadow sample.\n float contributions = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;\n float foregroundHit = max(hit - mask.b * contributions, 0.0);\n out_foreground = vec4(\n (light.rgb - background.rgb * contributions)\n / (foregroundHit > 0.0 ? foregroundHit : sampleCount),\n clamp((light.a - background.a) / sampleCount, 0.0, 1.0)\n );\n out_catcherBackground = background / sampleCount;\n}`\n }),\n outputs: ['foreground', 'catcherBackground'],\n outputParams: {\n foreground: { type: constants.HALF_FLOAT },\n catcherBackground: { type: constants.HALF_FLOAT }\n }\n });\n }\n\n setSize(width: number, height: number) {\n this._pass.setSize(width, height);\n this._layersPass.setSize(width, height);\n }\n\n setSampleCount(sampleCount: number) {\n this._pass.setUniform('sampleCount', Math.max(sampleCount, 1));\n this._layersPass.setUniform('sampleCount', Math.max(sampleCount, 1));\n }\n\n createPass(rayTracePass: WebGLRayTracePass) {\n this._pass.setOutputs(rayTracePass.hasShadowCatcher() ? ['color', 'albedo', 'normal', 'shadowCatcher'] : ['color', 'albedo', 'normal']);\n this._pass.createPass(\n {\n colorTex: rayTracePass.getOutput('color'),\n albedoTex: rayTracePass.getOutput('albedo'),\n normalTex: rayTracePass.getOutput('normal'),\n shadowCatcherTex: rayTracePass.hasShadowCatcher()\n ? rayTracePass.getOutput('shadowCatcher')\n : this._renderer.emptyTexture,\n catcherMomentsTex: rayTracePass.hasShadowCatcher()\n ? rayTracePass.getOutput('catcherMoments')\n : this._renderer.emptyTexture\n },\n undefined,\n { clear: true }\n );\n if (rayTracePass.hasShadowCatcher()) {\n this._layersPass.setOutputs(['foreground', 'catcherBackground']);\n this._layersPass.createPass({\n colorTex: rayTracePass.getOutput('color'),\n albedoTex: rayTracePass.getOutput('albedo'),\n normalTex: rayTracePass.getOutput('normal'),\n shadowCatcherTex: rayTracePass.getOutput('shadowCatcher'),\n catcherBackgroundTex: rayTracePass.getOutput('catcherBackground')\n }, undefined, { clear: true });\n } else {\n this._layersPass.setOutputs([]);\n }\n }\n\n getOutput(label: RayTraceOutput | LayerOutput): Texture2D {\n return label === 'foreground' || label === 'catcherBackground'\n ? this._layersPass.getOutput(label) ?? this._renderer.emptyTexture : this._pass.getOutput(label) ?? this._renderer.emptyTexture;\n }\n\n retainOutput(texture: Texture2D) { this._pass.retainOutput(texture); this._layersPass.retainOutput(texture); }\n releaseOutput(texture: Texture2D) { this._pass.releaseOutput(texture); this._layersPass.releaseOutput(texture); }\n\n getMemoryBytes() { return this._pass.getMemoryBytes() + this._layersPass.getMemoryBytes(); }\n\n dispose() {\n this._pass.dispose();\n this._layersPass.dispose();\n }\n}\n\n"]}
@@ -1,14 +1,21 @@
1
+ import { WebGLAov } from './WebGLAov.js';
2
+ import { type AovKind } from './aov.js';
1
3
  import { type SamplingPattern } from './sampling.js';
2
4
  import { type DepthSampleArea } from './depthQuery.js';
3
5
  import { WebGLDevice as WebGLRenderer, Texture2D as WebGLTexture2D } from './webgl.js';
4
6
  import Mesh from '../scene/Mesh.js';
5
7
  import OpenPBRMaterial from '../scene/OpenPBRMaterial.js';
6
- import { SceneBackground, SceneLight } from '../scene/Scene.js';
8
+ import type { SceneBackground, SceneLight } from '../scene/Scene.js';
7
9
  import Camera from '../scene/Camera.js';
8
10
  import Geometry from '../scene/Geometry.js';
9
11
  declare class WebGLRayTracePass {
12
+ private _aovPrimitiveCache;
10
13
  private readonly _renderer;
11
14
  private _meshes;
15
+ private _emissiveActive;
16
+ private _directLightLegacy?;
17
+ private _emissiveCache;
18
+ private _emissiveTex;
12
19
  private _sceneEnvironment;
13
20
  private _rectLightTextures;
14
21
  private _analyticLights;
@@ -44,12 +51,14 @@ declare class WebGLRayTracePass {
44
51
  private _envMap;
45
52
  private _envMapDistribution;
46
53
  private _envImageSource?;
54
+ private readonly _skySource;
47
55
  private _backgroundTex;
48
56
  private _hasEnvMap;
49
57
  private _hasBackground;
50
58
  private _groundedBackgroundParams;
51
59
  private _groundedBackgroundCenter;
52
60
  private _backgroundMapTransform;
61
+ private _backgroundMapRotation;
53
62
  private _bounces;
54
63
  private _bevelSamples;
55
64
  private _clamping?;
@@ -74,6 +83,8 @@ declare class WebGLRayTracePass {
74
83
  private _viewProjInv;
75
84
  private _apertureRadius;
76
85
  private _focusDistance;
86
+ private _aovPass;
87
+ private _aovCenter;
77
88
  private _tracePasses;
78
89
  private readonly _depthPass;
79
90
  private readonly _depthAbort;
@@ -81,6 +92,7 @@ declare class WebGLRayTracePass {
81
92
  private _hasShadowCatcher;
82
93
  private _spectral;
83
94
  constructor(renderer: WebGLRenderer);
95
+ preparePrograms(): boolean;
84
96
  createPass(clear: boolean, tile: {
85
97
  x: number;
86
98
  y: number;
@@ -105,7 +117,7 @@ declare class WebGLRayTracePass {
105
117
  buffer: ArrayBuffer;
106
118
  };
107
119
  getDiagnostics(): {
108
- textureAtlas: import("./MaterialTable.js").TextureAtlasStats | undefined;
120
+ textureAtlas: import("./textureAtlas.js").TextureAtlasStats | undefined;
109
121
  };
110
122
  private _updateMeshData;
111
123
  private _updateMaterialConstants;
@@ -128,8 +140,9 @@ declare class WebGLRayTracePass {
128
140
  bevel: boolean;
129
141
  dispersionWavelengths: 1 | 3;
130
142
  directLightCandidates: number;
143
+ caustics?: import('../Render.js').CausticSettings;
131
144
  }): void;
132
- setWavelength(wavelength: number): void;
145
+ setSpectralChannel(channel: number): void;
133
146
  setSampleCount(sampleCount: number): void;
134
147
  isInvalid(): boolean;
135
148
  hasShadowCatcher(): boolean;
@@ -137,6 +150,8 @@ declare class WebGLRayTracePass {
137
150
  prepare(): void;
138
151
  setSamplingPattern(pattern: SamplingPattern, maxSamples: number, sequenceSeed?: number): boolean;
139
152
  setSampleSequenceOffset(_offset: number): void;
153
+ prepareAovs(state: WebGLAov, camera: Camera, width: number, height: number, kinds: readonly AovKind[]): boolean;
154
+ renderAovs(state: WebGLAov, camera: Camera, width: number, height: number, samples: number, cap: number, kinds: readonly AovKind[], sequenceOffset?: number): boolean;
140
155
  readDepthSamples(area: DepthSampleArea, aspect?: number): Promise<Float32Array | undefined>;
141
156
  dispose(): void;
142
157
  }