@meimu/mutracer 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/LICENSES/FidelityFX-FSR.txt +19 -0
  3. package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
  4. package/README.md +3 -0
  5. package/THIRD_PARTY_NOTICES.md +18 -4
  6. package/dist/assets/bvh.worker.js +1 -1
  7. package/dist/mutracer.umd.js +9328 -7614
  8. package/docs/api.md +83 -35
  9. package/docs/caustics.md +80 -0
  10. package/docs/materials.md +9 -6
  11. package/docs/performance.md +7 -0
  12. package/docs/post-processing.md +62 -9
  13. package/docs/progressive-rendering.md +53 -9
  14. package/docs/sampling.md +4 -0
  15. package/docs/technical/acceleration.md +52 -0
  16. package/docs/technical/aovs.md +79 -0
  17. package/docs/technical/caustics.md +109 -0
  18. package/docs/technical/continuous-spectrum.md +122 -0
  19. package/docs/technical/display-upscale.md +82 -0
  20. package/docs/technical/openpbr.md +99 -0
  21. package/docs/technical/pbrt-import.md +168 -0
  22. package/docs/technical/tiling.md +74 -0
  23. package/docs/technical/webgl.md +53 -0
  24. package/docs/updates.md +3 -1
  25. package/docs/viewer-checklist.md +65 -0
  26. package/docs/viewer.md +18 -6
  27. package/lib/Display.d.ts +19 -5
  28. package/lib/Display.js +10 -7
  29. package/lib/Display.js.map +1 -1
  30. package/lib/Engine.d.ts +4 -1
  31. package/lib/Engine.js +77 -14
  32. package/lib/Engine.js.map +1 -1
  33. package/lib/Render.d.ts +81 -24
  34. package/lib/Render.js +201 -26
  35. package/lib/Render.js.map +1 -1
  36. package/lib/RenderLoop.d.ts +7 -3
  37. package/lib/RenderLoop.js +68 -44
  38. package/lib/RenderLoop.js.map +1 -1
  39. package/lib/main.d.ts +4 -2
  40. package/lib/main.js +1 -0
  41. package/lib/main.js.map +1 -1
  42. package/lib/oidn.d.ts +1 -1
  43. package/lib/renderer/AovPrimitiveCache.js +39 -8
  44. package/lib/renderer/AovPrimitiveCache.js.map +1 -1
  45. package/lib/renderer/DisplayPostProcess.d.ts +8 -3
  46. package/lib/renderer/DisplayPostProcess.js +51 -18
  47. package/lib/renderer/DisplayPostProcess.js.map +1 -1
  48. package/lib/renderer/GPUTraceQueue.d.ts +2 -1
  49. package/lib/renderer/GPUTraceQueue.js +3 -1
  50. package/lib/renderer/GPUTraceQueue.js.map +1 -1
  51. package/lib/renderer/MaterialData.js +7 -2
  52. package/lib/renderer/MaterialData.js.map +1 -1
  53. package/lib/renderer/RenderingPipeline.d.ts +11 -1
  54. package/lib/renderer/RenderingPipeline.js.map +1 -1
  55. package/lib/renderer/TileRender.d.ts +2 -2
  56. package/lib/renderer/TileRender.js +128 -7
  57. package/lib/renderer/TileRender.js.map +1 -1
  58. package/lib/renderer/WGPUAov.d.ts +6 -1
  59. package/lib/renderer/WGPUAov.js +108 -14
  60. package/lib/renderer/WGPUAov.js.map +1 -1
  61. package/lib/renderer/WGPUCanvasSurface.js +12 -1
  62. package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
  63. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  64. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  65. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  66. package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
  67. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  68. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  69. package/lib/renderer/WGPUPhotonMap.js +191 -0
  70. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  71. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  72. package/lib/renderer/WGPURayTraceOutput.js +122 -28
  73. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  74. package/lib/renderer/WGPURayTracePass.d.ts +65 -21
  75. package/lib/renderer/WGPURayTracePass.js +730 -409
  76. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  77. package/lib/renderer/WGPURenderingPipeline.js +110 -68
  78. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  79. package/lib/renderer/WebGLAov.js +3 -3
  80. package/lib/renderer/WebGLAov.js.map +1 -1
  81. package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
  82. package/lib/renderer/WebGLFullQuadPass.js +10 -0
  83. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  84. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  85. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  86. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  87. package/lib/renderer/WebGLRayTracePass.d.ts +20 -11
  88. package/lib/renderer/WebGLRayTracePass.js +157 -116
  89. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  90. package/lib/renderer/WebGLRenderingPipeline.js +17 -14
  91. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  92. package/lib/renderer/WebGLSkyBaker.js +60 -60
  93. package/lib/renderer/accumulationTarget.d.ts +2 -1
  94. package/lib/renderer/accumulationTarget.js.map +1 -1
  95. package/lib/renderer/aov.d.ts +13 -1
  96. package/lib/renderer/aov.js +21 -2
  97. package/lib/renderer/aov.js.map +1 -1
  98. package/lib/renderer/aovDisplay.js +2 -2
  99. package/lib/renderer/aovDisplay.js.map +1 -1
  100. package/lib/renderer/binnedSahBvh.d.ts +2 -1
  101. package/lib/renderer/binnedSahBvh.js +24 -17
  102. package/lib/renderer/binnedSahBvh.js.map +1 -1
  103. package/lib/renderer/bvhAccel.d.ts +3 -1
  104. package/lib/renderer/bvhAccel.js +36 -6
  105. package/lib/renderer/bvhAccel.js.map +1 -1
  106. package/lib/renderer/cameraUniform.d.ts +1 -1
  107. package/lib/renderer/cameraUniform.js +6 -2
  108. package/lib/renderer/cameraUniform.js.map +1 -1
  109. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  110. package/lib/renderer/causticDiagnostics.js +5 -0
  111. package/lib/renderer/causticDiagnostics.js.map +1 -0
  112. package/lib/renderer/causticEmission.d.ts +10 -0
  113. package/lib/renderer/causticEmission.js +40 -0
  114. package/lib/renderer/causticEmission.js.map +1 -0
  115. package/lib/renderer/causticUniform.d.ts +12 -0
  116. package/lib/renderer/causticUniform.js +22 -0
  117. package/lib/renderer/causticUniform.js.map +1 -0
  118. package/lib/renderer/caustics.d.ts +16 -0
  119. package/lib/renderer/caustics.js +93 -0
  120. package/lib/renderer/caustics.js.map +1 -0
  121. package/lib/renderer/compactVertices.d.ts +14 -0
  122. package/lib/renderer/compactVertices.js +124 -0
  123. package/lib/renderer/compactVertices.js.map +1 -0
  124. package/lib/renderer/easu.d.ts +11 -0
  125. package/lib/renderer/easu.js +156 -0
  126. package/lib/renderer/easu.js.map +1 -0
  127. package/lib/renderer/geometryUpdateState.d.ts +1 -0
  128. package/lib/renderer/geometryUpdateState.js.map +1 -1
  129. package/lib/renderer/geometryUpdates.js +3 -2
  130. package/lib/renderer/geometryUpdates.js.map +1 -1
  131. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  132. package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
  133. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  134. package/lib/renderer/glsl/aovTrace.frag.js +45 -37
  135. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
  136. package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
  137. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
  138. package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
  139. package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
  140. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
  141. package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
  142. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  143. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  144. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  145. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
  146. package/lib/renderer/glsl/chunks/intersect.glsl.js +478 -465
  147. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  148. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  149. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
  150. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  151. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
  152. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  153. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  154. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  155. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +70 -63
  156. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  157. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +89 -75
  158. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  159. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  160. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +160 -118
  161. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  162. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
  163. package/lib/renderer/glsl/chunks/sampling.glsl.js +88 -91
  164. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  165. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  166. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
  167. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
  168. package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
  169. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  170. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  171. package/lib/renderer/glsl/depthQuery.frag.js +13 -7
  172. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
  173. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  174. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  175. package/lib/renderer/glsl/rayTrace.frag.js +338 -252
  176. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  177. package/lib/renderer/glsl/shadowCatcher.frag.js +27 -26
  178. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  179. package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
  180. package/lib/renderer/gpuMemory.js +1 -1
  181. package/lib/renderer/gpuMemory.js.map +1 -1
  182. package/lib/renderer/lightSampling.d.ts +3 -2
  183. package/lib/renderer/lightSampling.js +14 -8
  184. package/lib/renderer/lightSampling.js.map +1 -1
  185. package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
  186. package/lib/renderer/openPbrEnergyLut.js +18 -1
  187. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  188. package/lib/renderer/pathLimits.d.ts +5 -4
  189. package/lib/renderer/pathLimits.js +6 -5
  190. package/lib/renderer/pathLimits.js.map +1 -1
  191. package/lib/renderer/prepareMeshBVH.d.ts +2 -0
  192. package/lib/renderer/prepareMeshBVH.js +5 -3
  193. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  194. package/lib/renderer/progressiveScheduler.js +5 -4
  195. package/lib/renderer/progressiveScheduler.js.map +1 -1
  196. package/lib/renderer/renderPipeline.d.ts +5 -0
  197. package/lib/renderer/renderPipeline.js +1 -0
  198. package/lib/renderer/renderPipeline.js.map +1 -1
  199. package/lib/renderer/researchTransport.d.ts +31 -0
  200. package/lib/renderer/researchTransport.js +5 -0
  201. package/lib/renderer/researchTransport.js.map +1 -0
  202. package/lib/renderer/sceneAssembly.d.ts +1 -1
  203. package/lib/renderer/sceneAssembly.js +4 -3
  204. package/lib/renderer/sceneAssembly.js.map +1 -1
  205. package/lib/renderer/sceneChangeDetector.d.ts +1 -1
  206. package/lib/renderer/sceneChangeDetector.js +3 -1
  207. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  208. package/lib/renderer/sceneLayoutSchema.d.ts +2 -0
  209. package/lib/renderer/sceneLayoutSchema.js +3 -3
  210. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  211. package/lib/renderer/scenePreparation.d.ts +3 -2
  212. package/lib/renderer/scenePreparation.js +18 -2
  213. package/lib/renderer/scenePreparation.js.map +1 -1
  214. package/lib/renderer/scratchSampling.js +6 -6
  215. package/lib/renderer/spectrum.d.ts +21 -0
  216. package/lib/renderer/spectrum.js +154 -0
  217. package/lib/renderer/spectrum.js.map +1 -0
  218. package/lib/renderer/staticBvhPreparation.d.ts +9 -0
  219. package/lib/renderer/staticBvhPreparation.js +8 -2
  220. package/lib/renderer/staticBvhPreparation.js.map +1 -1
  221. package/lib/renderer/surfaceHit.d.ts +10 -0
  222. package/lib/renderer/surfaceHit.js +22 -0
  223. package/lib/renderer/surfaceHit.js.map +1 -0
  224. package/lib/renderer/tangentRequirements.d.ts +2 -0
  225. package/lib/renderer/tangentRequirements.js +7 -0
  226. package/lib/renderer/tangentRequirements.js.map +1 -0
  227. package/lib/renderer/textureAtlas.d.ts +4 -0
  228. package/lib/renderer/textureAtlas.js +48 -2
  229. package/lib/renderer/textureAtlas.js.map +1 -1
  230. package/lib/renderer/webgl.js +4 -0
  231. package/lib/renderer/webgl.js.map +1 -1
  232. package/lib/renderer/webglLightSampling.d.ts +39 -0
  233. package/lib/renderer/webglLightSampling.js +15 -0
  234. package/lib/renderer/webglLightSampling.js.map +1 -0
  235. package/lib/renderer/webglVertexAttributes.d.ts +17 -0
  236. package/lib/renderer/webglVertexAttributes.js +44 -0
  237. package/lib/renderer/webglVertexAttributes.js.map +1 -0
  238. package/lib/renderer/wgpuBindlessSource.js +3 -3
  239. package/lib/renderer/wgpuMaterialConstants.js +4 -3
  240. package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
  241. package/lib/renderer/wgpuSceneUniform.js +2 -2
  242. package/lib/renderer/wgpuSceneUniform.js.map +1 -1
  243. package/lib/renderer/wgpuShaderSource.d.ts +22 -0
  244. package/lib/renderer/wgpuShaderSource.js +3 -1
  245. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  246. package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
  247. package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
  248. package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
  249. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  250. package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
  251. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  252. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
  253. package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
  254. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
  255. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
  256. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
  257. package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
  258. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
  259. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
  260. package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
  261. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  262. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  263. package/lib/renderer/wgsl/causticLight.compute.js +539 -0
  264. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  265. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  266. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  267. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  268. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  269. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  270. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  271. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  272. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  273. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  274. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  275. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  276. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  277. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  278. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
  279. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
  280. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +634 -620
  281. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  282. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
  283. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +23 -21
  284. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  285. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +3 -1
  286. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +77 -74
  287. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  288. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +795 -795
  289. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
  290. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  291. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -1
  292. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +45 -29
  293. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  294. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  295. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
  296. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  297. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  298. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +228 -189
  299. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  300. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  301. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
  302. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  303. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  304. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +88 -92
  305. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  306. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  307. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
  308. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
  309. package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
  310. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  311. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
  312. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
  313. package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
  314. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
  315. package/lib/renderer/wgsl/compose.frag.wgsl.js +100 -98
  316. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  317. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  318. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
  319. package/lib/renderer/wgsl/depthQuery.wgsl.js +12 -3
  320. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
  321. package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
  322. package/lib/renderer/wgsl/easu.wgsl.js +80 -0
  323. package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
  324. package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
  325. package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
  326. package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
  327. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  328. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
  329. package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
  330. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  331. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  332. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  333. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  334. package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
  335. package/lib/renderer/wgsl/rayTrace.compute.d.ts +23 -1
  336. package/lib/renderer/wgsl/rayTrace.compute.js +531 -543
  337. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  338. package/lib/scene/MaterialState.d.ts +2 -2
  339. package/lib/scene/MaterialState.js +2 -2
  340. package/lib/scene/MaterialState.js.map +1 -1
  341. package/lib/scene/Scene.js.map +1 -1
  342. package/lib/settings/render.d.ts +22 -0
  343. package/lib/settings/render.js +2 -0
  344. package/lib/settings/render.js.map +1 -1
  345. package/lib/util/fromTHREE.js +23 -16
  346. package/lib/util/fromTHREE.js.map +1 -1
  347. package/lib/version.d.ts +1 -1
  348. package/lib/version.js +1 -1
  349. package/lib/version.js.map +1 -1
  350. package/llms.txt +2 -1
  351. package/package.json +7 -4
  352. package/lib/oidnBundledWeights.cdn.d.ts +0 -2
  353. package/lib/oidnBundledWeights.cdn.js +0 -5
  354. package/lib/oidnBundledWeights.cdn.js.map +0 -1
  355. package/lib/renderer/bvh.worker.d.ts +0 -1
  356. package/lib/renderer/bvh.worker.js +0 -16
  357. package/lib/renderer/bvh.worker.js.map +0 -1
  358. package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
  359. package/lib/renderer/bvhWorkerBuild.js +0 -17
  360. package/lib/renderer/bvhWorkerBuild.js.map +0 -1
  361. package/lib/renderer/lightCore.d.ts +0 -12
  362. package/lib/renderer/lightCore.js +0 -13
  363. package/lib/renderer/lightCore.js.map +0 -1
  364. package/lib/renderer/materialCore.d.ts +0 -8
  365. package/lib/renderer/materialCore.js +0 -9
  366. package/lib/renderer/materialCore.js.map +0 -1
  367. package/lib/scene/PixelTexture.d.ts +0 -6
  368. package/lib/scene/PixelTexture.js +0 -10
  369. package/lib/scene/PixelTexture.js.map +0 -1
  370. package/lib/util/studioLighting.d.ts +0 -18
  371. package/lib/util/studioLighting.js +0 -36
  372. package/lib/util/studioLighting.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"aov.js","sourceRoot":"","sources":["../../src/renderer/aov.ts"],"names":[],"mappings":"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","sourcesContent":["/** Optional primary-surface outputs, separate from beauty and OIDN guides. */\nexport type AovKind = 'depth' | 'position' | 'roughness' | 'diffuseAlbedo' | 'specularAlbedo' | 'id' | 'motion';\nexport const AOV_KINDS: readonly AovKind[] = ['depth', 'position', 'roughness', 'diffuseAlbedo', 'specularAlbedo', 'id', 'motion'];\nexport const AOV_BACKGROUND_ID = 0xffffffff;\n// Four vec4 lanes for accumulated geometry/reflectance; two for center ID/motion.\n// Depth and roughness share a lane; coverage is position.w.\nexport const AOV_LAYOUT = {accumulatedBytes: 64, centerBytes: 32,\n depthRoughness: 0, position: 4, diffuseAlbedo: 8, specularAlbedo: 12,\n id: 0, motion: 4} as const;\nlet nextId = 0;\nexport function allocateAovId(): number {\n if (nextId >= AOV_BACKGROUND_ID) throw new RangeError('AOV ID space exhausted');\n return nextId++;\n}\nexport function validateAovId(value: number): number {\n if (!Number.isInteger(value) || value < 0 || value >= AOV_BACKGROUND_ID) throw new RangeError('AOV ID must be uint32 excluding 0xFFFFFFFF');\n return value;\n}\nexport function aovMask(kinds: readonly AovKind[]): number {\n let mask = 0;\n for (const kind of kinds) {\n const index = AOV_KINDS.indexOf(kind);\n if (index < 0) throw new RangeError(`Unknown AOV: ${kind}`);\n mask |= 1 << index;\n }\n return mask;\n}\nexport interface AovInstanceSnapshot {\n object: number; instance: number; topology: number; vertices: number;\n transform: Float32Array;\n}\nexport interface AovFrameSnapshot {\n width: number; height: number; projection: string;\n cameraEye?: Float32Array; cameraForward?: Float32Array;\n viewProjection: Float32Array; instances: readonly AovInstanceSnapshot[];\n}\n/** Per-render history; camera pose and rigid transforms may change without resetting. */\nexport class AovHistory {\n private frame?: AovFrameSnapshot;\n private instances=new Map<string,AovInstanceSnapshot>();\n clear() { this.frame = undefined; this.instances.clear(); }\n previous(next: AovFrameSnapshot): AovFrameSnapshot | undefined {\n const old = this.frame;\n return old && old.width === next.width && old.height === next.height && old.projection === next.projection ? old : undefined;\n }\n match(next: AovFrameSnapshot, instance: AovInstanceSnapshot): AovInstanceSnapshot | undefined {\n const old = this.previous(next) ? this.instances.get(`${instance.object}:${instance.instance}`) : undefined;\n return old && old.topology === instance.topology && old.vertices === instance.vertices ? old : undefined;\n }\n accept(frame: AovFrameSnapshot) {\n this.frame = {...frame, cameraEye: frame.cameraEye?.slice(), cameraForward: frame.cameraForward?.slice(), viewProjection: frame.viewProjection.slice(),\n instances: frame.instances.map(i => ({...i, transform: i.transform.slice()}))};\n this.instances.clear();\n for (const instance of this.frame.instances) this.instances.set(`${instance.object}:${instance.instance}`,instance);\n }\n}\n"]}
