@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.
- package/CHANGELOG.md +222 -0
- package/LICENSES/FidelityFX-FSR.txt +19 -0
- package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
- package/README.md +3 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +9328 -7614
- package/docs/api.md +83 -35
- package/docs/caustics.md +80 -0
- package/docs/materials.md +9 -6
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +53 -9
- 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 +122 -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/updates.md +3 -1
- package/docs/viewer-checklist.md +65 -0
- package/docs/viewer.md +18 -6
- 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 +4 -1
- package/lib/Engine.js +77 -14
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +81 -24
- package/lib/Render.js +201 -26
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +7 -3
- package/lib/RenderLoop.js +68 -44
- package/lib/RenderLoop.js.map +1 -1
- package/lib/main.d.ts +4 -2
- 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/GPUTraceQueue.d.ts +2 -1
- package/lib/renderer/GPUTraceQueue.js +3 -1
- package/lib/renderer/GPUTraceQueue.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 +11 -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/WGPUCausticLightPass.d.ts +48 -0
- package/lib/renderer/WGPUCausticLightPass.js +217 -0
- package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
- package/lib/renderer/WGPUPhotonMap.js +191 -0
- package/lib/renderer/WGPUPhotonMap.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
- package/lib/renderer/WGPURayTraceOutput.js +122 -28
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +65 -21
- package/lib/renderer/WGPURayTracePass.js +730 -409
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +110 -68
- 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 +2 -1
- package/lib/renderer/WebGLFullQuadPass.js +10 -0
- 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 +20 -11
- package/lib/renderer/WebGLRayTracePass.js +157 -116
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +17 -14
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +60 -60
- package/lib/renderer/accumulationTarget.d.ts +2 -1
- package/lib/renderer/accumulationTarget.js.map +1 -1
- 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/causticDiagnostics.d.ts +31 -0
- package/lib/renderer/causticDiagnostics.js +5 -0
- package/lib/renderer/causticDiagnostics.js.map +1 -0
- package/lib/renderer/causticEmission.d.ts +10 -0
- package/lib/renderer/causticEmission.js +40 -0
- package/lib/renderer/causticEmission.js.map +1 -0
- package/lib/renderer/causticUniform.d.ts +12 -0
- package/lib/renderer/causticUniform.js +22 -0
- package/lib/renderer/causticUniform.js.map +1 -0
- package/lib/renderer/caustics.d.ts +16 -0
- package/lib/renderer/caustics.js +93 -0
- package/lib/renderer/caustics.js.map +1 -0
- 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 +53 -53
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +45 -37
- 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.d.ts +2 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
- package/lib/renderer/glsl/chunks/intersect.glsl.js +478 -465
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +70 -63
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +89 -75
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +160 -118
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
- package/lib/renderer/glsl/chunks/sampling.glsl.js +88 -91
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
- 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 +13 -7
- 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.d.ts +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +338 -252
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +27 -26
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/lightSampling.d.ts +3 -2
- package/lib/renderer/lightSampling.js +14 -8
- package/lib/renderer/lightSampling.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 +5 -4
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +5 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +31 -0
- package/lib/renderer/researchTransport.js +5 -0
- package/lib/renderer/researchTransport.js.map +1 -0
- 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 +2 -0
- package/lib/renderer/sceneLayoutSchema.js +3 -3
- 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.d.ts +21 -0
- package/lib/renderer/spectrum.js +154 -0
- package/lib/renderer/spectrum.js.map +1 -0
- 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/webglLightSampling.d.ts +39 -0
- package/lib/renderer/webglLightSampling.js +15 -0
- package/lib/renderer/webglLightSampling.js.map +1 -0
- 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 +3 -3
- 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 +22 -0
- package/lib/renderer/wgpuShaderSource.js +3 -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 +55 -55
- 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 +33 -33
- 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 +6 -0
- package/lib/renderer/wgsl/causticLight.compute.js +539 -0
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +634 -620
- 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 +23 -21
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +3 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +77 -74
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +795 -795
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +45 -29
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +228 -189
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +88 -92
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
- 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 +100 -98
- 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 +12 -3
- 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.d.ts +29 -0
- package/lib/renderer/wgsl/photonMap.compute.js +352 -0
- package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +23 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +531 -543
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/MaterialState.d.ts +2 -2
- package/lib/scene/MaterialState.js +2 -2
- package/lib/scene/MaterialState.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +22 -0
- package/lib/settings/render.js +2 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +23 -16
- 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/llms.txt +2 -1
- package/package.json +7 -4
- 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
package/docs/api.md
CHANGED
|
@@ -127,41 +127,45 @@ other sequences retain their completed samples.
|
|
|
127
127
|
| Option | Default | Meaning |
|
|
128
128
|
| --- | --- | --- |
|
|
129
129
|
| `maxSamples` | `2048` | Complete sample budget |
|
|
130
|
+
| `aovResolution` | `'render'` | `'display'` traces AOVs at canvas size on WebGPU, capped at 4 samples regardless of `aovSamples`; requires a scale-based render. WebGL falls back with one warning |
|
|
130
131
|
| `aovs` / `aovSamples` | `[]` / `16` | Optional [surface outputs](#surface-outputs) / independent positive integer sample cap |
|
|
131
132
|
| `bounces` / `clamping` | `3` / `0` | Scattering depth / per-sample radiance clamp; 0 disables clamping |
|
|
132
133
|
| `samplingPattern` | `'sobol'` | Sobol, ZSobol or random; see [sampling](./sampling.md) |
|
|
134
|
+
| `caustics` | `undefined` | Optional caustics; all estimators default to off. See [caustics](#caustics) |
|
|
133
135
|
| `directLightCandidates` | `4` | WebGPU light candidates, clamped 1–16; ignored on WebGL |
|
|
134
136
|
| `bevel` / `bevelSamples` | `true` / `8` | Bevel shading / probes, clamped 1–32 |
|
|
135
|
-
| `dispersionWavelengths` | `3` |
|
|
137
|
+
| `dispersionWavelengths` | `3` | One continuous wavelength per RGB channel, or one randomly chosen channel |
|
|
136
138
|
| `alphaBlendStrategy` | `'stochastic'` | WebGPU primary BLEND policy; ignored on WebGL |
|
|
137
139
|
| `transmissiveOutputAlphaMin` | `1` | Path-depth alpha rule over transparent backgrounds; changes restart this render |
|
|
138
140
|
| `resolutionScale` | `1` | Relative to display canvas; exclusive with fixed width/height |
|
|
139
|
-
| `width` / `height` | undefined | Paired fixed constructor dimensions; getters
|
|
141
|
+
| `width` / `height` | undefined | Paired fixed constructor dimensions; `toBlob`, `readPixels` and the getters return exactly this size |
|
|
140
142
|
| `adaptiveResolution` | `false` | `{targetFrameMs, minScale}` for scale-based renders; both required, positive, minScale ≤ resolutionScale |
|
|
141
|
-
| `timeBudgetMs` / `maxTiles` | `21` / `Infinity` |
|
|
142
|
-
| `batchSamples` | `false` | Let one refine submit several samples within timeBudgetMs; see [sample batching](./progressive-rendering.md#sample-batching). `allowMultipleSamplesPerFrame` is a deprecated alias |
|
|
143
|
+
| `timeBudgetMs` / `maxTiles` | `21` / `Infinity` | Target tile time / maximum tile grid size per sample (rounded up to a rectangular grid); fewer tiles make larger tiles, without limiting work per frame or call |
|
|
144
|
+
| `batchSamples` | `false` | Let one refine submit several samples within an estimated timeBudgetMs; one sample or tile can exceed it; see [sample batching](./progressive-rendering.md#sample-batching). `allowMultipleSamplesPerFrame` is a deprecated alias |
|
|
143
145
|
| `fallback` | `null` | Single-level Render on the same engine |
|
|
144
146
|
| `denoiser` | `null` | Per-render configuration; read back through the frozen `denoiser` getter and change with `setDenoiser()`; see [denoising](./denoising.md) |
|
|
145
147
|
|
|
146
|
-
`bounces` is rounded and clamped to [1,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
or alpha,
|
|
148
|
+
`bounces` is rounded and clamped to [1, 50] on WebGPU or [1, 20] on WebGL;
|
|
149
|
+
NaN becomes 1. Paths allow at most `min(bounces * 3, 50)` events on WebGPU
|
|
150
|
+
or `min(bounces * 3, 20)` on WebGL, including transmission,
|
|
151
|
+
alpha skips and escape checks. Opaque paths also terminate at their scattering
|
|
152
|
+
limit. The event budget can truncate deep transparent paths before the requested
|
|
153
|
+
scattering depth. On Intel Mac WebGL, the event limit is `min(bounces, 3)`, doubled
|
|
154
|
+
for scenes with transmission or alpha, with earlier scattering termination.
|
|
155
|
+
See [caustic path-length limits](./caustics.md#limits) when comparing renderers.
|
|
153
156
|
|
|
154
157
|
| Method / property | Meaning |
|
|
155
158
|
| --- | --- |
|
|
156
159
|
| `refine(channel?, options?)` | Trace beauty or an enabled AOV within this render's budget; returns status |
|
|
160
|
+
| `refineUntil(deadline, {signal}?)` | For custom frame loops: refine once synchronously, then keep sampling until the `performance.now()` deadline or cancellation; returns `Promise<void>`; see [sample batching](progressive-rendering.md#sample-batching) |
|
|
157
161
|
| `converge(options)` | Deterministic offline image; see below |
|
|
158
162
|
| `readPixels(kind = 'hdr')` | Read this render; see [pixel outputs](#pixel-outputs) |
|
|
159
163
|
| `engine` | Owning engine |
|
|
160
164
|
| `denoising` | Queued/running inference, including intermediate updates; default false |
|
|
161
165
|
| `on('sample', listener)` | Complete samples: `{samples, isFirstFrame, frameTimeMs}`; returns unsubscribe |
|
|
162
166
|
| `samples` | Complete samples since restart; stale engine inputs report 0 |
|
|
163
|
-
| `gpuSampleTimeMs` | Latest WebGPU full beauty sample estimate in ms; undefined without timestamps, for stale inputs or during converge |
|
|
164
|
-
| `whenReadyToRefine()` | Wait for
|
|
167
|
+
| `gpuSampleTimeMs` | Deprecated; use `refineUntil` for custom frame loops. Latest WebGPU full beauty sample estimate in ms, extrapolated from tile GPU time when tiled; undefined without timestamps, for stale inputs or during converge |
|
|
168
|
+
| `whenReadyToRefine()` | Deprecated; use `refineUntil`. Wait for WebGPU sampling capacity and return `true` if sampling was queued; return `false` immediately with no sampling, on WebGL, or for only denoising, display or offline convergence work; submits no work; throws after disposal |
|
|
165
169
|
| `converged` | `samples >= maxSamples`, independently of filtering |
|
|
166
170
|
| `status` | Preparing, compiling, converging, denoising, finished or error |
|
|
167
171
|
| `setDenoiser(options)` | Replace the denoiser configuration; resolves when the filter is ready |
|
|
@@ -175,13 +179,10 @@ completed filtering. Synchronous execution failures return `'error'` and set
|
|
|
175
179
|
engine.lastError. Invalid lifecycle operations (disposed render or refine during
|
|
176
180
|
converge) throw.
|
|
177
181
|
|
|
178
|
-
`refine(undefined, {batchSamples
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
capped by that budget and is ignored on WebGL. `deferResolve` (default false,
|
|
183
|
-
WebGPU only) leaves the displayed image unchanged for calls between display
|
|
184
|
-
frames; the next presentation or pixel read updates it once with every new sample.
|
|
182
|
+
`refine(undefined, {batchSamples})` overrides batching for one call without
|
|
183
|
+
changing render settings or discarding samples; it defaults to the render's
|
|
184
|
+
`batchSamples`. The `targetBatchTimeMs` and `deferResolve` refine options are
|
|
185
|
+
deprecated; use `refineUntil`.
|
|
185
186
|
|
|
186
187
|
A fallback gets one sample when the requested render cannot finish its first
|
|
187
188
|
sample within budget and the fallback has no current complete image. A ready
|
|
@@ -206,6 +207,25 @@ Resolves `{samples, averageSamplesPerPixel, pilotSamples, adaptiveSampling,
|
|
|
206
207
|
varianceHistory?}` after filtering. It rejects if engine input revisions change.
|
|
207
208
|
The same render cannot refine concurrently; other renders remain usable.
|
|
208
209
|
|
|
210
|
+
### Caustics
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
render.caustics = {lightTracing: {photonsPerSample: 32768}};
|
|
214
|
+
render.caustics = undefined; // Disable every estimator.
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Changing any caustic option restarts accumulation. All estimators are experimental;
|
|
218
|
+
see the [caustics guide](./caustics.md) for choosing estimators, supported paths,
|
|
219
|
+
rendering cost and image-quality limitations.
|
|
220
|
+
|
|
221
|
+
| Option | Default | Meaning |
|
|
222
|
+
| --- | --- | --- |
|
|
223
|
+
| `lightTracing` | `false` | `true` or an object enables directly visible caustic light paths on WebGPU; ignored on WebGL 2 |
|
|
224
|
+
| `lightTracing.photonsPerSample` | pixel count / 4 | Emitted photons per sample, rounded to a positive integer and capped by the device dispatch limit |
|
|
225
|
+
| `photonMapping` | `false` | `true` or an object enables progressive caustic photon mapping on WebGPU; ignored on WebGL 2. See [PM-only denoising limits](./caustics.md#limits) |
|
|
226
|
+
| `photonMapping.photonsPerSample` | pixel count / 4, at most 262144 | Emitted photons per batch; 28 bytes each plus up to 13 MiB of overhead. Positive finite values are rounded to at least 1 and reduced to fit device limits and a 128 MiB batch budget; other values use the default |
|
|
227
|
+
| `photonMapping.initialRadius` | 3% of the caster bounding sphere radius | Positive first-batch gather radius in scene units, independent of `photonsPerSample`; shrinks as batches accumulate. Smaller radii preserve detail but require more photons |
|
|
228
|
+
|
|
209
229
|
## RenderLoop and Sync
|
|
210
230
|
|
|
211
231
|
`start()` uses requestAnimationFrame when available and a 16 ms setTimeout
|
|
@@ -226,6 +246,7 @@ otherwise. Worker visibility and control forwarding are described in
|
|
|
226
246
|
|
|
227
247
|
`engine`, `display`, `preview` (possibly undefined) and `final` are read-only.
|
|
228
248
|
`changing` defaults false; `samples` counts final beauty samples and reports 0 during preview; `status` starts preparing.
|
|
249
|
+
An exception during a tick, such as from a sync, sets `status` to error and `lastError`; the next successful tick clears them.
|
|
229
250
|
`select({changing})` defaults to changing ? preview : final. `addSync`/`removeSync`
|
|
230
251
|
manage integrations without disposing them. `tick` executes a manual frame;
|
|
231
252
|
`start`/`stop` manage animation frames. `converge` accepts the same options as
|
|
@@ -251,7 +272,7 @@ Use `engine.display`; creation of additional displays is outside this API.
|
|
|
251
272
|
their next refine; fixed renders retain their dimensions.
|
|
252
273
|
`present(render)` only presents: it returns the render or its ready fallback,
|
|
253
274
|
or undefined without changing the canvas when neither is ready.
|
|
254
|
-
`toBlob(render, {type?, quality?})` composes that render at its
|
|
275
|
+
`toBlob(render, {type?, quality?})` composes that render at its output dimensions,
|
|
255
276
|
without resizing or changing the current canvas. MIME defaults to image/png;
|
|
256
277
|
quality defaults to the browser encoder value.
|
|
257
278
|
|
|
@@ -331,9 +352,20 @@ const depth = await render.readPixels('depth'); // Float32Array, RGBA
|
|
|
331
352
|
const ids = await render.readPixels('id'); // Uint32Array, RGBA
|
|
332
353
|
```
|
|
333
354
|
|
|
334
|
-
You can change `render.aovs` or `render.
|
|
355
|
+
You can change `render.aovs`, `render.aovSamples` or `render.aovResolution` after sampling. Continue
|
|
335
356
|
calling `refine()` to regenerate AOVs for the current view; beauty samples and
|
|
336
|
-
completed denoising are preserved. AOV accumulation restarts when
|
|
357
|
+
completed denoising are preserved. AOV accumulation restarts when any of them changes.
|
|
358
|
+
|
|
359
|
+
To keep beauty at reduced resolution while reading or displaying full-resolution
|
|
360
|
+
surface outputs, set `aovResolution: 'display'` on a scale-based render. The
|
|
361
|
+
default is `'render'`. AOV readbacks and visualization use their own dimensions;
|
|
362
|
+
beauty and denoiser guides keep the render dimensions. Both modes stop at
|
|
363
|
+
`min(samples, aovSamples)`; display mode also caps at 4, follows canvas resizes,
|
|
364
|
+
and rejects fixed-size renders. During tracing, display mode starts after the first
|
|
365
|
+
beauty sample and adds one AOV sample per frame; the frame that reaches
|
|
366
|
+
`maxSamples` completes the rest. WebGL falls back to render dimensions and warns
|
|
367
|
+
once per render. Each kind has the same meaning in both modes.
|
|
368
|
+
Custom denoiser AOV inputs require `'render'` resolution.
|
|
337
369
|
|
|
338
370
|
| Kind | RGBA contents |
|
|
339
371
|
| --- | --- |
|
|
@@ -342,13 +374,14 @@ completed denoising are preserved. AOV accumulation restarts when either changes
|
|
|
342
374
|
| `roughness` | Specular roughness, metalness, unsupported-reflectance fraction, coverage |
|
|
343
375
|
| `diffuseAlbedo` | Directional-hemispherical diffuse reflectance RGB, valid coverage |
|
|
344
376
|
| `specularAlbedo` | Directional-hemispherical specular reflectance RGB, valid coverage |
|
|
377
|
+
| `diffuseColor` | Diffuse texture color: base weight × base color × (1 − metalness), tinted by coat color; valid coverage |
|
|
378
|
+
| `specularColor` | Specular texture color: metal base color plus dielectric specular color × F0, tinted by coat color; valid coverage |
|
|
345
379
|
| `id` | Object, local instance (0 for ordinary meshes), material, source triangle index; background is `0xFFFFFFFF` in all channels |
|
|
346
380
|
| `motion` | Previous position minus current position in pixels, x right and y down; z = 0, alpha = 3 for valid history or 0 otherwise |
|
|
347
381
|
|
|
348
|
-
Depth, position, roughness and
|
|
349
|
-
rays, including depth of field
|
|
350
|
-
|
|
351
|
-
uses only supported hits for both normalization and valid coverage. A blank pixel
|
|
382
|
+
Depth, position, roughness, reflectance and color average independent jittered primary
|
|
383
|
+
rays, including depth of field. RGB values use hit-count normalization; alpha is hit coverage over all AOV samples. Reflectance
|
|
384
|
+
and color use only supported hits for both normalization and valid coverage. A blank pixel
|
|
352
385
|
is zero. These passes preserve beauty samples but do not sample the same paths.
|
|
353
386
|
Alpha holes use the first surface with alpha ≥ 0.5, skipping shadow catchers,
|
|
354
387
|
with at most 32 layers.
|
|
@@ -373,14 +406,23 @@ Reflectance outputs are separate from the existing OIDN `albedo` guide.
|
|
|
373
406
|
Coat, fuzz, anisotropy, subsurface/volume scattering, bevel, thin film,
|
|
374
407
|
dispersion, partial alpha and nonstandard materials are unsupported by this
|
|
375
408
|
reflectance estimate. Such hits contribute to `roughness.b` and have zero
|
|
376
|
-
reflectance validity. Reflectance
|
|
377
|
-
|
|
409
|
+
reflectance validity. Reflectance tracing can be expensive; request it only when needed.
|
|
410
|
+
|
|
411
|
+
`diffuseColor` and `specularColor` read resolved material inputs without
|
|
412
|
+
integrating the BSDF, so they are cheap. They support coat, fuzz and anisotropic
|
|
413
|
+
surfaces; transmission, partial alpha, media and nonstandard materials have zero
|
|
414
|
+
color validity. A render can request `diffuseAlbedo` or `diffuseColor`, not both;
|
|
415
|
+
the same applies to `specularAlbedo` and `specularColor`.
|
|
378
416
|
|
|
379
417
|
Reading a kind absent from `render.aovs` rejects. A custom denoiser can request
|
|
380
418
|
its own [AOV inputs](./denoising.md#custom-denoisers). With neither request there
|
|
381
|
-
are no AOV allocations or passes. Enabling any kind costs about 128 GPU bytes
|
|
382
|
-
per pixel on WebGPU or 192 on WebGL, plus scene identity/history data
|
|
383
|
-
|
|
419
|
+
are no AOV allocations or passes. Enabling any kind normally costs about 128 GPU bytes
|
|
420
|
+
per AOV pixel on WebGPU or 192 on WebGL, plus scene identity/history data.
|
|
421
|
+
WebGPU display mode requesting only `depth`, `diffuseColor` and/or `specularColor` costs
|
|
422
|
+
24 bytes per pixel plus small scene metadata; borrowing all three GPU textures
|
|
423
|
+
adds another 24 bytes per pixel (about 288 MB total at 6 MP). Its color
|
|
424
|
+
accumulation has half precision. Other AOV selections use the full allocation;
|
|
425
|
+
each custom denoiser AOV snapshot adds 16 bytes per pixel. A render may retain one
|
|
384
426
|
reusable snapshot per kind between denoising calls. Readback adds a CPU copy.
|
|
385
427
|
WebGPU dimensions remain subject to device buffer limits. A full-frame AOV
|
|
386
428
|
sample runs independently of tile/adaptive sampling and may exceed the render's
|
|
@@ -402,7 +444,7 @@ const png = await engine.display.toBlob(render);
|
|
|
402
444
|
| `depth` | Black at the near depth, white at the far depth, clamped outside the range |
|
|
403
445
|
| `position` | World xyz mapped to RGB; origin is 0.5 and ±position scale maps to 0/1 |
|
|
404
446
|
| `roughness` | RGB = roughness, metalness, unsupported-reflectance fraction |
|
|
405
|
-
| `diffuseAlbedo`, `specularAlbedo` | Linear
|
|
447
|
+
| `diffuseAlbedo`, `specularAlbedo`, `diffuseColor`, `specularColor` | Linear RGB clamped to [0, 1], then sRGB encoded |
|
|
406
448
|
| `id` | Stable pseudocolor for the selected uint32 ID component; colors can collide |
|
|
407
449
|
| `motion` | Direction as hue (+x is red, +y is yellow-green), displacement/scale as brightness |
|
|
408
450
|
|
|
@@ -579,8 +621,14 @@ see [denoising](./denoising.md#custom-oidn-networks). The main entry exports
|
|
|
579
621
|
## GPU output and display passes
|
|
580
622
|
|
|
581
623
|
`render.getOutputTexture(kind)` borrows native HDR or the latest display image;
|
|
582
|
-
`
|
|
583
|
-
|
|
624
|
+
`render.getAovTexture('diffuseColor' | 'specularColor' | 'depth')` borrows raw
|
|
625
|
+
linear AOV textures at their own resolution after sampling; WebGL returns undefined.
|
|
626
|
+
`display.addPostProcess(pass, options?)` returns unregister and runs on every present/export.
|
|
627
|
+
Both are WebGPU-only. `options.outputSize` defaults to preserving input dimensions;
|
|
628
|
+
the final display texture and export can differ from the render size. Fixed renders
|
|
629
|
+
are cropped to their requested rectangle before export passes. HDR textures can
|
|
630
|
+
include extra pixels around a fixed render's requested image. See
|
|
631
|
+
[formats, lifecycle, EASU upscale and overlay examples](./post-processing.md).
|
|
584
632
|
|
|
585
633
|
Anisotropy direction options: `anisotropyMap` (default `undefined`) reads linear RG as a tangent direction and B as a multiplier for base specular strength. `specularAnisotropyRotation` (default `0`) rotates that direction counter-clockwise in radians; `coatAnisotropyRotation` (default `0`) rotates the coat relative to the geometry tangent. See [materials](./materials.md#anisotropy-directions) for frame and fallback conventions.
|
|
586
634
|
|
package/docs/caustics.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Caustics
|
|
2
|
+
|
|
3
|
+
Enable caustics on the render that needs them:
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
render.caustics = {lightTracing: true, photonMapping: true};
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Choose the estimators for the visible receiver:
|
|
10
|
+
|
|
11
|
+
| Scene | Settings |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| Glass or metal casting onto a directly visible surface | `{lightTracing: true}` |
|
|
14
|
+
| Water or glass between the camera and the caustic receiver | `{photonMapping: true}` |
|
|
15
|
+
| A mixture of direct, indirect and glass-covered receivers | `{lightTracing: true, photonMapping: true}` |
|
|
16
|
+
|
|
17
|
+
Light tracing preserves narrow, directly visible caustics without a gather
|
|
18
|
+
radius. Photon mapping covers indirect caustics and surfaces seen through glass,
|
|
19
|
+
with additional memory and gather cost. Combined estimators assign path coverage
|
|
20
|
+
automatically. The viewer's Cornell caustic preset enables both estimators.
|
|
21
|
+
|
|
22
|
+
Set `render.caustics = undefined` to disable every estimator. See
|
|
23
|
+
[API options and defaults](./api.md#caustics).
|
|
24
|
+
|
|
25
|
+
## Options and cost
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
render.caustics = {
|
|
29
|
+
lightTracing: {photonsPerSample: 32768},
|
|
30
|
+
photonMapping: {photonsPerSample: 32768, initialRadius: 0.1}
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Both estimators require WebGPU; WebGL ignores those options. HDR readback,
|
|
35
|
+
display and denoising include the combined result. Changes to any option restart
|
|
36
|
+
accumulation. The native SDK provides the same choices through Rust
|
|
37
|
+
`CausticSettings` and the C `MT_CAUSTIC_*` flags.
|
|
38
|
+
|
|
39
|
+
More emitted photons can reduce noise but cost more time and memory. Photon-map
|
|
40
|
+
storage adds 28 bytes per emitted photon plus up to 13 MiB of overhead. Requests
|
|
41
|
+
above the device limits or the 128 MiB batch budget use fewer photons. Photon
|
|
42
|
+
batches cover the full image even when path tracing uses tiles or adaptive
|
|
43
|
+
sampling. Their time counts toward the frame budget, but adaptive variance measures
|
|
44
|
+
only the path-traced component.
|
|
45
|
+
|
|
46
|
+
## Limits
|
|
47
|
+
|
|
48
|
+
Light tracing follows surfaces with no diffuse, subsurface, fuzz or coat
|
|
49
|
+
contribution and specular roughness at most 0.1. It supports emissive triangles,
|
|
50
|
+
rectangles, spheres, spotlights, directional lights and environment lighting,
|
|
51
|
+
perspective and orthographic cameras, depth of field and dispersion. Photon
|
|
52
|
+
mapping adds caustics throughout the allowed camera path. Volume scattering
|
|
53
|
+
events and shadow catchers remain with ordinary path tracing.
|
|
54
|
+
|
|
55
|
+
Complete caustic light-to-camera paths can be longer than `bounces`. Align total
|
|
56
|
+
path-length limits when comparing radiance with another renderer.
|
|
57
|
+
|
|
58
|
+
Photon mapping starts blurred and shrinks its radius as samples accumulate. A
|
|
59
|
+
small initial radius can be noisy; a large one can blur nearby surfaces and details.
|
|
60
|
+
Distant smooth casters enlarge the automatic radius, so set `initialRadius` if deep
|
|
61
|
+
caustics look too blurred. At the first diffuse surface, the gather radius is capped
|
|
62
|
+
to about two projected pixels to reduce patches after denoising; reflections and
|
|
63
|
+
refractions use an approximate footprint. More photons can help, but not every
|
|
64
|
+
batch improves the image, and more samples do not remove the precision loss in
|
|
65
|
+
stored photon data.
|
|
66
|
+
|
|
67
|
+
With photon mapping alone, directly visible receivers can show fewer cloud-like
|
|
68
|
+
OIDN blotches but grainier raw images. Receivers seen through reflection or
|
|
69
|
+
refraction can still show blotches. Enable light tracing as well for the cleanest
|
|
70
|
+
directly visible receivers.
|
|
71
|
+
|
|
72
|
+
A denoiser can soften narrow caustic lines, so compare raw HDR with denoised output
|
|
73
|
+
when judging detail. Use raw HDR for energy comparisons: displayed or denoised
|
|
74
|
+
brightness can differ even when regional HDR energy agrees.
|
|
75
|
+
|
|
76
|
+
Both estimators fall back to path tracing for the whole scene when a smooth caster
|
|
77
|
+
uses stochastic blend coverage. Cutout coverage remains supported. Environment
|
|
78
|
+
caustics follow path tracing's visible-background behavior through the first smooth
|
|
79
|
+
transmission; an explicit black background suppresses that contribution.
|
|
80
|
+
Quantitative energy agreement with other renderers is not guaranteed.
|
package/docs/materials.md
CHANGED
|
@@ -51,12 +51,14 @@ the textures they reference still share atlas space.
|
|
|
51
51
|
|
|
52
52
|
Units: `transmissionDepth` and `subsurfaceRadius` are in scene units;
|
|
53
53
|
`thinFilmThickness` is in micrometres (`0.45` = 450 nm).
|
|
54
|
+
Subsurface materials with short scattering radii may appear darker than in earlier releases.
|
|
54
55
|
|
|
55
56
|
`baseWeight` scales diffuse reflection and the metallic normal-incidence color
|
|
56
57
|
(`baseWeight * baseColor`). Dielectric specular, transmission and subsurface
|
|
57
58
|
retain their own strengths. For metals, `specularColor` tints the F82 Fresnel
|
|
58
59
|
curve near grazing angles and `specularWeight` scales the entire reflection,
|
|
59
60
|
including thin-film reflection. At their default values, F82 reduces to Schlick.
|
|
61
|
+
Low-roughness metals may appear slightly darker under broad lighting than in earlier releases.
|
|
60
62
|
|
|
61
63
|
Native `specularRoughnessAnisotropy` and `coatRoughnessAnisotropy` use the OpenPBR GGX mapping:
|
|
62
64
|
`alphaT = roughness² * sqrt(2 / (1 + (1 - anisotropy)²))` and
|
|
@@ -97,10 +99,11 @@ the substrate through the attenuation term.
|
|
|
97
99
|
**Interior media.** Transmission describes a homogeneous volume:
|
|
98
100
|
`transmissionColor` is the color that survives one `transmissionDepth`, and
|
|
99
101
|
`transmissionScatter` is the scattering albedo. With `transmissionDepth = 0`
|
|
100
|
-
the tint is applied at the surface. Subsurface
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
the tint is applied at the surface. Subsurface has its own color and per-channel
|
|
103
|
+
radius. A positive `transmissionDispersionScale` enables
|
|
104
|
+
wavelength-dependent refraction; values above `1` increase color separation,
|
|
105
|
+
and `0` disables it. Lower `transmissionDispersionAbbeNumber` values also
|
|
106
|
+
increase color separation.
|
|
104
107
|
|
|
105
108
|
## Compatibility names
|
|
106
109
|
|
|
@@ -128,7 +131,7 @@ an alternate serialization format.
|
|
|
128
131
|
| --- | --- | --- |
|
|
129
132
|
| `map` | RGB (sRGB), A | Multiplies `baseColor`; alpha use set by `mapAlphaUsage` |
|
|
130
133
|
| `alphaMap` | G | Opacity, as in Three.js |
|
|
131
|
-
| `normalMap`, `normalScale` | RGB | Tangent space;
|
|
134
|
+
| `normalMap`, `normalScale` | RGB | Tangent space; uses triangle UV derivatives |
|
|
132
135
|
| `metallicRoughnessMap` | G = roughness, B = metalness | glTF convention |
|
|
133
136
|
| `roughnessMap` | G | |
|
|
134
137
|
| `metalnessMap` | B | |
|
|
@@ -287,6 +290,6 @@ Set `specularAnisotropyRotation` or provide `anisotropyMap` to orient the base s
|
|
|
287
290
|
|
|
288
291
|
`coatAnisotropyRotation` defaults to zero and uses the geometry tangent independently of the base map. Base and coat use their respective directions and [normals](#coat-normals). Zero anisotropy strength ignores the direction.
|
|
289
292
|
|
|
290
|
-
Provided tangent XYZ and optional W handedness are preserved. For XYZ tangents the sign comes from triangle UV derivatives. Missing or degenerate tangents use UV derivatives and then a stable orthonormal fallback
|
|
293
|
+
Provided tangent XYZ and optional W handedness are preserved. Missing tangents are generated from primary UVs only when a material using the geometry needs anisotropy or an active coat normal map; adding such a material prepares them automatically. For XYZ tangents the sign comes from triangle UV derivatives. Missing UVs or degenerate tangents use UV derivatives where available and then a stable orthonormal fallback. The direction texture's selected UV set is used for derivative fallback, including UV1. A provided XYZW tangent remains authoritative. Directions are reorthogonalized against the final shading normal, including normal maps and back faces, and instance transforms preserve mirrored handedness. UV scale, offset and flipY affect texel lookup; they do not rotate the encoded direction.
|
|
291
294
|
|
|
292
295
|
The direction and strength inputs use native OpenPBR semantics by default. For imported glTF/Three.js strength, select `specularAnisotropyModel: 'gltf'`; the same roughness and strength properties then retain source values. Source scalar inputs are clamped to [0, 1] before texture factors; non-finite source roughness/strength fall back to 0.3/0. Native scalar handling is unchanged. Zero source strength preserves the original roughness path. The conversion matches the GGX alpha axes before existing minimum-alpha clamping; Fresnel, masking, multiple scattering and OpenPBR coating remain the library's model. See [the conversion rules](./threejs.md#anisotropy-source-conversion).
|
package/docs/performance.md
CHANGED
|
@@ -38,6 +38,13 @@ A tuning checklist. Each item links to the page with the details.
|
|
|
38
38
|
- Textures share an atlas bounded by `textureAtlasBudgetBytes`; larger textures
|
|
39
39
|
are downscaled. Check `engine.getDiagnostics()?.textureAtlas`.
|
|
40
40
|
|
|
41
|
+
WebGPU quantizes vertex normal and tangent directions; scenes with displacement
|
|
42
|
+
retain full normal precision. Vertex RGB values in
|
|
43
|
+
`[0, 1]` have at most `1/510` absolute error per channel; scenes containing
|
|
44
|
+
negative or HDR vertex colors retain float32 RGB instead. Positions and UV
|
|
45
|
+
coordinates retain float32 precision. Large scenes still depend on the device's
|
|
46
|
+
buffer limits and the browser's available CPU memory.
|
|
47
|
+
|
|
41
48
|
## Animation and editing
|
|
42
49
|
|
|
43
50
|
See [scene updates](./updates.md) for the cost of each kind of edit.
|
package/docs/post-processing.md
CHANGED
|
@@ -18,8 +18,9 @@ remove(); // Safe to call again.
|
|
|
18
18
|
|
|
19
19
|
Passes run in registration order on every `present()` and `toBlob()`, after
|
|
20
20
|
composition and denoising. They receive the selected complete render, including
|
|
21
|
-
fallbacks, at its actual dimensions. Export uses the same chain without
|
|
22
|
-
|
|
21
|
+
fallbacks, at its actual dimensions. Export uses the same chain without changing
|
|
22
|
+
the display canvas; fixed-size renders are cropped to their requested size before
|
|
23
|
+
entering the chain. `readPixels()` never runs these passes.
|
|
23
24
|
|
|
24
25
|
For a complete overlay implementation, see
|
|
25
26
|
[`createCrosshairPass`](../examples/shared/crosshairPass.ts). It loads the input
|
|
@@ -35,12 +36,55 @@ A changing overlay can read application state in its callback. `RenderLoop`
|
|
|
35
36
|
stops presenting after convergence, so explicitly call `display.present(final)`
|
|
36
37
|
when that state changes. This refreshes the overlay without tracing more samples.
|
|
37
38
|
|
|
39
|
+
For edge-adaptive enlargement without sharpening:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import {createEasuPass} from '@meimu/mutracer';
|
|
43
|
+
const pass = createEasuPass();
|
|
44
|
+
const removeUpscale = engine.display.addPostProcess(pass, {
|
|
45
|
+
outputSize: (_, display) => display
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Register the upscale before overlays that should stay at canvas resolution. An
|
|
50
|
+
input that already has the output size is copied unchanged and a larger one is
|
|
51
|
+
area-averaged, so one registration can serve a full-resolution or supersampled
|
|
52
|
+
final render and a reduced-resolution preview.
|
|
53
|
+
|
|
54
|
+
To recover texture detail, enable `diffuseColor`, `specularColor` and `depth`
|
|
55
|
+
on a scale-based render with `aovResolution: 'display'`, and create the pass with
|
|
56
|
+
`createEasuPass({albedoDetail: true})`. Keep beauty at the desired reduced
|
|
57
|
+
`resolutionScale`. Unregister the pass, then call `pass.dispose()` when finished
|
|
58
|
+
to release its scratch images.
|
|
59
|
+
|
|
60
|
+
EASU works on display-encoded RGB after tone mapping, including extended-range
|
|
61
|
+
output, and preserves alpha. EASU alone cannot recover missing texture detail.
|
|
62
|
+
Albedo compensation recovers supported surface texture detail but cannot recover
|
|
63
|
+
reflection, refraction or geometric detail. It maps the displayed image back
|
|
64
|
+
through the display transform, estimates locally how much radiance follows albedo,
|
|
65
|
+
and changes only that part, so specular highlights mostly keep their brightness.
|
|
66
|
+
Clipped highlights cannot be recovered. Transmission, cutouts, background, low
|
|
67
|
+
coverage and depth boundaries receive EASU alone. With detail, a present costs about
|
|
68
|
+
2.6 ms at 6 MP on an Apple M4 Max, compared with about 0.5 ms for EASU alone.
|
|
69
|
+
|
|
38
70
|
## Options and image semantics
|
|
39
71
|
|
|
40
72
|
`getOutputTexture(kind)` requires `'hdr'` or `'display'`; both return undefined
|
|
41
73
|
on WebGL, before a complete sample or after disposal. There are no passes by
|
|
42
74
|
default. `addPostProcess(pass)` returns an idempotent unregister function.
|
|
43
|
-
`PostProcess` and `
|
|
75
|
+
`PostProcess`, `PostProcessContext` and `PostProcessOptions` are exported types.
|
|
76
|
+
|
|
77
|
+
Use `addPostProcess(pass, {outputSize: (input, display) => display})` to output
|
|
78
|
+
at canvas resolution. The default preserves the input dimensions. Each callback
|
|
79
|
+
receives the previous pass's dimensions and the current canvas dimensions, also
|
|
80
|
+
for `toBlob()`. A chain can change size more than once. Return positive integer
|
|
81
|
+
width and height within `device.limits.maxTextureDimension2D`; invalid dimensions
|
|
82
|
+
discard the whole chain and emit an engine error, as callback exceptions do.
|
|
83
|
+
|
|
84
|
+
`ctx.width` and `ctx.height` remain the actual render dimensions. Read
|
|
85
|
+
`ctx.input.width/height` and `ctx.output.width/height` for the pass dimensions.
|
|
86
|
+
`toBlob()` exports the final chain dimensions; `getOutputTexture('display')`
|
|
87
|
+
borrows that actual-sized image, which may differ from the render size.
|
|
44
88
|
|
|
45
89
|
| Image | Meaning |
|
|
46
90
|
| --- | --- |
|
|
@@ -59,6 +103,21 @@ by primary-hit coverage for partially hit pixels, restoring the per-sample
|
|
|
59
103
|
average. Thus that CPU readback can differ from the borrowed native HDR texture.
|
|
60
104
|
See [custom denoiser image semantics](./denoising.md#custom-denoisers).
|
|
61
105
|
|
|
106
|
+
`createEasuPass()` defaults to EASU alone. `albedoDetail` defaults to `false`.
|
|
107
|
+
When the displayed render lacks those AOVs or display resolution, the pass warns
|
|
108
|
+
once and upscales without detail; frames whose AOVs are not ready yet or differ
|
|
109
|
+
from the output size also use EASU alone. The optional AOVs add tracing and
|
|
110
|
+
memory cost; see [surface outputs](./api.md#surface-outputs).
|
|
111
|
+
|
|
112
|
+
`render.getAovTexture(kind)` borrows enabled `diffuseColor`, `specularColor` or
|
|
113
|
+
`depth` outputs after an AOV sample completes, only on WebGPU. Colors use
|
|
114
|
+
`rgba8unorm-srgb`, which loads as linear values in [0, 1], with valid coverage in
|
|
115
|
+
alpha; depth uses `rg32float`, with
|
|
116
|
+
camera-forward depth in red and hit coverage in green. These raw textures follow
|
|
117
|
+
the same borrowing lifetime as `getOutputTexture()` and have the AOV dimensions.
|
|
118
|
+
Each is resolved from the accumulation when its samples change, and the first
|
|
119
|
+
call for a kind also creates its pipeline.
|
|
120
|
+
|
|
62
121
|
## Caveats
|
|
63
122
|
|
|
64
123
|
Textures are borrowed and read-only. Do not retain, write or destroy returned
|
|
@@ -79,9 +138,3 @@ discards the chain's recorded commands, displays the original composed image
|
|
|
79
138
|
and emits the engine `error` event. GPU validation errors remain WebGPU errors;
|
|
80
139
|
the callback must record valid commands.
|
|
81
140
|
|
|
82
|
-
## Implementation notes
|
|
83
|
-
|
|
84
|
-
The composed image is kept separately, so a thrown callback cannot leave a
|
|
85
|
-
partly processed result.
|
|
86
|
-
Display passes do not enter denoiser inputs, change samples or invalidate cached
|
|
87
|
-
filter results. HDR-stage callbacks are outside this API.
|
|
@@ -87,24 +87,68 @@ are refined that frame. See [scene updates](updates.md) for notifications.
|
|
|
87
87
|
|
|
88
88
|
## Sample batching
|
|
89
89
|
|
|
90
|
-
Without batching,
|
|
91
|
-
|
|
90
|
+
Without batching, each call advances one sample or tile, so a fast GPU can idle
|
|
91
|
+
between display frames. With `batchSamples`, sampling works on two levels:
|
|
92
92
|
|
|
93
|
-
- **Per call.** One `refine()` may submit several samples
|
|
94
|
-
`timeBudgetMs` of GPU work
|
|
93
|
+
- **Per call.** One `refine()` may submit several samples within an estimated
|
|
94
|
+
`timeBudgetMs` of GPU work, or one longer sample or tile, and returns without waiting for them.
|
|
95
95
|
Without `batchSamples`, a call traces one sample or tile.
|
|
96
96
|
- **Between frames.** RenderLoop also refines its final render each time the GPU
|
|
97
97
|
finishes queued work, until the next display frame. It keeps about 4 ms of work
|
|
98
|
-
queued, or one sample if that is longer
|
|
99
|
-
|
|
98
|
+
queued, or one sample or tile if that is longer. Expensive tiled samples can
|
|
99
|
+
continue between display frames when each measured tile fits `timeBudgetMs`;
|
|
100
|
+
longer tiles wait for display frames to bound input delay. Presentation still
|
|
101
|
+
follows the display frame rate.
|
|
100
102
|
|
|
101
103
|
Batching is off by default. Enable it on the loop's final render with
|
|
102
104
|
`final: {batchSamples: true}`, or on a Render you supply. RenderLoop stops
|
|
103
105
|
batching while the view is changing.
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
`
|
|
107
|
-
`
|
|
107
|
+
Prefer RenderLoop for between-frame refilling. For a custom loop, use
|
|
108
|
+
`refineUntil(deadline, {signal})`. It synchronously calls `refine()` once, so
|
|
109
|
+
`present()` belongs immediately after the call. On WebGPU it then refills short
|
|
110
|
+
batches until the deadline, cancellation, a hidden page or sampling/display
|
|
111
|
+
conditions prevent more work. WebGL performs only the synchronous call.
|
|
112
|
+
|
|
113
|
+
This example assumes `engine` and `render` are created with
|
|
114
|
+
`render.batchSamples = true` and the final beauty channel selected. Adjust the
|
|
115
|
+
60 Hz deadline to your application's cadence and update controls before
|
|
116
|
+
`engine.update()`.
|
|
117
|
+
|
|
118
|
+
<!-- own-loop-refill -->
|
|
119
|
+
```js
|
|
120
|
+
let refill;
|
|
121
|
+
const stop = () => refill?.abort();
|
|
122
|
+
for (const type of ['pointerdown', 'pointermove', 'pointerup', 'wheel', 'keydown', 'input', 'change'])
|
|
123
|
+
addEventListener(type, stop, {capture: true, passive: true});
|
|
124
|
+
|
|
125
|
+
function frame(timestamp) {
|
|
126
|
+
requestAnimationFrame(frame);
|
|
127
|
+
stop();
|
|
128
|
+
engine.update();
|
|
129
|
+
refill = new AbortController();
|
|
130
|
+
void render.refineUntil(timestamp + 1000 / 60, {signal: refill.signal});
|
|
131
|
+
engine.display.present(render);
|
|
132
|
+
}
|
|
133
|
+
requestAnimationFrame(frame);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Call `stop()` before pausing, exporting or switching to another render, and skip
|
|
137
|
+
`refineUntil()` while paused. A new call automatically ends the previous refill.
|
|
138
|
+
The signal cancels future submissions; work already queued on the GPU completes.
|
|
139
|
+
The returned Promise resolves when refilling stops, including after an
|
|
140
|
+
asynchronous error (reported through `render.status` and `engine.lastError`).
|
|
141
|
+
|
|
142
|
+
The library automatically continues the remaining tiles of the current sample
|
|
143
|
+
between presentations. `samples` increases only after the whole sample;
|
|
144
|
+
presentation keeps the previous complete sample until then. Committed scene or
|
|
145
|
+
camera edits discard an unfinished sample and restart against the new inputs.
|
|
146
|
+
`maxTiles` caps the sample's tile grid (rounded up to a rectangular grid), so a
|
|
147
|
+
smaller value makes larger tiles. It does not cap work per frame or per call;
|
|
148
|
+
use `timeBudgetMs` and the between-frame deadline to control queued work.
|
|
149
|
+
With GPU timing available, WebGPU can keep tiles above `timeBudgetMs` when the
|
|
150
|
+
budget cannot be reached or further subdivision brings little speedup. This limits
|
|
151
|
+
extra offline rendering cost while allowing longer pauses between updates.
|
|
108
152
|
|
|
109
153
|
## Reading and exporting
|
|
110
154
|
|
package/docs/sampling.md
CHANGED
|
@@ -23,6 +23,10 @@ render.samplingPattern = 'zsobol';
|
|
|
23
23
|
`sampleSequenceOffset`. Use disjoint offset ranges for animation frames.
|
|
24
24
|
- **Backends**: WebGPU and WebGL 2 can differ in floating-point rounding even
|
|
25
25
|
with identical sequence points.
|
|
26
|
+
- **Dispersion**: on WebGPU, `dispersionWavelengths: 3` with
|
|
27
|
+
`directLightCandidates > 1` can need more samples in individual RGB channels
|
|
28
|
+
under strongly colored lighting and materials. Lower overall noise does not
|
|
29
|
+
guarantee lower noise in every channel.
|
|
26
30
|
- **Fireflies**: very narrow specular lobes under directional lights can
|
|
27
31
|
produce rare, large contributions with any pattern. Sampling does not clamp
|
|
28
32
|
them; use `render.clamping` if needed.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Acceleration structures
|
|
2
|
+
|
|
3
|
+
The renderer traces a two-level hierarchy: one bottom-level BVH (BLAS) per geometry
|
|
4
|
+
and a top-level BVH (TLAS) over mesh instances. Builders, layouts and preparation
|
|
5
|
+
are documented in the [BVH guide](../bvh.md); this note records the choices behind
|
|
6
|
+
the defaults and the alternatives that were measured. The code is
|
|
7
|
+
`src/renderer/bvhAccel.ts` and `binnedSahBvh.ts`.
|
|
8
|
+
|
|
9
|
+
## TLAS
|
|
10
|
+
|
|
11
|
+
- **Builder.** The TLAS always uses the built-in binned SAH builder, a JavaScript
|
|
12
|
+
port of TinyBVH's `BVH::Build`, built and refitted on the calling thread.
|
|
13
|
+
- **Bins.** The web TLAS uses 64 SAH bins (`WEB_TLAS_BINS`); native keeps 8. More
|
|
14
|
+
bins separate overlapping static instances in scenes with many instances.
|
|
15
|
+
Higher instance costs, exact SAH and forced fallbacks were compared and not
|
|
16
|
+
adopted. The rebuilt tree can pick a different object at coincident faces, which
|
|
17
|
+
changes `id` AOVs there; other AOVs matched, and HDR differed only by rounding.
|
|
18
|
+
- **Instance bounds.** Each instance's world bounds, padded by displacement, are
|
|
19
|
+
stored after the TLAS. Leaf traversal tests them before transforming the ray
|
|
20
|
+
into the BLAS's space, so a ray that misses an instance skips the transform and
|
|
21
|
+
the BLAS root test. Both web backends and the caustic kernel use them.
|
|
22
|
+
|
|
23
|
+
## BLAS
|
|
24
|
+
|
|
25
|
+
- **Defaults.** The BVH2 layout with spatial splits off stays the default after a
|
|
26
|
+
matrix of builder, layout and split settings. CWBVH was slower on the measured
|
|
27
|
+
scenes despite its smaller nodes. Spatial splits help some scenes at three to
|
|
28
|
+
five times the build time, so they stay opt-in.
|
|
29
|
+
- **Traversal tweaks.** Changes to box tests and stack handling showed no reliable
|
|
30
|
+
gain and were not adopted.
|
|
31
|
+
|
|
32
|
+
## Static merge prototype
|
|
33
|
+
|
|
34
|
+
A prototype merged static instances into one world-space BLAS, with world-space
|
|
35
|
+
triangle bounds and vertex tests in local space. It was faster on a heavy
|
|
36
|
+
many-instance scene, but:
|
|
37
|
+
|
|
38
|
+
- coincident geometry needs the old tree as a fallback to keep object identity,
|
|
39
|
+
which costs memory and cold build time;
|
|
40
|
+
- HDR and legacy guides differ by rare rounding, and subsurface scattering, alpha
|
|
41
|
+
random streams, instance colors and picking were not verified;
|
|
42
|
+
- incremental updates and the choice of which instances count as static are
|
|
43
|
+
undesigned.
|
|
44
|
+
|
|
45
|
+
It is not in production. Pursuing it needs both web layouts, an update strategy and
|
|
46
|
+
those verifications, then a native port and comparison.
|
|
47
|
+
|
|
48
|
+
## Changing this code
|
|
49
|
+
|
|
50
|
+
- TLAS and BLAS changes affect `id` AOVs and picking at ties; compare those as well
|
|
51
|
+
as HDR.
|
|
52
|
+
- Keep native's TLAS parameters unless native is aligned in a separate change.
|