@meimu/mutracer 0.3.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.
- package/CHANGELOG.md +222 -0
- package/LICENSES/FidelityFX-FSR.txt +19 -0
- package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +6260 -5580
- package/docs/api.md +45 -18
- package/docs/materials.md +4 -2
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +3 -0
- package/docs/sampling.md +4 -0
- package/docs/technical/acceleration.md +52 -0
- package/docs/technical/aovs.md +79 -0
- package/docs/technical/caustics.md +109 -0
- package/docs/technical/continuous-spectrum.md +29 -0
- package/docs/technical/display-upscale.md +82 -0
- package/docs/technical/openpbr.md +99 -0
- package/docs/technical/pbrt-import.md +168 -0
- package/docs/technical/tiling.md +74 -0
- package/docs/technical/webgl.md +53 -0
- package/docs/viewer.md +11 -1
- package/lib/Display.d.ts +19 -5
- package/lib/Display.js +10 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -1
- package/lib/Engine.js +30 -2
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +20 -11
- package/lib/Render.js +32 -7
- package/lib/Render.js.map +1 -1
- package/lib/main.d.ts +3 -1
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/renderer/AovPrimitiveCache.js +39 -8
- package/lib/renderer/AovPrimitiveCache.js.map +1 -1
- package/lib/renderer/DisplayPostProcess.d.ts +8 -3
- package/lib/renderer/DisplayPostProcess.js +51 -18
- package/lib/renderer/DisplayPostProcess.js.map +1 -1
- package/lib/renderer/MaterialData.js +7 -2
- package/lib/renderer/MaterialData.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +7 -1
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +2 -2
- package/lib/renderer/TileRender.js +128 -7
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +6 -1
- package/lib/renderer/WGPUAov.js +108 -14
- package/lib/renderer/WGPUAov.js.map +1 -1
- package/lib/renderer/WGPUCanvasSurface.js +12 -1
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPURayTraceOutput.js +12 -12
- package/lib/renderer/WGPURayTracePass.d.ts +17 -4
- package/lib/renderer/WGPURayTracePass.js +194 -71
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +46 -40
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLAov.js +3 -3
- package/lib/renderer/WebGLAov.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
- package/lib/renderer/WebGLFullQuadPass.js +8 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
- package/lib/renderer/WebGLRayTracePass.js +115 -111
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -3
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +57 -57
- package/lib/renderer/aov.d.ts +13 -1
- package/lib/renderer/aov.js +21 -2
- package/lib/renderer/aov.js.map +1 -1
- package/lib/renderer/aovDisplay.js +2 -2
- package/lib/renderer/aovDisplay.js.map +1 -1
- package/lib/renderer/binnedSahBvh.d.ts +2 -1
- package/lib/renderer/binnedSahBvh.js +24 -17
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +3 -1
- package/lib/renderer/bvhAccel.js +36 -6
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +1 -1
- package/lib/renderer/cameraUniform.js +6 -2
- package/lib/renderer/cameraUniform.js.map +1 -1
- package/lib/renderer/compactVertices.d.ts +14 -0
- package/lib/renderer/compactVertices.js +124 -0
- package/lib/renderer/compactVertices.js.map +1 -0
- package/lib/renderer/easu.d.ts +11 -0
- package/lib/renderer/easu.js +156 -0
- package/lib/renderer/easu.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +1 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +3 -2
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +44 -36
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
- package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
- package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
- package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
- package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +12 -6
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.js +233 -170
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
- package/lib/renderer/openPbrEnergyLut.js +18 -1
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/pathLimits.d.ts +5 -4
- package/lib/renderer/pathLimits.js +6 -5
- package/lib/renderer/pathLimits.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.d.ts +2 -0
- package/lib/renderer/prepareMeshBVH.js +5 -3
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +1 -1
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +1 -1
- package/lib/renderer/researchTransport.js.map +1 -1
- package/lib/renderer/sceneAssembly.d.ts +1 -1
- package/lib/renderer/sceneAssembly.js +4 -3
- package/lib/renderer/sceneAssembly.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.d.ts +1 -1
- package/lib/renderer/sceneChangeDetector.js +3 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
- package/lib/renderer/sceneLayoutSchema.js +2 -2
- package/lib/renderer/sceneLayoutSchema.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +3 -2
- package/lib/renderer/scenePreparation.js +18 -2
- package/lib/renderer/scenePreparation.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.js +2 -2
- package/lib/renderer/staticBvhPreparation.d.ts +9 -0
- package/lib/renderer/staticBvhPreparation.js +8 -2
- package/lib/renderer/staticBvhPreparation.js.map +1 -1
- package/lib/renderer/surfaceHit.d.ts +10 -0
- package/lib/renderer/surfaceHit.js +22 -0
- package/lib/renderer/surfaceHit.js.map +1 -0
- package/lib/renderer/tangentRequirements.d.ts +2 -0
- package/lib/renderer/tangentRequirements.js +7 -0
- package/lib/renderer/tangentRequirements.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +4 -0
- package/lib/renderer/textureAtlas.js +48 -2
- package/lib/renderer/textureAtlas.js.map +1 -1
- package/lib/renderer/webgl.js +4 -0
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/webglVertexAttributes.d.ts +17 -0
- package/lib/renderer/webglVertexAttributes.js +44 -0
- package/lib/renderer/webglVertexAttributes.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +2 -2
- package/lib/renderer/wgpuMaterialConstants.js +4 -3
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
- package/lib/renderer/wgpuSceneUniform.js +2 -2
- package/lib/renderer/wgpuSceneUniform.js.map +1 -1
- package/lib/renderer/wgpuShaderSource.d.ts +15 -0
- package/lib/renderer/wgpuShaderSource.js +1 -1
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
- package/lib/renderer/wgsl/causticLight.compute.js +121 -119
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
- package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/easu.wgsl.js +80 -0
- package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.js +89 -89
- package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +11 -0
- package/lib/settings/render.js +1 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +21 -14
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +5 -2
- package/lib/oidnBundledWeights.cdn.d.ts +0 -2
- package/lib/oidnBundledWeights.cdn.js +0 -5
- package/lib/oidnBundledWeights.cdn.js.map +0 -1
- package/lib/renderer/bvh.worker.d.ts +0 -1
- package/lib/renderer/bvh.worker.js +0 -16
- package/lib/renderer/bvh.worker.js.map +0 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
- package/lib/renderer/bvhWorkerBuild.js +0 -17
- package/lib/renderer/bvhWorkerBuild.js.map +0 -1
- package/lib/renderer/lightCore.d.ts +0 -12
- package/lib/renderer/lightCore.js +0 -13
- package/lib/renderer/lightCore.js.map +0 -1
- package/lib/renderer/materialCore.d.ts +0 -8
- package/lib/renderer/materialCore.js +0 -9
- package/lib/renderer/materialCore.js.map +0 -1
- package/lib/scene/PixelTexture.d.ts +0 -6
- package/lib/scene/PixelTexture.js +0 -10
- package/lib/scene/PixelTexture.js.map +0 -1
- package/lib/util/studioLighting.d.ts +0 -18
- package/lib/util/studioLighting.js +0 -36
- package/lib/util/studioLighting.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aovDisplay.js","sourceRoot":"","sources":["../../src/renderer/aovDisplay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,UAAU,CAAC;
|
|
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
|
-
//
|
|
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
|
|
22
|
-
const
|
|
23
|
-
const
|
|
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
|
|
26
|
-
const
|
|
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 >
|
|
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. */
|
package/lib/renderer/bvhAccel.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
}
|