1
+ {"version":3,"file":"aov.js","sourceRoot":"","sources":["../../src/renderer/aov.ts"],"names":[],"mappings":"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","sourcesContent":["/** Optional primary-surface outputs, separate from beauty and OIDN guides. */\nexport type AovKind = 'depth' | 'position' | 'roughness' | 'diffuseAlbedo' | 'specularAlbedo' | 'id' | 'motion' | 'diffuseColor' | 'specularColor';\nexport const AOV_KINDS: readonly AovKind[] = ['depth', 'position', 'roughness', 'diffuseAlbedo', 'specularAlbedo', 'id', 'motion', 'diffuseColor', 'specularColor'];\nexport const AOV_BACKGROUND_ID = 0xffffffff;\n/** Display-resolution AOVs only guide texture detail; 4 jittered samples match 16 within measurement noise. */\nexport const DISPLAY_AOV_SAMPLE_CAP = 4;\n/** Mask bits of directional reflectance quadrature (diffuseAlbedo, specularAlbedo). */\nexport const AOV_REFLECTANCE_MASK = 24;\n/** Mask bits of resolved texture colors (diffuseColor, specularColor). */\nexport const AOV_COLOR_MASK = 384;\n/** Mask bits of kinds accumulated over jittered samples. */\nexport const AOV_ACCUMULATED_MASK = 31 | AOV_COLOR_MASK;\n/** Kinds that fit the compact display-resolution storage. */\nexport const COMPACT_AOV_KINDS: readonly AovKind[] = ['depth', 'diffuseColor', 'specularColor'];\n// Four vec4 lanes for accumulated geometry/reflectance; two for center ID/motion.\n// Depth and roughness share a lane; coverage is position.w. A lobe's albedo and\n// color share its reflectance lane, so a render requests at most one of them.\nexport const AOV_LAYOUT = {accumulatedBytes: 64, centerBytes: 32,\n depthRoughness: 0, position: 4, diffuseAlbedo: 8, specularAlbedo: 12,\n id: 0, motion: 4} as const;\n/** Kind index read by resolve and display shaders; colors resolve like the albedo sharing their lane. */\nexport function aovLaneKind(kind: AovKind): number {\n return kind === 'diffuseColor' ? 3 : kind === 'specularColor' ? 4 : AOV_KINDS.indexOf(kind);\n}\nlet nextId = 0;\nexport function allocateAovId(): number {\n if (nextId >= AOV_BACKGROUND_ID) throw new RangeError('AOV ID space exhausted');\n return nextId++;\n}\nexport function validateAovId(value: number): number {\n if (!Number.isInteger(value) || value < 0 || value >= AOV_BACKGROUND_ID) throw new RangeError('AOV ID must be uint32 excluding 0xFFFFFFFF');\n return value;\n}\nexport function aovMask(kinds: readonly AovKind[]): number {\n let mask = 0;\n for (const kind of kinds) {\n const index = AOV_KINDS.indexOf(kind);\n if (index < 0) throw new RangeError(`Unknown AOV: ${kind}`);\n mask |= 1 << index;\n }\n if ((mask & 8) && (mask & 128)) throw new RangeError('diffuseAlbedo and diffuseColor cannot be requested together');\n if ((mask & 16) && (mask & 256)) throw new RangeError('specularAlbedo and specularColor cannot be requested together');\n return mask;\n}\nexport interface AovInstanceSnapshot {\n object: number; instance: number; topology: number; vertices: number;\n transform: Float32Array;\n}\nexport interface AovFrameSnapshot {\n width: number; height: number; projection: string;\n cameraEye?: Float32Array; cameraForward?: Float32Array;\n viewProjection: Float32Array; instances: readonly AovInstanceSnapshot[];\n}\n/** Per-render history; camera pose and rigid transforms may change without resetting. */\nexport class AovHistory {\n private frame?: AovFrameSnapshot;\n private instances=new Map<string,AovInstanceSnapshot>();\n clear() { this.frame = undefined; this.instances.clear(); }\n previous(next: AovFrameSnapshot): AovFrameSnapshot | undefined {\n const old = this.frame;\n return old && old.width === next.width && old.height === next.height && old.projection === next.projection ? old : undefined;\n }\n match(next: AovFrameSnapshot, instance: AovInstanceSnapshot): AovInstanceSnapshot | undefined {\n const old = this.previous(next) ? this.instances.get(`${instance.object}:${instance.instance}`) : undefined;\n return old && old.topology === instance.topology && old.vertices === instance.vertices ? old : undefined;\n }\n accept(frame: AovFrameSnapshot) {\n this.frame = {...frame, cameraEye: frame.cameraEye?.slice(), cameraForward: frame.cameraForward?.slice(), viewProjection: frame.viewProjection.slice(),\n instances: frame.instances.map(i => ({...i, transform: i.transform.slice()}))};\n this.instances.clear();\n for (const instance of this.frame.instances) this.instances.set(`${instance.object}:${instance.instance}`,instance);\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { AOV_KINDS } from './aov.js';
1
+ import { AOV_KINDS, aovLaneKind } from './aov.js';
2
2
  export const DEFAULT_AOV_DISPLAY = {
3
3
  depthRange: [0, 10], positionScale: 1, motionScale: 16, idComponent: 'object'
4
4
  };
@@ -23,7 +23,7 @@ export function validateAovDisplay(options) {
23
23
  export function packAovDisplay(width, height, samples, kind, options, linear) {
24
24
  validateAovDisplay(options);
25
25
  const words = new Uint32Array(12), floats = new Float32Array(words.buffer);
26
- words.set([width, height, samples, AOV_KINDS.indexOf(kind)]);
26
+ words.set([width, height, samples, aovLaneKind(kind)]);
27
27
  floats.set([...options.depthRange, options.positionScale, options.motionScale], 4);
28
28
  words[8] = AOV_ID_COMPONENTS.indexOf(options.idComponent);
29
29
  words[9] = +linear;
@@ -1 +1 @@
1
- {"version":3,"file":"aovDisplay.js","sourceRoot":"","sources":["../../src/renderer/aovDisplay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,UAAU,CAAC;AASnD,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ;CAC9E,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAA8B,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAC5G,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;AAClD,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,OAA0B;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QACtH,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClG,MAAM,IAAI,UAAU,CAAC,4DAA4D,CAAC,CAAC;IACrF,KAAK,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/F,MAAM,IAAI,UAAU,CAAC,2DAA2D,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC;QAClD,MAAM,IAAI,UAAU,CAAC,0BAA0B,CAAC,CAAC;AACrD,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,MAAc,EAAE,OAAe,EAAE,IAAa,EAAE,OAA0B,EAAE,MAAe;IACvI,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3E,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IACnB,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { AOV_KINDS, type AovKind } from './aov.js';\n/** ID lane to visualize. Default object. */\nexport type AovIdComponent = 'object' | 'instance' | 'material' | 'primitive';\nexport interface AovDisplayOptions {\n depthRange: readonly [number, number];\n positionScale: number;\n motionScale: number;\n idComponent: AovIdComponent;\n}\nexport const DEFAULT_AOV_DISPLAY: AovDisplayOptions = {\n depthRange: [0, 10], positionScale: 1, motionScale: 16, idComponent: 'object'\n};\nexport const AOV_ID_COMPONENTS: readonly AovIdComponent[] = ['object', 'instance', 'material', 'primitive'];\nexport function displayAovKind(channel: string): AovKind | undefined {\n return AOV_KINDS.find(kind => kind === channel);\n}\nexport function validateAovDisplay(options: AovDisplayOptions) {\n const range = options.depthRange;\n if (!Array.isArray(range) || range.length !== 2 || !range.every(Number.isFinite) || range[0] < 0 || range[1] <= range[0])\n throw new RangeError('aovDepthRange requires 0 <= near < far');\n if (!range.map(Math.fround).every(Number.isFinite) || Math.fround(range[1]) <= Math.fround(range[0]))\n throw new RangeError('aovDepthRange must remain finite and increasing in float32');\n for (const scale of [options.positionScale, options.motionScale]) {\n if (!Number.isFinite(scale) || !Number.isFinite(Math.fround(scale)) || Math.fround(scale) <= 0) {\n throw new RangeError('AOV display scales must be finite and positive in float32');\n }\n }\n if (!AOV_ID_COMPONENTS.includes(options.idComponent))\n throw new RangeError('Unknown AOV ID component');\n}\nexport function packAovDisplay(width: number, height: number, samples: number, kind: AovKind, options: AovDisplayOptions, linear: boolean) {\n validateAovDisplay(options);\n const words = new Uint32Array(12), floats = new Float32Array(words.buffer);\n words.set([width, height, samples, AOV_KINDS.indexOf(kind)]);\n floats.set([...options.depthRange, options.positionScale, options.motionScale], 4);\n words[8] = AOV_ID_COMPONENTS.indexOf(options.idComponent);\n words[9] = +linear;\n return words;\n}\n"]}
1
+ {"version":3,"file":"aovDisplay.js","sourceRoot":"","sources":["../../src/renderer/aovDisplay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAgB,MAAM,UAAU,CAAC;AAShE,MAAM,CAAC,MAAM,mBAAmB,GAAsB;IACpD,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ;CAC9E,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAA8B,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAC5G,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;AAClD,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAC,OAA0B;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QACtH,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClG,MAAM,IAAI,UAAU,CAAC,4DAA4D,CAAC,CAAC;IACrF,KAAK,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/F,MAAM,IAAI,UAAU,CAAC,2DAA2D,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC;QAClD,MAAM,IAAI,UAAU,CAAC,0BAA0B,CAAC,CAAC;AACrD,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,MAAc,EAAE,OAAe,EAAE,IAAa,EAAE,OAA0B,EAAE,MAAe;IACvI,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3E,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IACnB,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { AOV_KINDS, aovLaneKind, type AovKind } from './aov.js';\n/** ID lane to visualize. Default object. */\nexport type AovIdComponent = 'object' | 'instance' | 'material' | 'primitive';\nexport interface AovDisplayOptions {\n depthRange: readonly [number, number];\n positionScale: number;\n motionScale: number;\n idComponent: AovIdComponent;\n}\nexport const DEFAULT_AOV_DISPLAY: AovDisplayOptions = {\n depthRange: [0, 10], positionScale: 1, motionScale: 16, idComponent: 'object'\n};\nexport const AOV_ID_COMPONENTS: readonly AovIdComponent[] = ['object', 'instance', 'material', 'primitive'];\nexport function displayAovKind(channel: string): AovKind | undefined {\n return AOV_KINDS.find(kind => kind === channel);\n}\nexport function validateAovDisplay(options: AovDisplayOptions) {\n const range = options.depthRange;\n if (!Array.isArray(range) || range.length !== 2 || !range.every(Number.isFinite) || range[0] < 0 || range[1] <= range[0])\n throw new RangeError('aovDepthRange requires 0 <= near < far');\n if (!range.map(Math.fround).every(Number.isFinite) || Math.fround(range[1]) <= Math.fround(range[0]))\n throw new RangeError('aovDepthRange must remain finite and increasing in float32');\n for (const scale of [options.positionScale, options.motionScale]) {\n if (!Number.isFinite(scale) || !Number.isFinite(Math.fround(scale)) || Math.fround(scale) <= 0) {\n throw new RangeError('AOV display scales must be finite and positive in float32');\n }\n }\n if (!AOV_ID_COMPONENTS.includes(options.idComponent))\n throw new RangeError('Unknown AOV ID component');\n}\nexport function packAovDisplay(width: number, height: number, samples: number, kind: AovKind, options: AovDisplayOptions, linear: boolean) {\n validateAovDisplay(options);\n const words = new Uint32Array(12), floats = new Float32Array(words.buffer);\n words.set([width, height, samples, aovLaneKind(kind)]);\n floats.set([...options.depthRange, options.positionScale, options.motionScale], 4);\n words[8] = AOV_ID_COMPONENTS.indexOf(options.idComponent);\n words[9] = +linear;\n return words;\n}\n"]}
@@ -13,8 +13,9 @@ export interface BinnedSahBvh {
13
13
  * Builds a binary BVH over axis-aligned boxes.
14
14
  * @param aabbs min x, y, z, max x, y, z for each primitive.
15
15
  * @param count number of primitives in `aabbs`.
16
+ * @param bins SAH resolution; default 8 retains the shared/native build contract.
16
17
  */
17
- export declare function buildBinnedSahBvh(aabbs: Float32Array, count: number): BinnedSahBvh;
18
+ export declare function buildBinnedSahBvh(aabbs: Float32Array, count: number, bins?: number): BinnedSahBvh;
18
19
  export interface Bvh2Layout {
19
20
  /** Node indices in depth-first order (node, left subtree, right subtree). */
20
21
  order: Uint32Array;
@@ -4,7 +4,7 @@
4
4
  // Copyright (c) 2024-2026 Jacco Bikker / Breda University of Applied Sciences.
5
5
  // MIT License, see src/tinybvh/LICENSE.
6
6
  //
7
- // Like the reference, it bins primitive centroids into 8 bins on all three
7
+ // By default, like the reference, it bins primitive centroids into 8 bins on all three
8
8
  // axes, sweeps the bins for the lowest surface area heuristic cost and stops
9
9
  // splitting when a leaf is cheaper (C_INT = C_TRAV = 1). Siblings are stored
10
10
  // next to each other: an interior node's children are leftFirst and
@@ -18,21 +18,21 @@ const C_INT = 1;
18
18
  const C_TRAV = 1;
19
19
  const FAR = 1e30;
20
20
  // Scratch shared by all builds; the builder is synchronous.
21
- const binMin = new Float64Array(3 * BINS * 3);
22
- const binMax = new Float64Array(3 * BINS * 3);
23
- const binCount = new Uint32Array(3 * BINS);
21
+ const defaultBinMin = new Float64Array(3 * BINS * 3);
22
+ const defaultBinMax = new Float64Array(3 * BINS * 3);
23
+ const defaultBinCount = new Uint32Array(3 * BINS);
24
24
  // Per split position: half area times primitive count of each side.
25
- const leftCost = new Float64Array(BINS - 1);
26
- const rightCost = new Float64Array(BINS - 1);
25
+ const defaultLeftCost = new Float64Array(BINS - 1);
26
+ const defaultRightCost = new Float64Array(BINS - 1);
27
27
  /**
28
28
  * Bin of a centroid along one axis. Binning and partitioning both use this,
29
29
  * so every primitive ends up on the side whose bounds include its bin.
30
30
  */
31
- function binOf(center, nodeMin, scale) {
31
+ function binOf(center, nodeMin, scale, bins) {
32
32
  const bin = ((center - nodeMin) * scale) | 0;
33
- return bin < 0 ? 0 : bin > BINS - 1 ? BINS - 1 : bin;
33
+ return bin < 0 ? 0 : bin > bins - 1 ? bins - 1 : bin;
34
34
  }
35
- function growBin(o, minX, minY, minZ, maxX, maxY, maxZ) {
35
+ function growBin(binMin, binMax, o, minX, minY, minZ, maxX, maxY, maxZ) {
36
36
  binMin[o] = Math.min(binMin[o], minX);
37
37
  binMin[o + 1] = Math.min(binMin[o + 1], minY);
38
38
  binMin[o + 2] = Math.min(binMin[o + 2], minZ);
@@ -44,8 +44,15 @@ function growBin(o, minX, minY, minZ, maxX, maxY, maxZ) {
44
44
  * Builds a binary BVH over axis-aligned boxes.
45
45
  * @param aabbs min x, y, z, max x, y, z for each primitive.
46
46
  * @param count number of primitives in `aabbs`.
47
+ * @param bins SAH resolution; default 8 retains the shared/native build contract.
47
48
  */
48
- export function buildBinnedSahBvh(aabbs, count) {
49
+ export function buildBinnedSahBvh(aabbs, count, bins = BINS) {
50
+ const BINS = bins;
51
+ const binMin = bins === 8 ? defaultBinMin : new Float64Array(3 * bins * 3);
52
+ const binMax = bins === 8 ? defaultBinMax : new Float64Array(3 * bins * 3);
53
+ const binCount = bins === 8 ? defaultBinCount : new Uint32Array(3 * bins);
54
+ const leftCost = bins === 8 ? defaultLeftCost : new Float64Array(bins - 1);
55
+ const rightCost = bins === 8 ? defaultRightCost : new Float64Array(bins - 1);
49
56
  const capacity = Math.max(1, count * 2 - 1);
50
57
  const bounds = new Float32Array(capacity * 6);
51
58
  const leftFirst = new Uint32Array(capacity);
@@ -121,15 +128,15 @@ export function buildBinnedSahBvh(aabbs, count) {
121
128
  const minX = aabbs[b], minY = aabbs[b + 1], minZ = aabbs[b + 2];
122
129
  const maxX = aabbs[b + 3], maxY = aabbs[b + 4], maxZ = aabbs[b + 5];
123
130
  // Axis a, bin i: bounds at ((a * BINS) + i) * 3.
124
- const bx = binOf(centers[c], nMinX, scaleX);
125
- const by = BINS + binOf(centers[c + 1], nMinY, scaleY);
126
- const bz = 2 * BINS + binOf(centers[c + 2], nMinZ, scaleZ);
131
+ const bx = binOf(centers[c], nMinX, scaleX, BINS);
132
+ const by = BINS + binOf(centers[c + 1], nMinY, scaleY, BINS);
133
+ const bz = 2 * BINS + binOf(centers[c + 2], nMinZ, scaleZ, BINS);
127
134
  binCount[bx]++;
128
135
  binCount[by]++;
129
136
  binCount[bz]++;
130
- growBin(bx * 3, minX, minY, minZ, maxX, maxY, maxZ);
131
- growBin(by * 3, minX, minY, minZ, maxX, maxY, maxZ);
132
- growBin(bz * 3, minX, minY, minZ, maxX, maxY, maxZ);
137
+ growBin(binMin, binMax, bx * 3, minX, minY, minZ, maxX, maxY, maxZ);
138
+ growBin(binMin, binMax, by * 3, minX, minY, minZ, maxX, maxY, maxZ);
139
+ growBin(binMin, binMax, bz * 3, minX, minY, minZ, maxX, maxY, maxZ);
133
140
  }
134
141
  // Sweep the bins of each axis for the lowest split cost.
135
142
  let splitCost = FAR;
@@ -183,7 +190,7 @@ export function buildBinnedSahBvh(aabbs, count) {
183
190
  let j = first + nodePrims, src = first;
184
191
  for (let i = 0; i < nodePrims; i++) {
185
192
  const p = primIndices[src];
186
- if (binOf(centers[p * 3 + bestAxis], nMin, scale) <= bestPos) {
193
+ if (binOf(centers[p * 3 + bestAxis], nMin, scale, BINS) <= bestPos) {
187
194
  src++;
188
195
  }
189
196
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"binnedSahBvh.js","sourceRoot":"","sources":["../../src/renderer/binnedSahBvh.ts"],"names":[],"mappings":"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","sourcesContent":["// Binned SAH BVH builder ported from TinyBVH's reference builder\n// (`BVH::Build( nodeIdx, depth )` in tiny_bvh.h at commit\n// 0e4584287823252cf83f0e9cd072848bec5f79c5, https://github.com/jbikker/tinybvh).\n// Copyright (c) 2024-2026 Jacco Bikker / Breda University of Applied Sciences.\n// MIT License, see src/tinybvh/LICENSE.\n//\n// Like the reference, it bins primitive centroids into 8 bins on all three\n// axes, sweeps the bins for the lowest surface area heuristic cost and stops\n// splitting when a leaf is cheaper (C_INT = C_TRAV = 1). Siblings are stored\n// next to each other: an interior node's children are leftFirst and\n// leftFirst + 1. Unlike the reference, node 1 is not left unused, the task\n// stack grows instead of turning a node into a leaf after 512 entries, and\n// arithmetic is float64: near-equal split costs can resolve differently from\n// TinyBVH's float32, giving trees of the same quality that are not\n// byte-identical.\n\nconst BINS = 8;\nconst C_INT = 1;\nconst C_TRAV = 1;\nconst FAR = 1e30;\n\nexport interface BinnedSahBvh {\n nodeCount: number;\n /** Per node: min x, y, z, max x, y, z. */\n bounds: Float32Array;\n /** Interior node: index of the left child. Leaf: first slot in primIndices. */\n leftFirst: Uint32Array;\n /** Primitive count of a leaf; 0 for interior nodes. */\n primCount: Uint32Array;\n /** Primitive indices referenced by leaves. */\n primIndices: Uint32Array;\n}\n\n// Scratch shared by all builds; the builder is synchronous.\nconst binMin = new Float64Array(3 * BINS * 3);\nconst binMax = new Float64Array(3 * BINS * 3);\nconst binCount = new Uint32Array(3 * BINS);\n// Per split position: half area times primitive count of each side.\nconst leftCost = new Float64Array(BINS - 1);\nconst rightCost = new Float64Array(BINS - 1);\n\n/**\n * Bin of a centroid along one axis. Binning and partitioning both use this,\n * so every primitive ends up on the side whose bounds include its bin.\n */\nfunction binOf(center: number, nodeMin: number, scale: number) {\n const bin = ((center - nodeMin) * scale) | 0;\n return bin < 0 ? 0 : bin > BINS - 1 ? BINS - 1 : bin;\n}\n\nfunction growBin(\n o: number,\n minX: number, minY: number, minZ: number,\n maxX: number, maxY: number, maxZ: number\n) {\n binMin[o] = Math.min(binMin[o], minX);\n binMin[o + 1] = Math.min(binMin[o + 1], minY);\n binMin[o + 2] = Math.min(binMin[o + 2], minZ);\n binMax[o] = Math.max(binMax[o], maxX);\n binMax[o + 1] = Math.max(binMax[o + 1], maxY);\n binMax[o + 2] = Math.max(binMax[o + 2], maxZ);\n}\n\n/**\n * Builds a binary BVH over axis-aligned boxes.\n * @param aabbs min x, y, z, max x, y, z for each primitive.\n * @param count number of primitives in `aabbs`.\n */\nexport function buildBinnedSahBvh(aabbs: Float32Array, count: number): BinnedSahBvh {\n const capacity = Math.max(1, count * 2 - 1);\n const bounds = new Float32Array(capacity * 6);\n const leftFirst = new Uint32Array(capacity);\n const primCount = new Uint32Array(capacity);\n const primIndices = new Uint32Array(count);\n if (count === 0) {\n return { nodeCount: 0, bounds, leftFirst, primCount, primIndices };\n }\n\n const centers = new Float32Array(count * 3);\n let rootMinX = FAR, rootMinY = FAR, rootMinZ = FAR;\n let rootMaxX = -FAR, rootMaxY = -FAR, rootMaxZ = -FAR;\n for (let i = 0; i < count; i++) {\n const b = i * 6, c = i * 3;\n const minX = aabbs[b], minY = aabbs[b + 1], minZ = aabbs[b + 2];\n const maxX = aabbs[b + 3], maxY = aabbs[b + 4], maxZ = aabbs[b + 5];\n centers[c] = (minX + maxX) * 0.5;\n centers[c + 1] = (minY + maxY) * 0.5;\n centers[c + 2] = (minZ + maxZ) * 0.5;\n if (minX < rootMinX) rootMinX = minX;\n if (minY < rootMinY) rootMinY = minY;\n if (minZ < rootMinZ) rootMinZ = minZ;\n if (maxX > rootMaxX) rootMaxX = maxX;\n if (maxY > rootMaxY) rootMaxY = maxY;\n if (maxZ > rootMaxZ) rootMaxZ = maxZ;\n primIndices[i] = i;\n }\n bounds[0] = rootMinX; bounds[1] = rootMinY; bounds[2] = rootMinZ;\n bounds[3] = rootMaxX; bounds[4] = rootMaxY; bounds[5] = rootMaxZ;\n leftFirst[0] = 0;\n primCount[0] = count;\n\n const minDimX = (rootMaxX - rootMinX) * 1e-20;\n const minDimY = (rootMaxY - rootMinY) * 1e-20;\n const minDimZ = (rootMaxZ - rootMinZ) * 1e-20;\n\n let newNode = 1;\n const tasks: number[] = [];\n let nodeIndex = 0;\n while (true) {\n while (true) {\n const nb = nodeIndex * 6;\n const nMinX = bounds[nb], nMinY = bounds[nb + 1], nMinZ = bounds[nb + 2];\n const extentX = bounds[nb + 3] - nMinX;\n const extentY = bounds[nb + 4] - nMinY;\n const extentZ = bounds[nb + 5] - nMinZ;\n const area = extentX * extentY + extentY * extentZ + extentZ * extentX;\n if (area === 0) break; // can't split an infinitely small node.\n\n const first = leftFirst[nodeIndex];\n const nodePrims = primCount[nodeIndex];\n // Every split of a single primitive leaves one side empty.\n if (nodePrims === 1) break;\n const scaleX = extentX > minDimX ? BINS / extentX : 0;\n const scaleY = extentY > minDimY ? BINS / extentY : 0;\n const scaleZ = extentZ > minDimZ ? BINS / extentZ : 0;\n\n for (let i = 0; i < 3 * BINS * 3; i++) {\n binMin[i] = FAR;\n binMax[i] = -FAR;\n }\n binCount.fill(0);\n for (let i = first, end = first + nodePrims; i < end; i++) {\n const p = primIndices[i];\n const c = p * 3, b = p * 6;\n const minX = aabbs[b], minY = aabbs[b + 1], minZ = aabbs[b + 2];\n const maxX = aabbs[b + 3], maxY = aabbs[b + 4], maxZ = aabbs[b + 5];\n // Axis a, bin i: bounds at ((a * BINS) + i) * 3.\n const bx = binOf(centers[c], nMinX, scaleX);\n const by = BINS + binOf(centers[c + 1], nMinY, scaleY);\n const bz = 2 * BINS + binOf(centers[c + 2], nMinZ, scaleZ);\n binCount[bx]++; binCount[by]++; binCount[bz]++;\n growBin(bx * 3, minX, minY, minZ, maxX, maxY, maxZ);\n growBin(by * 3, minX, minY, minZ, maxX, maxY, maxZ);\n growBin(bz * 3, minX, minY, minZ, maxX, maxY, maxZ);\n }\n\n // Sweep the bins of each axis for the lowest split cost.\n let splitCost = FAR;\n let bestAxis = 0, bestPos = 0;\n for (let axis = 0; axis < 3; axis++) {\n const extent = axis === 0 ? extentX : axis === 1 ? extentY : extentZ;\n const minDim = axis === 0 ? minDimX : axis === 1 ? minDimY : minDimZ;\n if (!(extent > minDim)) continue;\n let lMinX = FAR, lMinY = FAR, lMinZ = FAR, lMaxX = -FAR, lMaxY = -FAR, lMaxZ = -FAR;\n let rMinX = FAR, rMinY = FAR, rMinZ = FAR, rMaxX = -FAR, rMaxY = -FAR, rMaxZ = -FAR;\n let leftN = 0, rightN = 0;\n for (let i = 0; i < BINS - 1; i++) {\n const l = (axis * BINS + i) * 3;\n const r = (axis * BINS + BINS - 1 - i) * 3;\n lMinX = Math.min(lMinX, binMin[l]); lMinY = Math.min(lMinY, binMin[l + 1]); lMinZ = Math.min(lMinZ, binMin[l + 2]);\n lMaxX = Math.max(lMaxX, binMax[l]); lMaxY = Math.max(lMaxY, binMax[l + 1]); lMaxZ = Math.max(lMaxZ, binMax[l + 2]);\n rMinX = Math.min(rMinX, binMin[r]); rMinY = Math.min(rMinY, binMin[r + 1]); rMinZ = Math.min(rMinZ, binMin[r + 2]);\n rMaxX = Math.max(rMaxX, binMax[r]); rMaxY = Math.max(rMaxY, binMax[r + 1]); rMaxZ = Math.max(rMaxZ, binMax[r + 2]);\n leftN += binCount[axis * BINS + i];\n rightN += binCount[axis * BINS + BINS - 1 - i];\n const lx = lMaxX - lMinX, ly = lMaxY - lMinY, lz = lMaxZ - lMinZ;\n const rx = rMaxX - rMinX, ry = rMaxY - rMinY, rz = rMaxZ - rMinZ;\n leftCost[i] = leftN === 0 ? FAR : (lx * ly + ly * lz + lz * lx) * leftN;\n rightCost[BINS - 2 - i] = rightN === 0 ? FAR : (rx * ry + ry * rz + rz * rx) * rightN;\n }\n for (let i = 0; i < BINS - 1; i++) {\n const cost = leftCost[i] + rightCost[i];\n if (cost < splitCost) {\n splitCost = cost;\n bestAxis = axis;\n bestPos = i;\n }\n }\n }\n splitCost = C_TRAV + C_INT * splitCost / area;\n // Not splitting is better (also stops on non-finite bounds).\n if (!(splitCost < nodePrims * C_INT)) break;\n\n // In-place partition by the chosen bin.\n const scale = bestAxis === 0 ? scaleX : bestAxis === 1 ? scaleY : scaleZ;\n const nMin = bestAxis === 0 ? nMinX : bestAxis === 1 ? nMinY : nMinZ;\n let j = first + nodePrims, src = first;\n for (let i = 0; i < nodePrims; i++) {\n const p = primIndices[src];\n if (binOf(centers[p * 3 + bestAxis], nMin, scale) <= bestPos) {\n src++;\n } else {\n // Explicit numeric expression also supports scriptc typed-array stores.\n primIndices[src + 0] = primIndices[--j];\n primIndices[j] = p;\n }\n }\n const leftPrims = src - first;\n const rightPrims = nodePrims - leftPrims;\n if (leftPrims === 0 || rightPrims === 0) break; // should not happen.\n\n const n = newNode;\n newNode += 2;\n // Child bounds are the unions of the bins on each side of the split.\n const leftBase = n * 6, rightBase = leftBase + 6;\n for (let k = 0; k < 3; k++) {\n bounds[leftBase + k] = bounds[rightBase + k] = FAR;\n bounds[leftBase + 3 + k] = bounds[rightBase + 3 + k] = -FAR;\n }\n for (let i = 0; i < BINS; i++) {\n const o = (bestAxis * BINS + i) * 3;\n const base = i <= bestPos ? leftBase : rightBase;\n for (let k = 0; k < 3; k++) {\n if (binMin[o + k] < bounds[base + k]) bounds[base + k] = binMin[o + k];\n if (binMax[o + k] > bounds[base + 3 + k]) bounds[base + 3 + k] = binMax[o + k];\n }\n }\n leftFirst[n] = first; primCount[n] = leftPrims;\n leftFirst[n + 1] = j; primCount[n + 1] = rightPrims;\n leftFirst[nodeIndex] = n; primCount[nodeIndex] = 0;\n tasks.push(n + 1);\n nodeIndex = n;\n }\n if (!tasks.length) break;\n nodeIndex = tasks.pop()!;\n }\n\n return { nodeCount: newNode, bounds, leftFirst, primCount, primIndices };\n}\n\nexport interface Bvh2Layout {\n /** Node indices in depth-first order (node, left subtree, right subtree). */\n order: Uint32Array;\n /** Offset of each node in vec4 units: 2 per node plus 1 per leaf primitive. */\n offsets: Uint32Array;\n vec4Count: number;\n maxDepth: number;\n maxLeafPrimitives: number;\n}\n\n/**\n * Places nodes in the depth-first BVH2 layout read by the traversal shaders:\n * the left child follows its parent and leaf primitives follow their leaf.\n */\nexport function layoutBvh2(bvh: BinnedSahBvh): Bvh2Layout {\n const { nodeCount, leftFirst, primCount } = bvh;\n const order = new Uint32Array(nodeCount);\n const offsets = new Uint32Array(nodeCount);\n let vec4Count = 0, maxDepth = 0, maxLeafPrimitives = 0;\n if (!nodeCount) return { order, offsets, vec4Count, maxDepth, maxLeafPrimitives };\n const stack: number[] = [0, 1];\n let written = 0;\n while (stack.length) {\n const depth = stack.pop()!;\n const node = stack.pop()!;\n order[written++] = node;\n offsets[node] = vec4Count;\n if (depth > maxDepth) maxDepth = depth;\n const prims = primCount[node];\n vec4Count += 2 + prims;\n if (prims) {\n if (prims > maxLeafPrimitives) maxLeafPrimitives = prims;\n } else {\n stack.push(leftFirst[node] + 1, depth + 1, leftFirst[node], depth + 1);\n }\n }\n return { order, offsets, vec4Count, maxDepth, maxLeafPrimitives };\n}\n"]}
1
+ {"version":3,"file":"binnedSahBvh.js","sourceRoot":"","sources":["../../src/renderer/binnedSahBvh.ts"],"names":[],"mappings":"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","sourcesContent":["// Binned SAH BVH builder ported from TinyBVH's reference builder\n// (`BVH::Build( nodeIdx, depth )` in tiny_bvh.h at commit\n// 0e4584287823252cf83f0e9cd072848bec5f79c5, https://github.com/jbikker/tinybvh).\n// Copyright (c) 2024-2026 Jacco Bikker / Breda University of Applied Sciences.\n// MIT License, see src/tinybvh/LICENSE.\n//\n// By default, like the reference, it bins primitive centroids into 8 bins on all three\n// axes, sweeps the bins for the lowest surface area heuristic cost and stops\n// splitting when a leaf is cheaper (C_INT = C_TRAV = 1). Siblings are stored\n// next to each other: an interior node's children are leftFirst and\n// leftFirst + 1. Unlike the reference, node 1 is not left unused, the task\n// stack grows instead of turning a node into a leaf after 512 entries, and\n// arithmetic is float64: near-equal split costs can resolve differently from\n// TinyBVH's float32, giving trees of the same quality that are not\n// byte-identical.\n\nconst BINS = 8;\nconst C_INT = 1;\nconst C_TRAV = 1;\nconst FAR = 1e30;\n\nexport interface BinnedSahBvh {\n nodeCount: number;\n /** Per node: min x, y, z, max x, y, z. */\n bounds: Float32Array;\n /** Interior node: index of the left child. Leaf: first slot in primIndices. */\n leftFirst: Uint32Array;\n /** Primitive count of a leaf; 0 for interior nodes. */\n primCount: Uint32Array;\n /** Primitive indices referenced by leaves. */\n primIndices: Uint32Array;\n}\n\n// Scratch shared by all builds; the builder is synchronous.\nconst defaultBinMin = new Float64Array(3 * BINS * 3);\nconst defaultBinMax = new Float64Array(3 * BINS * 3);\nconst defaultBinCount = new Uint32Array(3 * BINS);\n// Per split position: half area times primitive count of each side.\nconst defaultLeftCost = new Float64Array(BINS - 1);\nconst defaultRightCost = new Float64Array(BINS - 1);\n\n/**\n * Bin of a centroid along one axis. Binning and partitioning both use this,\n * so every primitive ends up on the side whose bounds include its bin.\n */\nfunction binOf(center: number, nodeMin: number, scale: number, bins: number) {\n const bin = ((center - nodeMin) * scale) | 0;\n return bin < 0 ? 0 : bin > bins - 1 ? bins - 1 : bin;\n}\n\nfunction growBin(\n binMin: Float64Array, binMax: Float64Array, o: number,\n minX: number, minY: number, minZ: number,\n maxX: number, maxY: number, maxZ: number\n) {\n binMin[o] = Math.min(binMin[o], minX);\n binMin[o + 1] = Math.min(binMin[o + 1], minY);\n binMin[o + 2] = Math.min(binMin[o + 2], minZ);\n binMax[o] = Math.max(binMax[o], maxX);\n binMax[o + 1] = Math.max(binMax[o + 1], maxY);\n binMax[o + 2] = Math.max(binMax[o + 2], maxZ);\n}\n\n/**\n * Builds a binary BVH over axis-aligned boxes.\n * @param aabbs min x, y, z, max x, y, z for each primitive.\n * @param count number of primitives in `aabbs`.\n * @param bins SAH resolution; default 8 retains the shared/native build contract.\n */\nexport function buildBinnedSahBvh(aabbs: Float32Array, count: number, bins = BINS): BinnedSahBvh {\n const BINS = bins;\n const binMin = bins === 8 ? defaultBinMin : new Float64Array(3 * bins * 3);\n const binMax = bins === 8 ? defaultBinMax : new Float64Array(3 * bins * 3);\n const binCount = bins === 8 ? defaultBinCount : new Uint32Array(3 * bins);\n const leftCost = bins === 8 ? defaultLeftCost : new Float64Array(bins - 1);\n const rightCost = bins === 8 ? defaultRightCost : new Float64Array(bins - 1);\n const capacity = Math.max(1, count * 2 - 1);\n const bounds = new Float32Array(capacity * 6);\n const leftFirst = new Uint32Array(capacity);\n const primCount = new Uint32Array(capacity);\n const primIndices = new Uint32Array(count);\n if (count === 0) {\n return { nodeCount: 0, bounds, leftFirst, primCount, primIndices };\n }\n\n const centers = new Float32Array(count * 3);\n let rootMinX = FAR, rootMinY = FAR, rootMinZ = FAR;\n let rootMaxX = -FAR, rootMaxY = -FAR, rootMaxZ = -FAR;\n for (let i = 0; i < count; i++) {\n const b = i * 6, c = i * 3;\n const minX = aabbs[b], minY = aabbs[b + 1], minZ = aabbs[b + 2];\n const maxX = aabbs[b + 3], maxY = aabbs[b + 4], maxZ = aabbs[b + 5];\n centers[c] = (minX + maxX) * 0.5;\n centers[c + 1] = (minY + maxY) * 0.5;\n centers[c + 2] = (minZ + maxZ) * 0.5;\n if (minX < rootMinX) rootMinX = minX;\n if (minY < rootMinY) rootMinY = minY;\n if (minZ < rootMinZ) rootMinZ = minZ;\n if (maxX > rootMaxX) rootMaxX = maxX;\n if (maxY > rootMaxY) rootMaxY = maxY;\n if (maxZ > rootMaxZ) rootMaxZ = maxZ;\n primIndices[i] = i;\n }\n bounds[0] = rootMinX; bounds[1] = rootMinY; bounds[2] = rootMinZ;\n bounds[3] = rootMaxX; bounds[4] = rootMaxY; bounds[5] = rootMaxZ;\n leftFirst[0] = 0;\n primCount[0] = count;\n\n const minDimX = (rootMaxX - rootMinX) * 1e-20;\n const minDimY = (rootMaxY - rootMinY) * 1e-20;\n const minDimZ = (rootMaxZ - rootMinZ) * 1e-20;\n\n let newNode = 1;\n const tasks: number[] = [];\n let nodeIndex = 0;\n while (true) {\n while (true) {\n const nb = nodeIndex * 6;\n const nMinX = bounds[nb], nMinY = bounds[nb + 1], nMinZ = bounds[nb + 2];\n const extentX = bounds[nb + 3] - nMinX;\n const extentY = bounds[nb + 4] - nMinY;\n const extentZ = bounds[nb + 5] - nMinZ;\n const area = extentX * extentY + extentY * extentZ + extentZ * extentX;\n if (area === 0) break; // can't split an infinitely small node.\n\n const first = leftFirst[nodeIndex];\n const nodePrims = primCount[nodeIndex];\n // Every split of a single primitive leaves one side empty.\n if (nodePrims === 1) break;\n const scaleX = extentX > minDimX ? BINS / extentX : 0;\n const scaleY = extentY > minDimY ? BINS / extentY : 0;\n const scaleZ = extentZ > minDimZ ? BINS / extentZ : 0;\n\n for (let i = 0; i < 3 * BINS * 3; i++) {\n binMin[i] = FAR;\n binMax[i] = -FAR;\n }\n binCount.fill(0);\n for (let i = first, end = first + nodePrims; i < end; i++) {\n const p = primIndices[i];\n const c = p * 3, b = p * 6;\n const minX = aabbs[b], minY = aabbs[b + 1], minZ = aabbs[b + 2];\n const maxX = aabbs[b + 3], maxY = aabbs[b + 4], maxZ = aabbs[b + 5];\n // Axis a, bin i: bounds at ((a * BINS) + i) * 3.\n const bx = binOf(centers[c], nMinX, scaleX, BINS);\n const by = BINS + binOf(centers[c + 1], nMinY, scaleY, BINS);\n const bz = 2 * BINS + binOf(centers[c + 2], nMinZ, scaleZ, BINS);\n binCount[bx]++; binCount[by]++; binCount[bz]++;\n growBin(binMin, binMax, bx * 3, minX, minY, minZ, maxX, maxY, maxZ);\n growBin(binMin, binMax, by * 3, minX, minY, minZ, maxX, maxY, maxZ);\n growBin(binMin, binMax, bz * 3, minX, minY, minZ, maxX, maxY, maxZ);\n }\n\n // Sweep the bins of each axis for the lowest split cost.\n let splitCost = FAR;\n let bestAxis = 0, bestPos = 0;\n for (let axis = 0; axis < 3; axis++) {\n const extent = axis === 0 ? extentX : axis === 1 ? extentY : extentZ;\n const minDim = axis === 0 ? minDimX : axis === 1 ? minDimY : minDimZ;\n if (!(extent > minDim)) continue;\n let lMinX = FAR, lMinY = FAR, lMinZ = FAR, lMaxX = -FAR, lMaxY = -FAR, lMaxZ = -FAR;\n let rMinX = FAR, rMinY = FAR, rMinZ = FAR, rMaxX = -FAR, rMaxY = -FAR, rMaxZ = -FAR;\n let leftN = 0, rightN = 0;\n for (let i = 0; i < BINS - 1; i++) {\n const l = (axis * BINS + i) * 3;\n const r = (axis * BINS + BINS - 1 - i) * 3;\n lMinX = Math.min(lMinX, binMin[l]); lMinY = Math.min(lMinY, binMin[l + 1]); lMinZ = Math.min(lMinZ, binMin[l + 2]);\n lMaxX = Math.max(lMaxX, binMax[l]); lMaxY = Math.max(lMaxY, binMax[l + 1]); lMaxZ = Math.max(lMaxZ, binMax[l + 2]);\n rMinX = Math.min(rMinX, binMin[r]); rMinY = Math.min(rMinY, binMin[r + 1]); rMinZ = Math.min(rMinZ, binMin[r + 2]);\n rMaxX = Math.max(rMaxX, binMax[r]); rMaxY = Math.max(rMaxY, binMax[r + 1]); rMaxZ = Math.max(rMaxZ, binMax[r + 2]);\n leftN += binCount[axis * BINS + i];\n rightN += binCount[axis * BINS + BINS - 1 - i];\n const lx = lMaxX - lMinX, ly = lMaxY - lMinY, lz = lMaxZ - lMinZ;\n const rx = rMaxX - rMinX, ry = rMaxY - rMinY, rz = rMaxZ - rMinZ;\n leftCost[i] = leftN === 0 ? FAR : (lx * ly + ly * lz + lz * lx) * leftN;\n rightCost[BINS - 2 - i] = rightN === 0 ? FAR : (rx * ry + ry * rz + rz * rx) * rightN;\n }\n for (let i = 0; i < BINS - 1; i++) {\n const cost = leftCost[i] + rightCost[i];\n if (cost < splitCost) {\n splitCost = cost;\n bestAxis = axis;\n bestPos = i;\n }\n }\n }\n splitCost = C_TRAV + C_INT * splitCost / area;\n // Not splitting is better (also stops on non-finite bounds).\n if (!(splitCost < nodePrims * C_INT)) break;\n\n // In-place partition by the chosen bin.\n const scale = bestAxis === 0 ? scaleX : bestAxis === 1 ? scaleY : scaleZ;\n const nMin = bestAxis === 0 ? nMinX : bestAxis === 1 ? nMinY : nMinZ;\n let j = first + nodePrims, src = first;\n for (let i = 0; i < nodePrims; i++) {\n const p = primIndices[src];\n if (binOf(centers[p * 3 + bestAxis], nMin, scale, BINS) <= bestPos) {\n src++;\n } else {\n // Explicit numeric expression also supports scriptc typed-array stores.\n primIndices[src + 0] = primIndices[--j];\n primIndices[j] = p;\n }\n }\n const leftPrims = src - first;\n const rightPrims = nodePrims - leftPrims;\n if (leftPrims === 0 || rightPrims === 0) break; // should not happen.\n\n const n = newNode;\n newNode += 2;\n // Child bounds are the unions of the bins on each side of the split.\n const leftBase = n * 6, rightBase = leftBase + 6;\n for (let k = 0; k < 3; k++) {\n bounds[leftBase + k] = bounds[rightBase + k] = FAR;\n bounds[leftBase + 3 + k] = bounds[rightBase + 3 + k] = -FAR;\n }\n for (let i = 0; i < BINS; i++) {\n const o = (bestAxis * BINS + i) * 3;\n const base = i <= bestPos ? leftBase : rightBase;\n for (let k = 0; k < 3; k++) {\n if (binMin[o + k] < bounds[base + k]) bounds[base + k] = binMin[o + k];\n if (binMax[o + k] > bounds[base + 3 + k]) bounds[base + 3 + k] = binMax[o + k];\n }\n }\n leftFirst[n] = first; primCount[n] = leftPrims;\n leftFirst[n + 1] = j; primCount[n + 1] = rightPrims;\n leftFirst[nodeIndex] = n; primCount[nodeIndex] = 0;\n tasks.push(n + 1);\n nodeIndex = n;\n }\n if (!tasks.length) break;\n nodeIndex = tasks.pop()!;\n }\n\n return { nodeCount: newNode, bounds, leftFirst, primCount, primIndices };\n}\n\nexport interface Bvh2Layout {\n /** Node indices in depth-first order (node, left subtree, right subtree). */\n order: Uint32Array;\n /** Offset of each node in vec4 units: 2 per node plus 1 per leaf primitive. */\n offsets: Uint32Array;\n vec4Count: number;\n maxDepth: number;\n maxLeafPrimitives: number;\n}\n\n/**\n * Places nodes in the depth-first BVH2 layout read by the traversal shaders:\n * the left child follows its parent and leaf primitives follow their leaf.\n */\nexport function layoutBvh2(bvh: BinnedSahBvh): Bvh2Layout {\n const { nodeCount, leftFirst, primCount } = bvh;\n const order = new Uint32Array(nodeCount);\n const offsets = new Uint32Array(nodeCount);\n let vec4Count = 0, maxDepth = 0, maxLeafPrimitives = 0;\n if (!nodeCount) return { order, offsets, vec4Count, maxDepth, maxLeafPrimitives };\n const stack: number[] = [0, 1];\n let written = 0;\n while (stack.length) {\n const depth = stack.pop()!;\n const node = stack.pop()!;\n order[written++] = node;\n offsets[node] = vec4Count;\n if (depth > maxDepth) maxDepth = depth;\n const prims = primCount[node];\n vec4Count += 2 + prims;\n if (prims) {\n if (prims > maxLeafPrimitives) maxLeafPrimitives = prims;\n } else {\n stack.push(leftFirst[node] + 1, depth + 1, leftFirst[node], depth + 1);\n }\n }\n return { order, offsets, vec4Count, maxDepth, maxLeafPrimitives };\n}\n"]}
@@ -19,6 +19,7 @@ export interface FlattendBVH {
19
19
  layout?: BvhLayout;
20
20
  instancesBuffer?: ArrayBuffer;
21
21
  }
22
+ export declare const WEB_TLAS_BINS = 64;
22
23
  export interface TLASInstance {
23
24
  blasIndex: number;
24
25
  bounds: Box3;
@@ -62,7 +63,8 @@ export declare function refitLinearInstances(buffer: ArrayBuffer, instances: Mes
62
63
  * (instance record, BLAS offset, source instance index, 0); instance records
63
64
  * are written in leaf order to instancesBuffer.
64
65
  */
65
- export declare function buildTLAS(instances: MeshInstances, blases: BLASInstance[]): FlattendBVH;
66
+ export declare function buildTLAS(instances: MeshInstances, blases: BLASInstance[], bins?: number, perInstanceBounds?: boolean): FlattendBVH;
67
+ export declare function buildWebTLAS(instances: MeshInstances, blases: BLASInstance[]): FlattendBVH;
66
68
  /** Bounds transport for a platform BVH builder; same padding as buildTLAS. */
67
69
  export declare function meshInstanceBounds(instances: MeshInstances): Float32Array;
68
70
  /** Pack a platform-built BVH2 hierarchy whose leaf x lane holds source indices. */
@@ -27,6 +27,8 @@ function unionBounds(bounds, a, b) {
27
27
  vec3.max(bounds.max, a.max, b.max);
28
28
  return bounds;
29
29
  }
30
+ // More TLAS bins separate overlapping static instances; native retains eight.
31
+ export const WEB_TLAS_BINS = 64;
30
32
  // Keep a bounded specialization range for unusually deep hierarchies while
31
33
  // allowing large TinyBVH converted builds (for example Mustang_Red requires 51).
32
34
  // WebGPU still specializes each TLAS/BLAS stack to the scene's exact need.
@@ -290,7 +292,7 @@ export function refitLinearInstances(buffer, instances, primitiveOffsets, vertex
290
292
  * (instance record, BLAS offset, source instance index, 0); instance records
291
293
  * are written in leaf order to instancesBuffer.
292
294
  */
293
- export function buildTLAS(instances, blases) {
295
+ export function buildTLAS(instances, blases, bins = 8, perInstanceBounds = false) {
294
296
  if (!meshInstancesLength(instances))
295
297
  return emptyBvh(true);
296
298
  const placement = getBlasPlacement(blases);
@@ -298,10 +300,12 @@ export function buildTLAS(instances, blases) {
298
300
  for (let i = 0; i < meshInstancesLength(instances); i++) {
299
301
  instanceBounds(readMeshInstance(instances, i), aabbs, i * 6);
300
302
  }
301
- const bvh = buildBinnedSahBvh(aabbs, meshInstancesLength(instances));
303
+ const bvh = buildBinnedSahBvh(aabbs, meshInstancesLength(instances), bins);
302
304
  const { order, offsets, vec4Count, maxDepth, maxLeafPrimitives } = layoutBvh2(bvh);
303
305
  const { bounds, leftFirst, primCount, primIndices } = bvh;
304
- const buffer = new ArrayBuffer(vec4Count * 16);
306
+ // Web TLAS leaves point at separate world boxes. Keep the shared/native
307
+ // instance stride and legacy leaf layout unchanged.
308
+ const buffer = new ArrayBuffer((vec4Count + (perInstanceBounds ? meshInstancesLength(instances) * 2 : 0)) * 16);
305
309
  const floats = new Float32Array(buffer);
306
310
  const ints = new Int32Array(buffer);
307
311
  const instancesBuffer = new ArrayBuffer(meshInstancesLength(instances) * INSTANCE_WORD_STRIDE * 4);
@@ -332,6 +336,12 @@ export function buildTLAS(instances, blases) {
332
336
  // Keep the source instance index in the otherwise-unused z lane so
333
337
  // the TLAS can be refitted without rebuilding its topology.
334
338
  ints[e + 2] = source;
339
+ if (perInstanceBounds) {
340
+ const box = vec4Count + target * 2;
341
+ ints[e + 3] = box;
342
+ floats.set(aabbs.subarray(source * 6, source * 6 + 3), box * 4);
343
+ floats.set(aabbs.subarray(source * 6 + 3, source * 6 + 6), box * 4 + 4);
344
+ }
335
345
  writeInstanceRecord(instanceInts, instanceFloats, target, instance, placement);
336
346
  target++;
337
347
  }
@@ -345,6 +355,10 @@ export function buildTLAS(instances, blases) {
345
355
  instancesBuffer
346
356
  };
347
357
  }
358
+ // Web-only leaf boxes; shared and native callers retain their existing layout.
359
+ export function buildWebTLAS(instances, blases) {
360
+ return buildTLAS(instances, blases, WEB_TLAS_BINS, true);
361
+ }
348
362
  /** Bounds transport for a platform BVH builder; same padding as buildTLAS. */
349
363
  export function meshInstanceBounds(instances) {
350
364
  const bounds = new Float32Array(meshInstancesLength(instances) * 6);
@@ -470,6 +484,16 @@ export function refitTLAS(flattened, instances, blases, dirtySourceIndices) {
470
484
  write(bounds.max, 1, Math.max(read(bounds.max, 1), scratch[4]));
471
485
  write(bounds.max, 2, Math.max(read(bounds.max, 2), scratch[5]));
472
486
  }
487
+ const boxRanges = [];
488
+ function writeLeafBox(primitiveOffset, instance) {
489
+ const box = ints[primitiveOffset + 3];
490
+ if (!box)
491
+ return;
492
+ instanceBounds(instance, scratch, 0);
493
+ floats.set(scratch.subarray(0, 3), box * 4);
494
+ floats.set(scratch.subarray(3, 6), box * 4 + 4);
495
+ boxRanges.push({ offset: box * 16, size: 32 });
496
+ }
473
497
  function writeNodeBounds(index, bounds) {
474
498
  const base = index * 4;
475
499
  floats[base] = read(bounds.min, 0);
@@ -504,6 +528,7 @@ export function refitTLAS(flattened, instances, blases, dirtySourceIndices) {
504
528
  if (!instance)
505
529
  continue;
506
530
  addInstanceBounds(bounds, instance);
531
+ writeLeafBox(primitiveOffset, instance);
507
532
  writeInstance(targetInstance, sourceInstance);
508
533
  }
509
534
  }
@@ -539,10 +564,15 @@ export function refitTLAS(flattened, instances, blases, dirtySourceIndices) {
539
564
  const dirtyNodes = new Set();
540
565
  for (const leaf of dirtyLeaves) {
541
566
  const bounds = new Box3();
542
- for (const { source } of metadata.instancesByLeaf.get(leaf) ?? []) {
567
+ const entries = metadata.instancesByLeaf.get(leaf) ?? [];
568
+ for (let i = 0; i < entries.length; i++) {
569
+ const { source } = entries[i];
543
570
  const instance = readMeshInstance(instances, source);
544
- if (instance)
571
+ if (instance) {
545
572
  addInstanceBounds(bounds, instance);
573
+ if (dirtySourceIndices.has(source))
574
+ writeLeafBox(leaf * 4 + 8 + i * 4, instance);
575
+ }
546
576
  }
547
577
  writeNodeBounds(leaf, bounds);
548
578
  dirtyNodes.add(leaf);
@@ -562,7 +592,7 @@ export function refitTLAS(flattened, instances, blases, dirtySourceIndices) {
562
592
  writeNodeBounds(index, bounds);
563
593
  }
564
594
  return {
565
- tlasRanges: mergeRefitRanges([...dirtyNodes].map((index) => ({ offset: index * 16, size: 32 }))),
595
+ tlasRanges: mergeRefitRanges([...boxRanges, ...[...dirtyNodes].map((index) => ({ offset: index * 16, size: 32 }))]),
566
596
  instanceRanges: mergeRefitRanges(instanceRanges)
567
597
  };
568
598
  }