@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
@@ -3,6 +3,7 @@
3
3
  export declare class WGPUShaderCache {
4
4
  private device;
5
5
  private modules;
6
+ private moduleIds;
6
7
  private bindGroupLayouts;
7
8
  private layouts;
8
9
  private pipelines;
@@ -21,6 +22,5 @@ export declare class WGPUShaderCache {
21
22
  createComputePipeline(descriptor: GPUComputePipelineDescriptor): GPUComputePipeline;
22
23
  clear(): void;
23
24
  }
24
- /** Grow in coarse buckets; scene edits must not shrink a compiled stack. */
25
- export declare function retainedShaderCapacity(required: number, previous?: number, minimum?: number): number;
25
+ export { retainedShaderCapacity } from './shaderCapacity.js';
26
26
  export declare function getTargetShaderCache(device: GPUDevice): WGPUShaderCache;
@@ -3,6 +3,7 @@
3
3
  export class WGPUShaderCache {
4
4
  device;
5
5
  modules = new Map();
6
+ moduleIds = new Map();
6
7
  bindGroupLayouts = new Map();
7
8
  layouts = new Map();
8
9
  pipelines = new Map();
@@ -30,7 +31,13 @@ export class WGPUShaderCache {
30
31
  }
31
32
  createShaderModule(descriptor) {
32
33
  const key = descriptor.code;
33
- return this.remember(this.modules, key, this.modules.get(key) ?? this.device.createShaderModule(descriptor), 8);
34
+ const module = this.remember(this.modules, key, this.modules.get(key) ?? this.device.createShaderModule(descriptor), 8);
35
+ // Pipeline retention is longer than module retention. Give exact source the
36
+ // same identity after module eviction, so a feature toggle can still find
37
+ // its compiled pipeline. Other GPU objects keep their object identities.
38
+ const id = this.remember(this.moduleIds, key, this.moduleIds.get(key) ?? this.id(module), 128);
39
+ this.ids.set(module, id);
40
+ return module;
34
41
  }
35
42
  createBindGroupLayout(descriptor) {
36
43
  const entries = Array.from(descriptor.entries);
@@ -81,6 +88,7 @@ export class WGPUShaderCache {
81
88
  }
82
89
  clear() {
83
90
  this.modules.clear();
91
+ this.moduleIds.clear();
84
92
  this.bindGroupLayouts.clear();
85
93
  this.layouts.clear();
86
94
  this.pipelines.clear();
@@ -88,10 +96,7 @@ export class WGPUShaderCache {
88
96
  this.computePipelines.clear();
89
97
  }
90
98
  }
91
- /** Grow in coarse buckets; scene edits must not shrink a compiled stack. */
92
- export function retainedShaderCapacity(required, previous = 0, minimum = 8) {
93
- return Math.max(previous, minimum, 2 ** Math.ceil(Math.log2(Math.max(1, required))));
94
- }
99
+ export { retainedShaderCapacity } from './shaderCapacity.js';
95
100
  /** Shared by target-local post-process passes; never contains GPU image resources. */
96
101
  const targetShaderCaches = new WeakMap();
97
102
  export function getTargetShaderCache(device) {
@@ -1 +1 @@
1
- {"version":3,"file":"WGPUShaderCache.js","sourceRoot":"","sources":["../../src/renderer/WGPUShaderCache.ts"],"names":[],"mappings":"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","sourcesContent":["/** Small renderer-owned caches. Keys include exact source and GPU object identity;\n * resources/bind groups are deliberately never retained here. */\nexport class WGPUShaderCache {\n private modules = new Map<string, GPUShaderModule>();\n private bindGroupLayouts = new Map<string, GPUBindGroupLayout>();\n private layouts = new Map<string, GPUPipelineLayout>();\n private pipelines = new Map<string, Promise<GPUComputePipeline>>();\n private renderPipelines = new Map<string, GPURenderPipeline>();\n private computePipelines = new Map<string, GPUComputePipeline>();\n private ids = new WeakMap<object, number>();\n private nextId = 0;\n\n constructor(private device: GPUDevice) {}\n\n private id(value: object) {\n let id = this.ids.get(value);\n if (id === undefined) {\n id = ++this.nextId;\n this.ids.set(value, id);\n }\n return id;\n }\n\n private remember<T>(cache: Map<string, T>, key: string, value: T, limit: number) {\n cache.delete(key);\n cache.set(key, value);\n if (cache.size > limit) cache.delete(cache.keys().next().value!);\n return value;\n }\n\n createShaderModule(descriptor: Pick<GPUShaderModuleDescriptor, 'code' | 'label'>) {\n const key = descriptor.code;\n return this.remember(this.modules, key,\n this.modules.get(key) ?? this.device.createShaderModule(descriptor), 8);\n }\n\n createBindGroupLayout(descriptor: GPUBindGroupLayoutDescriptor) {\n const entries = Array.from(descriptor.entries);\n const key = JSON.stringify(entries);\n return this.remember(this.bindGroupLayouts, key,\n this.bindGroupLayouts.get(key) ??\n this.device.createBindGroupLayout({ ...descriptor, entries }), 32);\n }\n\n createPipelineLayout(descriptor: GPUPipelineLayoutDescriptor) {\n const bindGroupLayouts = Array.from(descriptor.bindGroupLayouts);\n const { bindGroupLayouts: _groups, label: _label, ...options } = descriptor;\n const key = JSON.stringify([options,\n bindGroupLayouts.map((layout) => layout == null ? null : this.id(layout))]);\n return this.remember(this.layouts, key,\n this.layouts.get(key) ??\n this.device.createPipelineLayout({ ...descriptor, bindGroupLayouts }), 16);\n }\n\n createComputePipelineAsync(descriptor: GPUComputePipelineDescriptor) {\n const { compute, layout } = descriptor;\n const key = JSON.stringify([\n this.id(compute.module),\n layout === 'auto' ? 'auto' : this.id(layout),\n compute.entryPoint,\n Object.entries(compute.constants ?? {}).sort(([a], [b]) => a.localeCompare(b))\n ]);\n let pipeline = this.pipelines.get(key);\n if (!pipeline) {\n pipeline = this.device.createComputePipelineAsync(descriptor);\n const pending = pipeline;\n // A failed/in-flight request must not poison a later retry. The identity\n // guard also avoids deleting a replacement after LRU eviction.\n void pending.catch(() => {\n if (this.pipelines.get(key) === pending) this.pipelines.delete(key);\n });\n }\n return this.remember(this.pipelines, key, pipeline, 128);\n }\n\n createRenderPipeline(descriptor: GPURenderPipelineDescriptor) {\n const { label: _label, vertex, fragment, ...options } = descriptor;\n const key = JSON.stringify([options,\n { ...vertex, module: this.id(vertex.module) },\n fragment && { ...fragment, module: this.id(fragment.module) }]);\n return this.remember(this.renderPipelines, key,\n this.renderPipelines.get(key) ?? this.device.createRenderPipeline(descriptor), 128);\n }\n\n createComputePipeline(descriptor: GPUComputePipelineDescriptor) {\n const { label: _label, compute, ...options } = descriptor;\n const key = JSON.stringify([options, { ...compute, module: this.id(compute.module) }]);\n return this.remember(this.computePipelines, key,\n this.computePipelines.get(key) ?? this.device.createComputePipeline(descriptor), 128);\n }\n\n clear() {\n this.modules.clear();\n this.bindGroupLayouts.clear();\n this.layouts.clear();\n this.pipelines.clear();\n this.renderPipelines.clear();\n this.computePipelines.clear();\n }\n}\n\n/** Grow in coarse buckets; scene edits must not shrink a compiled stack. */\nexport function retainedShaderCapacity(required: number, previous = 0, minimum = 8) {\n return Math.max(previous, minimum, 2 ** Math.ceil(Math.log2(Math.max(1, required))));\n}\n\n/** Shared by target-local post-process passes; never contains GPU image resources. */\nconst targetShaderCaches = new WeakMap<GPUDevice, WGPUShaderCache>();\nexport function getTargetShaderCache(device: GPUDevice) {\n let cache = targetShaderCaches.get(device);\n if (!cache) targetShaderCaches.set(device, cache = new WGPUShaderCache(device));\n return cache;\n}\n"]}
1
+ {"version":3,"file":"WGPUShaderCache.js","sourceRoot":"","sources":["../../src/renderer/WGPUShaderCache.ts"],"names":[],"mappings":"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","sourcesContent":["/** Small renderer-owned caches. Keys include exact source and GPU object identity;\n * resources/bind groups are deliberately never retained here. */\nexport class WGPUShaderCache {\n private modules = new Map<string, GPUShaderModule>();\n private moduleIds = new Map<string, number>();\n private bindGroupLayouts = new Map<string, GPUBindGroupLayout>();\n private layouts = new Map<string, GPUPipelineLayout>();\n private pipelines = new Map<string, Promise<GPUComputePipeline>>();\n private renderPipelines = new Map<string, GPURenderPipeline>();\n private computePipelines = new Map<string, GPUComputePipeline>();\n private ids = new WeakMap<object, number>();\n private nextId = 0;\n\n constructor(private device: GPUDevice) {}\n\n private id(value: object) {\n let id = this.ids.get(value);\n if (id === undefined) {\n id = ++this.nextId;\n this.ids.set(value, id);\n }\n return id;\n }\n\n private remember<T>(cache: Map<string, T>, key: string, value: T, limit: number) {\n cache.delete(key);\n cache.set(key, value);\n if (cache.size > limit) cache.delete(cache.keys().next().value!);\n return value;\n }\n\n createShaderModule(descriptor: Pick<GPUShaderModuleDescriptor, 'code' | 'label'>) {\n const key = descriptor.code;\n const module = this.remember(this.modules, key,\n this.modules.get(key) ?? this.device.createShaderModule(descriptor), 8);\n // Pipeline retention is longer than module retention. Give exact source the\n // same identity after module eviction, so a feature toggle can still find\n // its compiled pipeline. Other GPU objects keep their object identities.\n const id = this.remember(this.moduleIds, key, this.moduleIds.get(key) ?? this.id(module), 128);\n this.ids.set(module, id);\n return module;\n }\n\n createBindGroupLayout(descriptor: GPUBindGroupLayoutDescriptor) {\n const entries = Array.from(descriptor.entries);\n const key = JSON.stringify(entries);\n return this.remember(this.bindGroupLayouts, key,\n this.bindGroupLayouts.get(key) ??\n this.device.createBindGroupLayout({ ...descriptor, entries }), 32);\n }\n\n createPipelineLayout(descriptor: GPUPipelineLayoutDescriptor) {\n const bindGroupLayouts = Array.from(descriptor.bindGroupLayouts);\n const { bindGroupLayouts: _groups, label: _label, ...options } = descriptor;\n const key = JSON.stringify([options,\n bindGroupLayouts.map((layout) => layout == null ? null : this.id(layout))]);\n return this.remember(this.layouts, key,\n this.layouts.get(key) ??\n this.device.createPipelineLayout({ ...descriptor, bindGroupLayouts }), 16);\n }\n\n createComputePipelineAsync(descriptor: GPUComputePipelineDescriptor) {\n const { compute, layout } = descriptor;\n const key = JSON.stringify([\n this.id(compute.module),\n layout === 'auto' ? 'auto' : this.id(layout),\n compute.entryPoint,\n Object.entries(compute.constants ?? {}).sort(([a], [b]) => a.localeCompare(b))\n ]);\n let pipeline = this.pipelines.get(key);\n if (!pipeline) {\n pipeline = this.device.createComputePipelineAsync(descriptor);\n const pending = pipeline;\n // A failed/in-flight request must not poison a later retry. The identity\n // guard also avoids deleting a replacement after LRU eviction.\n void pending.catch(() => {\n if (this.pipelines.get(key) === pending) this.pipelines.delete(key);\n });\n }\n return this.remember(this.pipelines, key, pipeline, 128);\n }\n\n createRenderPipeline(descriptor: GPURenderPipelineDescriptor) {\n const { label: _label, vertex, fragment, ...options } = descriptor;\n const key = JSON.stringify([options,\n { ...vertex, module: this.id(vertex.module) },\n fragment && { ...fragment, module: this.id(fragment.module) }]);\n return this.remember(this.renderPipelines, key,\n this.renderPipelines.get(key) ?? this.device.createRenderPipeline(descriptor), 128);\n }\n\n createComputePipeline(descriptor: GPUComputePipelineDescriptor) {\n const { label: _label, compute, ...options } = descriptor;\n const key = JSON.stringify([options, { ...compute, module: this.id(compute.module) }]);\n return this.remember(this.computePipelines, key,\n this.computePipelines.get(key) ?? this.device.createComputePipeline(descriptor), 128);\n }\n\n clear() {\n this.modules.clear();\n this.moduleIds.clear();\n this.bindGroupLayouts.clear();\n this.layouts.clear();\n this.pipelines.clear();\n this.renderPipelines.clear();\n this.computePipelines.clear();\n }\n}\n\nexport {retainedShaderCapacity} from './shaderCapacity.js';\n\n/** Shared by target-local post-process passes; never contains GPU image resources. */\nconst targetShaderCaches = new WeakMap<GPUDevice, WGPUShaderCache>();\nexport function getTargetShaderCache(device: GPUDevice) {\n let cache = targetShaderCaches.get(device);\n if (!cache) targetShaderCaches.set(device, cache = new WGPUShaderCache(device));\n return cache;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { type ShaderCapabilities } from './shaderCapabilities.js';
2
+ /** Metadata for successful pipelines. Transport and resource layouts never mix. */
3
+ export declare class WGPUShaderCapabilities {
4
+ private capacity;
5
+ private variants;
6
+ constructor(capacity?: number);
7
+ find(structure: string, required: ShaderCapabilities): ShaderCapabilities | undefined;
8
+ remember(structure: string, capabilities: ShaderCapabilities): void;
9
+ clear(): void;
10
+ }
@@ -0,0 +1,54 @@
1
+ import { shaderCapabilitiesInclude } from './shaderCapabilities.js';
2
+ function capabilityKey(capabilities) {
3
+ return `${capabilities.SCENE_CAPABILITIES},${capabilities.MATERIAL_CAPABILITIES},${capabilities.LIGHT_CAPABILITIES}`;
4
+ }
5
+ function capabilityCount(capabilities) {
6
+ let count = 0;
7
+ for (let bits of [capabilities.SCENE_CAPABILITIES, capabilities.MATERIAL_CAPABILITIES, capabilities.LIGHT_CAPABILITIES]) {
8
+ while (bits) {
9
+ bits &= bits - 1;
10
+ count++;
11
+ }
12
+ }
13
+ return count;
14
+ }
15
+ /** Metadata for successful pipelines. Transport and resource layouts never mix. */
16
+ export class WGPUShaderCapabilities {
17
+ capacity;
18
+ variants = new Map();
19
+ constructor(capacity = 128) {
20
+ this.capacity = capacity;
21
+ }
22
+ find(structure, required) {
23
+ const exactKey = structure + ':' + capabilityKey(required);
24
+ let key = exactKey;
25
+ let found = this.variants.get(key);
26
+ if (!found) {
27
+ let count = Infinity;
28
+ for (const [candidateKey, variant] of this.variants) {
29
+ if (variant.structure !== structure || !shaderCapabilitiesInclude(variant.capabilities, required))
30
+ continue;
31
+ const candidateCount = capabilityCount(variant.capabilities);
32
+ if (candidateCount <= count) {
33
+ key = candidateKey;
34
+ found = variant;
35
+ count = candidateCount;
36
+ }
37
+ }
38
+ }
39
+ if (!found)
40
+ return;
41
+ this.variants.delete(key);
42
+ this.variants.set(key, found);
43
+ return found.capabilities;
44
+ }
45
+ remember(structure, capabilities) {
46
+ const key = structure + ':' + capabilityKey(capabilities);
47
+ this.variants.delete(key);
48
+ this.variants.set(key, { structure, capabilities });
49
+ if (this.variants.size > this.capacity)
50
+ this.variants.delete(this.variants.keys().next().value);
51
+ }
52
+ clear() { this.variants.clear(); }
53
+ }
54
+ //# sourceMappingURL=WGPUShaderCapabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WGPUShaderCapabilities.js","sourceRoot":"","sources":["../../src/renderer/WGPUShaderCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,yBAAyB,EAA0B,MAAM,yBAAyB,CAAC;AAE3F,SAAS,aAAa,CAAC,YAAgC;IACrD,OAAO,GAAG,YAAY,CAAC,kBAAkB,IAAI,YAAY,CAAC,qBAAqB,IAAI,YAAY,CAAC,kBAAkB,EAAE,CAAC;AACvH,CAAC;AAED,SAAS,eAAe,CAAC,YAAgC;IACvD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,YAAY,CAAC,qBAAqB,EAAE,YAAY,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACxH,OAAO,IAAI,EAAE,CAAC;YAAC,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC;YAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IAC7C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mFAAmF;AACnF,MAAM,OAAO,sBAAsB;IAGb;IAFZ,QAAQ,GAAG,IAAI,GAAG,EAAiE,CAAC;IAE5F,YAAoB,WAAW,GAAG;QAAd,aAAQ,GAAR,QAAQ,CAAM;IAAG,CAAC;IAEtC,IAAI,CAAC,SAAiB,EAAE,QAA4B;QAClD,MAAM,QAAQ,GAAG,SAAS,GAAG,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC3D,IAAI,GAAG,GAAG,QAAQ,CAAC;QACnB,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,KAAK,GAAG,QAAQ,CAAC;YACrB,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACpD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,yBAAyB,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC;oBAAE,SAAS;gBAC5G,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC7D,IAAI,cAAc,IAAI,KAAK,EAAE,CAAC;oBAC5B,GAAG,GAAG,YAAY,CAAC;oBAAC,KAAK,GAAG,OAAO,CAAC;oBAAC,KAAK,GAAG,cAAc,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC,YAAY,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,SAAiB,EAAE,YAAgC;QAC1D,MAAM,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAC,SAAS,EAAE,YAAY,EAAC,CAAC,CAAC;QAClD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAC;IACnG,CAAC;IAED,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;CACnC","sourcesContent":["import {shaderCapabilitiesInclude, type ShaderCapabilities} from './shaderCapabilities.js';\n\nfunction capabilityKey(capabilities: ShaderCapabilities) {\n return `${capabilities.SCENE_CAPABILITIES},${capabilities.MATERIAL_CAPABILITIES},${capabilities.LIGHT_CAPABILITIES}`;\n}\n\nfunction capabilityCount(capabilities: ShaderCapabilities) {\n let count = 0;\n for (let bits of [capabilities.SCENE_CAPABILITIES, capabilities.MATERIAL_CAPABILITIES, capabilities.LIGHT_CAPABILITIES]) {\n while (bits) { bits &= bits - 1; count++; }\n }\n return count;\n}\n\n/** Metadata for successful pipelines. Transport and resource layouts never mix. */\nexport class WGPUShaderCapabilities {\n private variants = new Map<string, {structure: string; capabilities: ShaderCapabilities}>();\n\n constructor(private capacity = 128) {}\n\n find(structure: string, required: ShaderCapabilities) {\n const exactKey = structure + ':' + capabilityKey(required);\n let key = exactKey;\n let found = this.variants.get(key);\n if (!found) {\n let count = Infinity;\n for (const [candidateKey, variant] of this.variants) {\n if (variant.structure !== structure || !shaderCapabilitiesInclude(variant.capabilities, required)) continue;\n const candidateCount = capabilityCount(variant.capabilities);\n if (candidateCount <= count) {\n key = candidateKey; found = variant; count = candidateCount;\n }\n }\n }\n if (!found) return;\n this.variants.delete(key);\n this.variants.set(key, found);\n return found.capabilities;\n }\n\n remember(structure: string, capabilities: ShaderCapabilities) {\n const key = structure + ':' + capabilityKey(capabilities);\n this.variants.delete(key);\n this.variants.set(key, {structure, capabilities});\n if (this.variants.size > this.capacity) this.variants.delete(this.variants.keys().next().value!);\n }\n\n clear() { this.variants.clear(); }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { ProceduralEnvironmentSource } from './envMapDistribution.js';
2
+ /** Renders into the pipeline's own environment/background texture on its device. */
3
+ export declare class WGPUSkyBaker {
4
+ private readonly device;
5
+ private readonly tables;
6
+ private readonly uniforms;
7
+ private readonly pipelines;
8
+ private readonly inputs;
9
+ private time?;
10
+ constructor(device: GPUDevice);
11
+ bake(source: ProceduralEnvironmentSource, output: GPUTexture): void;
12
+ dispose(): void;
13
+ }
@@ -0,0 +1,85 @@
1
+ import { sunPosition } from '../scene/skyParameters.js';
2
+ import { SUN_RADIUS } from './skyModel.js';
3
+ import { proceduralSkyWGSL } from './wgsl/proceduralSky.compute.js';
4
+ /** Renders into the pipeline's own environment/background texture on its device. */
5
+ export class WGPUSkyBaker {
6
+ device;
7
+ tables;
8
+ uniforms;
9
+ pipelines;
10
+ inputs = { transmittance: [], multiple: [1, 2], skyView: [1, 2, 4], irradiance: [1, 3], map: [3, 4] };
11
+ time;
12
+ constructor(device) {
13
+ this.device = device;
14
+ const texture = (label, width, height) => device.createTexture({
15
+ label, size: [width, height], format: 'rgba32float', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING
16
+ });
17
+ this.tables = {
18
+ transmittance: texture('Sky transmittance', 256, 64), multiple: texture('Sky multiple scattering', 32, 1),
19
+ skyView: texture('Sky view', 96, 192), irradiance: texture('Sky irradiance', 2, 1)
20
+ };
21
+ this.uniforms = [0, 1].map(() => device.createBuffer({ label: 'Sky parameters', size: 80, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }));
22
+ const module = device.createShaderModule({ label: 'Procedural sky', code: proceduralSkyWGSL });
23
+ this.pipelines = {};
24
+ for (const pass of Object.keys(this.inputs)) {
25
+ const layout = device.createBindGroupLayout({ entries: [
26
+ { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },
27
+ ...this.inputs[pass].map(binding => ({ binding, visibility: GPUShaderStage.COMPUTE, texture: { sampleType: 'unfilterable-float' } })),
28
+ { binding: 5, visibility: GPUShaderStage.COMPUTE, storageTexture: { access: 'write-only', format: 'rgba32float' } }
29
+ ] });
30
+ this.pipelines[pass] = device.createComputePipeline({ label: `Sky ${pass}`, layout: device.createPipelineLayout({ bindGroupLayouts: [layout] }), compute: { module, entryPoint: pass } });
31
+ }
32
+ }
33
+ bake(source, output) {
34
+ const { width, height, sky, intensity, ambient } = source;
35
+ if (width > this.device.limits.maxTextureDimension2D || height > this.device.limits.maxTextureDimension2D) {
36
+ throw new RangeError('ProceduralSky resolution exceeds the device texture size limit.');
37
+ }
38
+ const { elevation, azimuth } = sunPosition(sky.time);
39
+ const e = elevation * Math.PI / 180, a = azimuth * Math.PI / 180;
40
+ const data = new Float32Array([
41
+ Math.cos(e), Math.sin(e), 0, a,
42
+ Math.cos(e) * Math.cos(a), Math.sin(e), Math.cos(e) * Math.sin(a), SUN_RADIUS * Math.PI / 180,
43
+ width, height, 0, 0,
44
+ intensity, intensity, intensity, 1,
45
+ ...ambient, 0
46
+ ]);
47
+ this.device.queue.writeBuffer(this.uniforms[0], 0, data);
48
+ data[11] = 1;
49
+ this.device.queue.writeBuffer(this.uniforms[1], 0, data);
50
+ const encoder = this.device.createCommandEncoder({ label: 'Procedural sky' });
51
+ const draw = (name, target, ground = false) => {
52
+ const pipeline = this.pipelines[name];
53
+ const inputs = {
54
+ 1: this.tables.transmittance, 2: name === 'multiple' ? this.tables.transmittance : this.tables.multiple,
55
+ 3: this.tables.skyView, 4: this.tables.irradiance
56
+ };
57
+ const group = this.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [
58
+ { binding: 0, resource: { buffer: this.uniforms[ground ? 1 : 0] } },
59
+ ...this.inputs[name].map(binding => ({ binding, resource: inputs[binding].createView() })),
60
+ { binding: 5, resource: target.createView() }
61
+ ] });
62
+ const pass = encoder.beginComputePass({ label: `Sky ${name}` });
63
+ pass.setPipeline(pipeline);
64
+ pass.setBindGroup(0, group);
65
+ pass.dispatchWorkgroups(Math.ceil(target.width / 8), Math.ceil(target.height / 8));
66
+ pass.end();
67
+ };
68
+ if (this.time === undefined)
69
+ draw('transmittance', this.tables.transmittance);
70
+ if (this.time !== sky.time) {
71
+ draw('multiple', this.tables.multiple);
72
+ draw('skyView', this.tables.skyView);
73
+ draw('irradiance', this.tables.irradiance);
74
+ draw('skyView', this.tables.skyView, true);
75
+ }
76
+ draw('map', output, true);
77
+ this.device.queue.submit([encoder.finish()]);
78
+ this.time = sky.time;
79
+ }
80
+ dispose() {
81
+ Object.values(this.tables).forEach(texture => texture.destroy());
82
+ this.uniforms.forEach(buffer => buffer.destroy());
83
+ }
84
+ }
85
+ //# sourceMappingURL=WGPUSkyBaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WGPUSkyBaker.js","sourceRoot":"","sources":["../../src/renderer/WGPUSkyBaker.ts"],"names":[],"mappings":"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","sourcesContent":["import { sunPosition } from '../scene/skyParameters.js';\nimport type { ProceduralEnvironmentSource } from './envMapDistribution.js';\nimport { SUN_RADIUS } from './skyModel.js';\nimport { proceduralSkyWGSL } from './wgsl/proceduralSky.compute.js';\n\ntype Pass = 'transmittance' | 'multiple' | 'skyView' | 'irradiance' | 'map';\n\n/** Renders into the pipeline's own environment/background texture on its device. */\nexport class WGPUSkyBaker {\n private readonly tables: Record<Exclude<Pass, 'map'>, GPUTexture>;\n private readonly uniforms: GPUBuffer[];\n private readonly pipelines: Record<Pass, GPUComputePipeline>;\n private readonly inputs: Record<Pass, number[]> = { transmittance: [], multiple: [1, 2], skyView: [1, 2, 4], irradiance: [1, 3], map: [3, 4] };\n private time?: number;\n\n constructor(private readonly device: GPUDevice) {\n const texture = (label: string, width: number, height: number) => device.createTexture({\n label, size: [width, height], format: 'rgba32float', usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING\n });\n this.tables = {\n transmittance: texture('Sky transmittance', 256, 64), multiple: texture('Sky multiple scattering', 32, 1),\n skyView: texture('Sky view', 96, 192), irradiance: texture('Sky irradiance', 2, 1)\n };\n this.uniforms = [0, 1].map(() => device.createBuffer({ label: 'Sky parameters', size: 80, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST }));\n const module = device.createShaderModule({ label: 'Procedural sky', code: proceduralSkyWGSL });\n this.pipelines = {} as Record<Pass, GPUComputePipeline>;\n for (const pass of Object.keys(this.inputs) as Pass[]) {\n const layout = device.createBindGroupLayout({ entries: [\n { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },\n ...this.inputs[pass].map(binding => ({ binding, visibility: GPUShaderStage.COMPUTE, texture: { sampleType: 'unfilterable-float' as const } })),\n { binding: 5, visibility: GPUShaderStage.COMPUTE, storageTexture: { access: 'write-only', format: 'rgba32float' } }\n ] });\n this.pipelines[pass] = device.createComputePipeline({ label: `Sky ${pass}`, layout: device.createPipelineLayout({ bindGroupLayouts: [layout] }), compute: { module, entryPoint: pass } });\n }\n }\n\n bake(source: ProceduralEnvironmentSource, output: GPUTexture) {\n const { width, height, sky, intensity, ambient } = source;\n if (width > this.device.limits.maxTextureDimension2D || height > this.device.limits.maxTextureDimension2D) {\n throw new RangeError('ProceduralSky resolution exceeds the device texture size limit.');\n }\n const { elevation, azimuth } = sunPosition(sky.time);\n const e = elevation * Math.PI / 180, a = azimuth * Math.PI / 180;\n const data = new Float32Array([\n Math.cos(e), Math.sin(e), 0, a,\n Math.cos(e) * Math.cos(a), Math.sin(e), Math.cos(e) * Math.sin(a), SUN_RADIUS * Math.PI / 180,\n width, height, 0, 0,\n intensity, intensity, intensity, 1,\n ...ambient, 0\n ]);\n this.device.queue.writeBuffer(this.uniforms[0], 0, data);\n data[11] = 1;\n this.device.queue.writeBuffer(this.uniforms[1], 0, data);\n const encoder = this.device.createCommandEncoder({ label: 'Procedural sky' });\n const draw = (name: Pass, target: GPUTexture, ground = false) => {\n const pipeline = this.pipelines[name];\n const inputs: Record<number, GPUTexture> = {\n 1: this.tables.transmittance, 2: name === 'multiple' ? this.tables.transmittance : this.tables.multiple,\n 3: this.tables.skyView, 4: this.tables.irradiance\n };\n const group = this.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [\n { binding: 0, resource: { buffer: this.uniforms[ground ? 1 : 0] } },\n ...this.inputs[name].map(binding => ({ binding, resource: inputs[binding].createView() })),\n { binding: 5, resource: target.createView() }\n ] });\n const pass = encoder.beginComputePass({ label: `Sky ${name}` });\n pass.setPipeline(pipeline); pass.setBindGroup(0, group);\n pass.dispatchWorkgroups(Math.ceil(target.width / 8), Math.ceil(target.height / 8)); pass.end();\n };\n if (this.time === undefined) draw('transmittance', this.tables.transmittance);\n if (this.time !== sky.time) {\n draw('multiple', this.tables.multiple);\n draw('skyView', this.tables.skyView);\n draw('irradiance', this.tables.irradiance);\n draw('skyView', this.tables.skyView, true);\n }\n draw('map', output, true);\n this.device.queue.submit([encoder.finish()]);\n this.time = sky.time;\n }\n\n dispose() {\n Object.values(this.tables).forEach(texture => texture.destroy());\n this.uniforms.forEach(buffer => buffer.destroy());\n }\n}\n"]}
@@ -0,0 +1,41 @@
1
+ import { type AovDisplayOptions } from './aovDisplay.js';
2
+ import { AovHistory, type AovKind, type AovFrameSnapshot } from './aov.js';
3
+ import { Texture2D, type WebGLDevice } from './webgl.js';
4
+ declare const names: readonly ["geometry", "position", "diffuse", "specular"];
5
+ export declare class WebGLAov {
6
+ readonly renderer: WebGLDevice;
7
+ private displayPass?;
8
+ readonly history: AovHistory;
9
+ width: number;
10
+ height: number;
11
+ samples: number;
12
+ centerReady: boolean;
13
+ frame?: AovFrameSnapshot;
14
+ readonly accumulation: Record<typeof names[number], Texture2D>[];
15
+ previousCenter: {
16
+ id: Texture2D;
17
+ motion: Texture2D;
18
+ } | undefined;
19
+ center: {
20
+ id: Texture2D;
21
+ motion: Texture2D;
22
+ } | undefined;
23
+ scene: Texture2D;
24
+ constructor(renderer: WebGLDevice);
25
+ reset(): void;
26
+ resize(width: number, height: number): void;
27
+ setScene(words: Uint32Array): void;
28
+ visualize(kind: AovKind, options: AovDisplayOptions): Texture2D;
29
+ read(kind: AovKind): Promise<{
30
+ width: number;
31
+ height: number;
32
+ data: Uint32Array<ArrayBuffer>;
33
+ } | {
34
+ width: number;
35
+ height: number;
36
+ data: Float32Array<ArrayBufferLike>;
37
+ }>;
38
+ get bytes(): number;
39
+ dispose(): void;
40
+ }
41
+ export {};
@@ -0,0 +1,106 @@
1
+ import displayShader from './glsl/aovDisplay.frag.js';
2
+ import { WebGLFullQuadPass } from './WebGLFullQuadPass.js';
3
+ import { AOV_KINDS } from './aov.js';
4
+ import { AOV_ID_COMPONENTS, validateAovDisplay } from './aovDisplay.js';
5
+ import { AovHistory } from './aov.js';
6
+ import { Texture2D, FrameBuffer } from './webgl.js';
7
+ import { readRgbaPixels } from './WebGLReadback.js';
8
+ const names = ['geometry', 'position', 'diffuse', 'specular'];
9
+ export class WebGLAov {
10
+ renderer;
11
+ displayPass;
12
+ history = new AovHistory();
13
+ width = 0;
14
+ height = 0;
15
+ samples = 0;
16
+ centerReady = false;
17
+ frame;
18
+ accumulation = [];
19
+ previousCenter;
20
+ center;
21
+ scene = new Texture2D({ type: 5125, minFilter: 9728, magFilter: 9728 });
22
+ constructor(renderer) {
23
+ this.renderer = renderer;
24
+ }
25
+ reset() { if (this.centerReady) {
26
+ const swap = this.previousCenter;
27
+ this.previousCenter = this.center;
28
+ this.center = swap;
29
+ } this.samples = 0; this.centerReady = false; this.frame = undefined; }
30
+ resize(width, height) {
31
+ if (width === this.width && height === this.height)
32
+ return;
33
+ this.dispose();
34
+ this.history.clear();
35
+ this.reset();
36
+ this.width = width;
37
+ this.height = height;
38
+ const options = { width, height, type: 5126, minFilter: 9728, magFilter: 9728 };
39
+ for (let i = 0; i < 2; i++)
40
+ this.accumulation.push(Object.fromEntries(names.map(n => [n, new Texture2D(options)])));
41
+ this.previousCenter = { id: new Texture2D({ ...options, type: 5125 }), motion: new Texture2D(options) };
42
+ this.center = { id: new Texture2D({ ...options, type: 5125 }), motion: new Texture2D(options) };
43
+ }
44
+ setScene(words) {
45
+ const width = Math.min(1024, Math.max(1, Math.ceil(words.length / 4))), height = Math.ceil(words.length / (width * 4));
46
+ const data = new Uint32Array(width * height * 4);
47
+ data.set(words);
48
+ this.scene.source = { data, width, height };
49
+ }
50
+ visualize(kind, options) {
51
+ if (!this.samples || !this.center)
52
+ throw new Error('AOV output is not ready');
53
+ validateAovDisplay(options);
54
+ this.displayPass ??= new WebGLFullQuadPass('AOV display', this.renderer, { shader: displayShader, outputs: ['color'] });
55
+ const pass = this.displayPass;
56
+ pass.setSize(this.width, this.height);
57
+ pass.setUniforms({ kind: AOV_KINDS.indexOf(kind), samples: this.samples, mapping: [...options.depthRange, options.positionScale, options.motionScale], idComponent: AOV_ID_COMPONENTS.indexOf(options.idComponent) });
58
+ pass.createPass({ ...this.accumulation[(this.samples - 1) % 2], identity: this.center.id, motion: this.center.motion });
59
+ return pass.getOutput('color');
60
+ }
61
+ async read(kind) {
62
+ const gl = this.renderer.gl, framebuffer = new FrameBuffer(), width = this.width, height = this.height;
63
+ try {
64
+ const accumulated = this.accumulation[(this.samples - 1) % 2];
65
+ const name = kind === 'depth' || kind === 'roughness' ? 'geometry' : kind === 'diffuseAlbedo' ? 'diffuse' : kind === 'specularAlbedo' ? 'specular' : 'position';
66
+ framebuffer.bind(this.renderer, [kind === 'id' ? this.center.id : kind === 'motion' ? this.center.motion : accumulated[name]]);
67
+ if (kind === 'id') {
68
+ const source = new Uint32Array(width * height * 4), data = new Uint32Array(source.length);
69
+ gl.readPixels(0, 0, width, height, gl.RGBA_INTEGER, gl.UNSIGNED_INT, source);
70
+ for (let y = 0; y < height; y++)
71
+ data.set(source.subarray((height - 1 - y) * width * 4, (height - y) * width * 4), y * width * 4);
72
+ return { width, height, data };
73
+ }
74
+ const data = readRgbaPixels(gl, width, height, false);
75
+ if (kind === 'motion') {
76
+ for (let o = 2; o < data.length; o += 4)
77
+ data[o] = 0;
78
+ return { width, height, data };
79
+ }
80
+ framebuffer.bind(this.renderer, [accumulated.position]);
81
+ const coverage = readRgbaPixels(gl, width, height, false);
82
+ for (let p = 0; p < width * height; p++) {
83
+ const o = p * 4, hits = coverage[o + 3], inv = hits > 0 ? 1 / hits : 0, alpha = hits / Math.max(1, this.samples);
84
+ if (kind === 'depth')
85
+ data.set([data[o] * inv, 0, 0, alpha], o);
86
+ else if (kind === 'roughness')
87
+ data.set([data[o + 1] * inv, data[o + 2] * inv, data[o + 3] * inv, alpha], o);
88
+ else if (kind === 'position')
89
+ data.set([data[o] * inv, data[o + 1] * inv, data[o + 2] * inv, alpha], o);
90
+ else {
91
+ const count = data[o + 3], scale = count > 0 ? 1 / count : 0;
92
+ data.set([data[o] * scale, data[o + 1] * scale, data[o + 2] * scale, count / Math.max(1, this.samples)], o);
93
+ }
94
+ }
95
+ return { width, height, data };
96
+ }
97
+ finally {
98
+ framebuffer.dispose(this.renderer);
99
+ }
100
+ }
101
+ get bytes() { return this.width * this.height * (2 * 64 + 64 + (this.displayPass ? 4 : 0)) + this.scene.width * this.scene.height * 16; }
102
+ dispose() { this.displayPass?.dispose(); this.displayPass = undefined; const gl = this.renderer.gl; for (const set of this.accumulation)
103
+ for (const texture of Object.values(set))
104
+ texture.dispose(gl); this.accumulation.length = 0; this.center?.id.dispose(gl); this.center?.motion.dispose(gl); this.center = undefined; this.previousCenter?.id.dispose(gl); this.previousCenter?.motion.dispose(gl); this.previousCenter = undefined; this.scene.dispose(gl); }
105
+ }
106
+ //# sourceMappingURL=WebGLAov.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGLAov.js","sourceRoot":"","sources":["../../src/renderer/WebGLAov.ts"],"names":[],"mappings":"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","sourcesContent":["import displayShader from './glsl/aovDisplay.frag.js';\nimport {WebGLFullQuadPass} from './WebGLFullQuadPass.js';\nimport {AOV_KINDS} from './aov.js';\nimport {AOV_ID_COMPONENTS, validateAovDisplay, type AovDisplayOptions} from './aovDisplay.js';\nimport {AovHistory, type AovKind, type AovFrameSnapshot} from './aov.js';\nimport {Texture2D, FrameBuffer, type WebGLDevice} from './webgl.js';\nimport {readRgbaPixels} from './WebGLReadback.js';\nconst names = ['geometry','position','diffuse','specular'] as const;\nexport class WebGLAov {\n private displayPass?: WebGLFullQuadPass<string,'color'>;\n readonly history=new AovHistory();\n width=0; height=0; samples=0; centerReady=false; frame?: AovFrameSnapshot;\n readonly accumulation: Record<typeof names[number],Texture2D>[]=[];\n previousCenter: {id:Texture2D; motion:Texture2D} | undefined;\n center: {id:Texture2D; motion:Texture2D} | undefined;\n scene = new Texture2D({type: 5125, minFilter:9728,magFilter:9728});\n constructor(readonly renderer: WebGLDevice) {}\n reset(){if(this.centerReady){const swap=this.previousCenter;this.previousCenter=this.center;this.center=swap;}this.samples=0;this.centerReady=false;this.frame=undefined;}\n resize(width:number,height:number){\n if(width===this.width && height===this.height)return;\n this.dispose();this.history.clear();this.reset();this.width=width;this.height=height;\n const options={width,height,type:5126,minFilter:9728,magFilter:9728};\n for(let i=0;i<2;i++)this.accumulation.push(Object.fromEntries(names.map(n=>[n,new Texture2D(options)])) as Record<typeof names[number],Texture2D>);\n this.previousCenter={id:new Texture2D({...options,type:5125}),motion:new Texture2D(options)};\n this.center={id:new Texture2D({...options,type:5125}),motion:new Texture2D(options)};\n }\n setScene(words:Uint32Array){\n const width=Math.min(1024,Math.max(1,Math.ceil(words.length/4))),height=Math.ceil(words.length/(width*4));\n const data=new Uint32Array(width*height*4);data.set(words);\n this.scene.source={data,width,height};\n }\n visualize(kind:AovKind,options:AovDisplayOptions):Texture2D {\n if(!this.samples || !this.center)throw new Error('AOV output is not ready');\n validateAovDisplay(options);\n this.displayPass??=new WebGLFullQuadPass('AOV display',this.renderer,{shader:displayShader,outputs:['color']});\n const pass=this.displayPass;pass.setSize(this.width,this.height);pass.setUniforms({kind:AOV_KINDS.indexOf(kind),samples:this.samples,mapping:[...options.depthRange,options.positionScale,options.motionScale],idComponent:AOV_ID_COMPONENTS.indexOf(options.idComponent)});\n pass.createPass({...this.accumulation[(this.samples-1)%2],identity:this.center.id,motion:this.center.motion});return pass.getOutput('color');\n }\n async read(kind:AovKind){\n const gl=this.renderer.gl, framebuffer=new FrameBuffer(), width=this.width,height=this.height;\n try{\n const accumulated=this.accumulation[(this.samples-1)%2];\n const name=kind==='depth'||kind==='roughness'?'geometry':kind==='diffuseAlbedo'?'diffuse':kind==='specularAlbedo'?'specular':'position';\n framebuffer.bind(this.renderer,[kind==='id'?this.center!.id:kind==='motion'?this.center!.motion:accumulated[name]]);\n if(kind==='id'){\n const source=new Uint32Array(width*height*4),data=new Uint32Array(source.length);\n gl.readPixels(0,0,width,height,gl.RGBA_INTEGER,gl.UNSIGNED_INT,source);\n for(let y=0;y<height;y++)data.set(source.subarray((height-1-y)*width*4,(height-y)*width*4),y*width*4);\n return {width,height,data};\n }\n const data=readRgbaPixels(gl,width,height,false);\n if(kind==='motion'){for(let o=2;o<data.length;o+=4)data[o]=0;return {width,height,data};}\n framebuffer.bind(this.renderer,[accumulated.position]);const coverage=readRgbaPixels(gl,width,height,false);\n for(let p=0;p<width*height;p++){\n const o=p*4,hits=coverage[o+3],inv=hits>0?1/hits:0,alpha=hits/Math.max(1,this.samples);\n if(kind==='depth')data.set([data[o]*inv,0,0,alpha],o);\n else if(kind==='roughness')data.set([data[o+1]*inv,data[o+2]*inv,data[o+3]*inv,alpha],o);\n else if(kind==='position')data.set([data[o]*inv,data[o+1]*inv,data[o+2]*inv,alpha],o);\n else{const count=data[o+3],scale=count>0?1/count:0;data.set([data[o]*scale,data[o+1]*scale,data[o+2]*scale,count/Math.max(1,this.samples)],o);}\n }\n return {width,height,data};\n }finally{framebuffer.dispose(this.renderer);}\n }\n get bytes(){return this.width*this.height*(2*64+64+(this.displayPass?4:0))+this.scene.width*this.scene.height*16;}\n dispose(){this.displayPass?.dispose();this.displayPass=undefined;const gl=this.renderer.gl;for(const set of this.accumulation)for(const texture of Object.values(set))texture.dispose(gl);this.accumulation.length=0;this.center?.id.dispose(gl);this.center?.motion.dispose(gl);this.center=undefined;this.previousCenter?.id.dispose(gl);this.previousCenter?.motion.dispose(gl);this.previousCenter=undefined;this.scene.dispose(gl);}\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { FragmentShader, ShaderDefineValue } from './shader.js';
2
- import { WebGLDevice, Texture2D, TextureOptions } from './webgl.js';
1
+ import { FragmentShader, type ShaderDefineValue } from './shader.js';
2
+ import { WebGLDevice, Texture2D, type TextureOptions } from './webgl.js';
3
3
  export interface WebGLFullQuadPassOutput extends TextureOptions {
4
4
  }
5
5
  export interface WebGLPassOptions {
@@ -25,7 +25,7 @@ export interface WebGLPassOptions {
25
25
  export declare class WebGLFullQuadPass<I extends string, O extends string> {
26
26
  private readonly _renderer;
27
27
  private _bindings;
28
- private readonly _sourceShader;
28
+ private _sourceShader;
29
29
  private readonly _outputs;
30
30
  private readonly _frameBuffer;
31
31
  private _outputTextures;
@@ -43,6 +43,7 @@ export declare class WebGLFullQuadPass<I extends string, O extends string> {
43
43
  outputs?: O[];
44
44
  outputParams?: Partial<Record<O, WebGLFullQuadPassOutput>>;
45
45
  });
46
+ setShader(shader: FragmentShader): void;
46
47
  reserveCapacity(): void;
47
48
  private _samplingShader;
48
49
  setSize(width: number, height: number): void;
@@ -56,9 +57,11 @@ export declare class WebGLFullQuadPass<I extends string, O extends string> {
56
57
  private readonly _retainedOutputs;
57
58
  retainOutput(texture: Texture2D): void;
58
59
  releaseOutput(texture: Texture2D): void;
60
+ loadDiagnosticOutputs(outputs: Partial<Record<O, Texture2D>>): void;
59
61
  getOutput(name: O): Record<O, Texture2D>[O];
60
62
  private _prepareOutputs;
61
- createPass(inputs: Record<I, Texture2D>, explicitOutputs?: Partial<Record<O, Texture2D>>, options?: WebGLPassOptions): void;
63
+ isProgramReady(inputs?: Record<I, Texture2D>): boolean;
64
+ createPass(inputs: Record<I, Texture2D>, explicitOutputs?: Partial<Record<O, Texture2D>>, options?: WebGLPassOptions): boolean;
62
65
  releaseTarget(target: object): void;
63
66
  getMemoryBytes(target?: object): number;
64
67
  dispose(): void;
@@ -37,6 +37,10 @@ export class WebGLFullQuadPass {
37
37
  options.outputParams?.[name] || {}
38
38
  ])));
39
39
  }
40
+ setShader(shader) {
41
+ this._sourceShader = shader;
42
+ this._bindings = new WebGLProgramBindings(this._samplingShader(shader, this._reserveCapacity, { ...shader.uniforms, ...this._bindings.uniforms }, this._bindings.defines));
43
+ }
40
44
  reserveCapacity() {
41
45
  if (this._reserveCapacity)
42
46
  return;
@@ -49,7 +53,7 @@ export class WebGLFullQuadPass {
49
53
  if (scratch)
50
54
  for (const name of textures)
51
55
  uniforms[`${name}RegionSize`] = { type: 'ivec2', value: [1, 1] };
52
- const sampled = new FragmentShader({ name: shader.name, outputs: shader.outputs, defines, uniforms,
56
+ const sampled = new FragmentShader({ name: shader.name, outputs: shader.outputs, outputTypes: shader.outputTypes, defines, uniforms,
53
57
  includes: [{ defines: {}, uniforms: {}, main: '', functions: [() => scratchGLSLFunctions(textures, scratch), ...shader.functions] }],
54
58
  main: shader.main });
55
59
  sampled.parallelCompile = shader.parallelCompile;
@@ -113,6 +117,13 @@ export class WebGLFullQuadPass {
113
117
  if (!Object.values(this._outputTextures).includes(texture))
114
118
  texture.dispose(this._renderer.gl);
115
119
  }
120
+ // Internal fixed-accumulation loader; transfer ownership to the selected target.
121
+ loadDiagnosticOutputs(outputs) {
122
+ for (const name of Object.keys(outputs)) {
123
+ this._outputTextures[name]?.dispose(this._renderer.gl);
124
+ this._outputTextures[name] = outputs[name];
125
+ }
126
+ }
116
127
  getOutput(name) {
117
128
  return this._outputTextures[name];
118
129
  }
@@ -132,6 +143,11 @@ export class WebGLFullQuadPass {
132
143
  setTextureRegion(texture, this._width, this._height);
133
144
  }
134
145
  }
146
+ isProgramReady(inputs) {
147
+ if (inputs)
148
+ this._bindings.setUniforms(inputs);
149
+ return this._renderer.isProgramCompiled(this._bindings.getProgram(this._renderer));
150
+ }
135
151
  createPass(inputs, explicitOutputs, options = {}) {
136
152
  const renderer = this._renderer;
137
153
  const gl = renderer.gl;
@@ -169,7 +185,10 @@ export class WebGLFullQuadPass {
169
185
  this.setUniform(`${name}RegionSize`, [region.width, region.height]);
170
186
  }
171
187
  this._bindings.setUniforms(inputs);
172
- this._bindings.bind(renderer);
188
+ if (!this._bindings.bind(renderer)) {
189
+ gl.disable(gl.SCISSOR_TEST);
190
+ return false;
191
+ }
173
192
  gl.disable(gl.DEPTH_TEST);
174
193
  if (options.blend) {
175
194
  gl.enable(gl.BLEND);
@@ -181,6 +200,7 @@ export class WebGLFullQuadPass {
181
200
  }
182
201
  gl.drawArrays(gl.TRIANGLES, 0, 3);
183
202
  gl.disable(gl.SCISSOR_TEST);
203
+ return true;
184
204
  }
185
205
  releaseTarget(target) {
186
206
  const outputs = this._targetOutputs.get(target);