@meimu/mutracer 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/LICENSES/GLSL-PathTracer-MIT.txt +21 -0
- package/LICENSES/GlMatrix-MIT.txt +19 -0
- package/LICENSES/KinoBloom-MIT.txt +21 -0
- package/LICENSES/OIDNWeb-MIT.txt +21 -0
- package/LICENSES/Octicons-MIT.txt +21 -0
- package/LICENSES/RayTracingRenderer-MIT.txt +21 -0
- package/LICENSES/TinyBVH-MIT.txt +21 -0
- package/LICENSES/WebGPUUtils-MIT.txt +21 -0
- package/LICENSES/ZetaRay-MIT.txt +21 -0
- package/README.md +240 -2
- package/THIRD_PARTY_NOTICES.md +160 -0
- package/dist/assets/bvh.worker.js +1 -0
- package/dist/mutracer.umd.js +14360 -0
- package/docs/api.md +394 -0
- package/docs/bvh.md +141 -0
- package/docs/denoising.md +301 -0
- package/docs/getting-started.md +308 -0
- package/docs/materials.md +281 -0
- package/docs/performance.md +85 -0
- package/docs/post-processing.md +87 -0
- package/docs/progressive-rendering.md +160 -0
- package/docs/sampling.md +40 -0
- package/docs/threejs.md +274 -0
- package/docs/todo.md +61 -0
- package/docs/updates.md +208 -0
- package/lib/Display.d.ts +72 -0
- package/lib/Display.js +123 -0
- package/lib/Display.js.map +1 -0
- package/lib/Engine.d.ts +161 -0
- package/lib/Engine.js +681 -0
- package/lib/Engine.js.map +1 -0
- package/lib/Render.d.ts +265 -0
- package/lib/Render.js +742 -0
- package/lib/Render.js.map +1 -0
- package/lib/RenderLoop.d.ts +79 -0
- package/lib/RenderLoop.js +236 -0
- package/lib/RenderLoop.js.map +1 -0
- package/lib/Sync.d.ts +19 -0
- package/lib/Sync.js +19 -0
- package/lib/Sync.js.map +1 -0
- package/lib/constants.d.ts +2 -0
- package/lib/constants.js +3 -0
- package/lib/constants.js.map +1 -0
- package/lib/main.d.ts +56 -0
- package/lib/main.js +43 -0
- package/lib/main.js.map +1 -0
- package/lib/math.d.ts +23 -0
- package/lib/math.js +56 -0
- package/lib/math.js.map +1 -0
- package/lib/oidn.d.ts +45 -0
- package/lib/oidn.js +42 -0
- package/lib/oidn.js.map +1 -0
- package/lib/oidnBundledWeights.cdn.d.ts +2 -0
- package/lib/oidnBundledWeights.cdn.js +5 -0
- package/lib/oidnBundledWeights.cdn.js.map +1 -0
- package/lib/oidnBundledWeights.d.ts +2 -0
- package/lib/oidnBundledWeights.js +4 -0
- package/lib/oidnBundledWeights.js.map +1 -0
- package/lib/renderer/DisplayPostProcess.d.ts +14 -0
- package/lib/renderer/DisplayPostProcess.js +41 -0
- package/lib/renderer/DisplayPostProcess.js.map +1 -0
- package/lib/renderer/MaterialTable.d.ts +119 -0
- package/lib/renderer/MaterialTable.js +550 -0
- package/lib/renderer/MaterialTable.js.map +1 -0
- package/lib/renderer/OfflineAdaptiveSampling.d.ts +47 -0
- package/lib/renderer/OfflineAdaptiveSampling.js +36 -0
- package/lib/renderer/OfflineAdaptiveSampling.js.map +1 -0
- package/lib/renderer/RenderingPipeline.d.ts +232 -0
- package/lib/renderer/RenderingPipeline.js +18 -0
- package/lib/renderer/RenderingPipeline.js.map +1 -0
- package/lib/renderer/ScratchPool.d.ts +13 -0
- package/lib/renderer/ScratchPool.js +21 -0
- package/lib/renderer/ScratchPool.js.map +1 -0
- package/lib/renderer/TileRender.d.ts +44 -0
- package/lib/renderer/TileRender.js +283 -0
- package/lib/renderer/TileRender.js.map +1 -0
- package/lib/renderer/WGPUBloomPass.d.ts +17 -0
- package/lib/renderer/WGPUBloomPass.js +243 -0
- package/lib/renderer/WGPUBloomPass.js.map +1 -0
- package/lib/renderer/WGPUCanvasSurface.d.ts +21 -0
- package/lib/renderer/WGPUCanvasSurface.js +48 -0
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -0
- package/lib/renderer/WGPUComputePass.d.ts +73 -0
- package/lib/renderer/WGPUComputePass.js +317 -0
- package/lib/renderer/WGPUComputePass.js.map +1 -0
- package/lib/renderer/WGPUFullQuadPass.d.ts +73 -0
- package/lib/renderer/WGPUFullQuadPass.js +389 -0
- package/lib/renderer/WGPUFullQuadPass.js.map +1 -0
- package/lib/renderer/WGPUHDRPeakMeter.d.ts +19 -0
- package/lib/renderer/WGPUHDRPeakMeter.js +112 -0
- package/lib/renderer/WGPUHDRPeakMeter.js.map +1 -0
- package/lib/renderer/WGPUJNLMDenoiser.d.ts +61 -0
- package/lib/renderer/WGPUJNLMDenoiser.js +412 -0
- package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +44 -0
- package/lib/renderer/WGPURayTraceOutput.js +368 -0
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -0
- package/lib/renderer/WGPURayTracePass.d.ts +284 -0
- package/lib/renderer/WGPURayTracePass.js +2323 -0
- package/lib/renderer/WGPURayTracePass.js.map +1 -0
- package/lib/renderer/WGPURenderingPipeline.d.ts +9 -0
- package/lib/renderer/WGPURenderingPipeline.js +1448 -0
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -0
- package/lib/renderer/WGPUSceneFeatures.d.ts +3 -0
- package/lib/renderer/WGPUSceneFeatures.js +20 -0
- package/lib/renderer/WGPUSceneFeatures.js.map +1 -0
- package/lib/renderer/WGPUScratchBuffer.d.ts +9 -0
- package/lib/renderer/WGPUScratchBuffer.js +21 -0
- package/lib/renderer/WGPUScratchBuffer.js.map +1 -0
- package/lib/renderer/WGPUScratchTexture.d.ts +10 -0
- package/lib/renderer/WGPUScratchTexture.js +27 -0
- package/lib/renderer/WGPUScratchTexture.js.map +1 -0
- package/lib/renderer/WGPUShaderCache.d.ts +26 -0
- package/lib/renderer/WGPUShaderCache.js +103 -0
- package/lib/renderer/WGPUShaderCache.js.map +1 -0
- package/lib/renderer/WebGLBloomPass.d.ts +18 -0
- package/lib/renderer/WebGLBloomPass.js +113 -0
- package/lib/renderer/WebGLBloomPass.js.map +1 -0
- package/lib/renderer/WebGLFullQuadPass.d.ts +65 -0
- package/lib/renderer/WebGLFullQuadPass.js +208 -0
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -0
- package/lib/renderer/WebGLJNLMDenoiser.d.ts +32 -0
- package/lib/renderer/WebGLJNLMDenoiser.js +328 -0
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -0
- package/lib/renderer/WebGLRayTraceOutputPass.d.ts +20 -0
- package/lib/renderer/WebGLRayTraceOutputPass.js +106 -0
- package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -0
- package/lib/renderer/WebGLRayTracePass.d.ts +142 -0
- package/lib/renderer/WebGLRayTracePass.js +845 -0
- package/lib/renderer/WebGLRayTracePass.js.map +1 -0
- package/lib/renderer/WebGLReadback.d.ts +4 -0
- package/lib/renderer/WebGLReadback.js +75 -0
- package/lib/renderer/WebGLReadback.js.map +1 -0
- package/lib/renderer/WebGLRenderingPipeline.d.ts +4 -0
- package/lib/renderer/WebGLRenderingPipeline.js +510 -0
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -0
- package/lib/renderer/WebGLScratchCopy.d.ts +10 -0
- package/lib/renderer/WebGLScratchCopy.js +27 -0
- package/lib/renderer/WebGLScratchCopy.js.map +1 -0
- package/lib/renderer/accumulationTarget.d.ts +26 -0
- package/lib/renderer/accumulationTarget.js +2 -0
- package/lib/renderer/accumulationTarget.js.map +1 -0
- package/lib/renderer/binnedSahBvh.d.ts +31 -0
- package/lib/renderer/binnedSahBvh.js +263 -0
- package/lib/renderer/binnedSahBvh.js.map +1 -0
- package/lib/renderer/bvh.worker.d.ts +1 -0
- package/lib/renderer/bvh.worker.js +16 -0
- package/lib/renderer/bvh.worker.js.map +1 -0
- package/lib/renderer/bvhAccel.d.ts +81 -0
- package/lib/renderer/bvhAccel.js +621 -0
- package/lib/renderer/bvhAccel.js.map +1 -0
- package/lib/renderer/bvhWorkerBuild.d.ts +12 -0
- package/lib/renderer/bvhWorkerBuild.js +17 -0
- package/lib/renderer/bvhWorkerBuild.js.map +1 -0
- package/lib/renderer/bvhWorkerClient.d.ts +57 -0
- package/lib/renderer/bvhWorkerClient.js +166 -0
- package/lib/renderer/bvhWorkerClient.js.map +1 -0
- package/lib/renderer/cameraLens.d.ts +5 -0
- package/lib/renderer/cameraLens.js +15 -0
- package/lib/renderer/cameraLens.js.map +1 -0
- package/lib/renderer/cameraSnapshot.d.ts +3 -0
- package/lib/renderer/cameraSnapshot.js +7 -0
- package/lib/renderer/cameraSnapshot.js.map +1 -0
- package/lib/renderer/committedScene.d.ts +13 -0
- package/lib/renderer/committedScene.js +126 -0
- package/lib/renderer/committedScene.js.map +1 -0
- package/lib/renderer/dataTextureUtil.d.ts +32 -0
- package/lib/renderer/dataTextureUtil.js +46 -0
- package/lib/renderer/dataTextureUtil.js.map +1 -0
- package/lib/renderer/denoiser.d.ts +65 -0
- package/lib/renderer/denoiser.js +2 -0
- package/lib/renderer/denoiser.js.map +1 -0
- package/lib/renderer/depthQuery.d.ts +14 -0
- package/lib/renderer/depthQuery.js +14 -0
- package/lib/renderer/depthQuery.js.map +1 -0
- package/lib/renderer/deviceRequirements.d.ts +23 -0
- package/lib/renderer/deviceRequirements.js +50 -0
- package/lib/renderer/deviceRequirements.js.map +1 -0
- package/lib/renderer/envMapCreation.d.ts +10 -0
- package/lib/renderer/envMapCreation.js +96 -0
- package/lib/renderer/envMapCreation.js.map +1 -0
- package/lib/renderer/envMapDistribution.d.ts +9 -0
- package/lib/renderer/envMapDistribution.js +107 -0
- package/lib/renderer/envMapDistribution.js.map +1 -0
- package/lib/renderer/float16.d.ts +1 -0
- package/lib/renderer/float16.js +19 -0
- package/lib/renderer/float16.js.map +1 -0
- package/lib/renderer/geometryBvh.d.ts +11 -0
- package/lib/renderer/geometryBvh.js +24 -0
- package/lib/renderer/geometryBvh.js.map +1 -0
- package/lib/renderer/geometryUpdates.d.ts +28 -0
- package/lib/renderer/geometryUpdates.js +131 -0
- package/lib/renderer/geometryUpdates.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +37 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/common.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/common.glsl.js +17 -0
- package/lib/renderer/glsl/chunks/common.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +192 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/intersect.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/intersect.glsl.js +1091 -0
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +371 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +1767 -0
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/rand.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/rand.glsl.js +26 -0
- package/lib/renderer/glsl/chunks/rand.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/random.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/random.glsl.js +27 -0
- package/lib/renderer/glsl/chunks/random.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +287 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampleLight.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +254 -0
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +279 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +48 -0
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampling.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampling.glsl.js +194 -0
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sobol.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sobol.glsl.js +170 -0
- package/lib/renderer/glsl/chunks/sobol.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +27 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/uvProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +72 -0
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/depthQuery.frag.d.ts +3 -0
- package/lib/renderer/glsl/depthQuery.frag.js +55 -0
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -0
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.d.ts +6 -0
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +46 -0
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -0
- package/lib/renderer/glsl/rayTrace.frag.d.ts +2 -0
- package/lib/renderer/glsl/rayTrace.frag.js +623 -0
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -0
- package/lib/renderer/glsl/shadowCatcher.frag.d.ts +3 -0
- package/lib/renderer/glsl/shadowCatcher.frag.js +119 -0
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -0
- package/lib/renderer/glsl/webglPipeline.frag.d.ts +4 -0
- package/lib/renderer/glsl/webglPipeline.frag.js +208 -0
- package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -0
- package/lib/renderer/gpuMemory.d.ts +2 -0
- package/lib/renderer/gpuMemory.js +10 -0
- package/lib/renderer/gpuMemory.js.map +1 -0
- package/lib/renderer/halton.d.ts +1 -0
- package/lib/renderer/halton.js +15 -0
- package/lib/renderer/halton.js.map +1 -0
- package/lib/renderer/jnlm.d.ts +85 -0
- package/lib/renderer/jnlm.js +87 -0
- package/lib/renderer/jnlm.js.map +1 -0
- package/lib/renderer/lightSampling.d.ts +75 -0
- package/lib/renderer/lightSampling.js +305 -0
- package/lib/renderer/lightSampling.js.map +1 -0
- package/lib/renderer/lightsUtil.d.ts +26 -0
- package/lib/renderer/lightsUtil.js +154 -0
- package/lib/renderer/lightsUtil.js.map +1 -0
- package/lib/renderer/materialChanges.d.ts +13 -0
- package/lib/renderer/materialChanges.js +59 -0
- package/lib/renderer/materialChanges.js.map +1 -0
- package/lib/renderer/materialComparison.generated.d.ts +5 -0
- package/lib/renderer/materialComparison.generated.js +655 -0
- package/lib/renderer/materialComparison.generated.js.map +1 -0
- package/lib/renderer/materialConstants.d.ts +6 -0
- package/lib/renderer/materialConstants.js +3 -0
- package/lib/renderer/materialConstants.js.map +1 -0
- package/lib/renderer/materialEmission.d.ts +9 -0
- package/lib/renderer/materialEmission.js +21 -0
- package/lib/renderer/materialEmission.js.map +1 -0
- package/lib/renderer/materialIndices.d.ts +7 -0
- package/lib/renderer/materialIndices.js +34 -0
- package/lib/renderer/materialIndices.js.map +1 -0
- package/lib/renderer/materialLayout.d.ts +102 -0
- package/lib/renderer/materialLayout.js +189 -0
- package/lib/renderer/materialLayout.js.map +1 -0
- package/lib/renderer/materialTextureSlots.d.ts +537 -0
- package/lib/renderer/materialTextureSlots.js +219 -0
- package/lib/renderer/materialTextureSlots.js.map +1 -0
- package/lib/renderer/mergeMeshesToGeometry.d.ts +8 -0
- package/lib/renderer/mergeMeshesToGeometry.js +236 -0
- package/lib/renderer/mergeMeshesToGeometry.js.map +1 -0
- package/lib/renderer/meshInstances.d.ts +23 -0
- package/lib/renderer/meshInstances.js +66 -0
- package/lib/renderer/meshInstances.js.map +1 -0
- package/lib/renderer/meshMembership.d.ts +10 -0
- package/lib/renderer/meshMembership.js +72 -0
- package/lib/renderer/meshMembership.js.map +1 -0
- package/lib/renderer/oidnNetwork.d.ts +20 -0
- package/lib/renderer/oidnNetwork.js +123 -0
- package/lib/renderer/oidnNetwork.js.map +1 -0
- package/lib/renderer/openPbrEnergyLut.d.ts +32 -0
- package/lib/renderer/openPbrEnergyLut.js +965 -0
- package/lib/renderer/openPbrEnergyLut.js.map +1 -0
- package/lib/renderer/pathLimits.d.ts +4 -0
- package/lib/renderer/pathLimits.js +7 -0
- package/lib/renderer/pathLimits.js.map +1 -0
- package/lib/renderer/prepareMeshBVH.d.ts +110 -0
- package/lib/renderer/prepareMeshBVH.js +857 -0
- package/lib/renderer/prepareMeshBVH.js.map +1 -0
- package/lib/renderer/progressiveScheduler.d.ts +11 -0
- package/lib/renderer/progressiveScheduler.js +19 -0
- package/lib/renderer/progressiveScheduler.js.map +1 -0
- package/lib/renderer/renderPipeline.d.ts +57 -0
- package/lib/renderer/renderPipeline.js +49 -0
- package/lib/renderer/renderPipeline.js.map +1 -0
- package/lib/renderer/sampling.d.ts +10 -0
- package/lib/renderer/sampling.js +28 -0
- package/lib/renderer/sampling.js.map +1 -0
- package/lib/renderer/sceneChangeDetector.d.ts +29 -0
- package/lib/renderer/sceneChangeDetector.js +232 -0
- package/lib/renderer/sceneChangeDetector.js.map +1 -0
- package/lib/renderer/sceneLightChanges.d.ts +14 -0
- package/lib/renderer/sceneLightChanges.js +34 -0
- package/lib/renderer/sceneLightChanges.js.map +1 -0
- package/lib/renderer/scratchSampling.d.ts +3 -0
- package/lib/renderer/scratchSampling.js +39 -0
- package/lib/renderer/scratchSampling.js.map +1 -0
- package/lib/renderer/shader.d.ts +37 -0
- package/lib/renderer/shader.js +41 -0
- package/lib/renderer/shader.js.map +1 -0
- package/lib/renderer/staticBvhPreparation.d.ts +24 -0
- package/lib/renderer/staticBvhPreparation.js +116 -0
- package/lib/renderer/staticBvhPreparation.js.map +1 -0
- package/lib/renderer/textureRegion.d.ts +8 -0
- package/lib/renderer/textureRegion.js +9 -0
- package/lib/renderer/textureRegion.js.map +1 -0
- package/lib/renderer/texturesFromMaterials.d.ts +6 -0
- package/lib/renderer/texturesFromMaterials.js +37 -0
- package/lib/renderer/texturesFromMaterials.js.map +1 -0
- package/lib/renderer/util.d.ts +17 -0
- package/lib/renderer/util.js +56 -0
- package/lib/renderer/util.js.map +1 -0
- package/lib/renderer/webgl.d.ts +131 -0
- package/lib/renderer/webgl.js +586 -0
- package/lib/renderer/webgl.js.map +1 -0
- package/lib/renderer/webglShaders.d.ts +4 -0
- package/lib/renderer/webglShaders.js +41 -0
- package/lib/renderer/webglShaders.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +23 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +128 -0
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +1441 -0
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +8 -0
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +85 -0
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +7 -0
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +315 -0
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.d.ts +3 -0
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +1737 -0
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +352 -0
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/rand.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +25 -0
- package/lib/renderer/wgsl/chunks/rand.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/random.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/random.wgsl.js +2 -0
- package/lib/renderer/wgsl/chunks/random.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -0
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +328 -0
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +400 -0
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +3 -0
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +439 -0
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +40 -0
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +198 -0
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +8 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sobol.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +170 -0
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +42 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +5 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +218 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/customDenoise.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/customDenoise.wgsl.js +28 -0
- package/lib/renderer/wgsl/customDenoise.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +3 -0
- package/lib/renderer/wgsl/depthQuery.wgsl.js +34 -0
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.d.ts +2 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +108 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.js.map +1 -0
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +16 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +927 -0
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -0
- package/lib/scene/AmbientLight.d.ts +17 -0
- package/lib/scene/AmbientLight.js +15 -0
- package/lib/scene/AmbientLight.js.map +1 -0
- package/lib/scene/Camera.d.ts +78 -0
- package/lib/scene/Camera.js +111 -0
- package/lib/scene/Camera.js.map +1 -0
- package/lib/scene/DirectionalLight.d.ts +18 -0
- package/lib/scene/DirectionalLight.js +17 -0
- package/lib/scene/DirectionalLight.js.map +1 -0
- package/lib/scene/EnvironmentLight.d.ts +14 -0
- package/lib/scene/EnvironmentLight.js +14 -0
- package/lib/scene/EnvironmentLight.js.map +1 -0
- package/lib/scene/Geometry.d.ts +87 -0
- package/lib/scene/Geometry.js +108 -0
- package/lib/scene/Geometry.js.map +1 -0
- package/lib/scene/IESProfile.d.ts +19 -0
- package/lib/scene/IESProfile.js +165 -0
- package/lib/scene/IESProfile.js.map +1 -0
- package/lib/scene/InstancedMesh.d.ts +43 -0
- package/lib/scene/InstancedMesh.js +79 -0
- package/lib/scene/InstancedMesh.js.map +1 -0
- package/lib/scene/Mesh.d.ts +14 -0
- package/lib/scene/Mesh.js +17 -0
- package/lib/scene/Mesh.js.map +1 -0
- package/lib/scene/OpenPBRMaterial.d.ts +224 -0
- package/lib/scene/OpenPBRMaterial.js +240 -0
- package/lib/scene/OpenPBRMaterial.js.map +1 -0
- package/lib/scene/RectLight.d.ts +31 -0
- package/lib/scene/RectLight.js +26 -0
- package/lib/scene/RectLight.js.map +1 -0
- package/lib/scene/Scene.d.ts +55 -0
- package/lib/scene/Scene.js +2 -0
- package/lib/scene/Scene.js.map +1 -0
- package/lib/scene/SceneNode.d.ts +16 -0
- package/lib/scene/SceneNode.js +33 -0
- package/lib/scene/SceneNode.js.map +1 -0
- package/lib/scene/SphereLight.d.ts +22 -0
- package/lib/scene/SphereLight.js +20 -0
- package/lib/scene/SphereLight.js.map +1 -0
- package/lib/scene/SpotLight.d.ts +35 -0
- package/lib/scene/SpotLight.js +29 -0
- package/lib/scene/SpotLight.js.map +1 -0
- package/lib/scene/Texture.d.ts +38 -0
- package/lib/scene/Texture.js +37 -0
- package/lib/scene/Texture.js.map +1 -0
- package/lib/scene/anisotropyParameters.d.ts +1 -0
- package/lib/scene/anisotropyParameters.js +13 -0
- package/lib/scene/anisotropyParameters.js.map +1 -0
- package/lib/scene/geometryChanges.d.ts +5 -0
- package/lib/scene/geometryChanges.js +18 -0
- package/lib/scene/geometryChanges.js.map +1 -0
- package/lib/scene/materialTextureNames.d.ts +2 -0
- package/lib/scene/materialTextureNames.js +9 -0
- package/lib/scene/materialTextureNames.js.map +1 -0
- package/lib/scene/openPbrSchema.d.ts +400 -0
- package/lib/scene/openPbrSchema.js +149 -0
- package/lib/scene/openPbrSchema.js.map +1 -0
- package/lib/scene/thinFilmParameters.d.ts +4 -0
- package/lib/scene/thinFilmParameters.js +12 -0
- package/lib/scene/thinFilmParameters.js.map +1 -0
- package/lib/settings/display.d.ts +118 -0
- package/lib/settings/display.js +34 -0
- package/lib/settings/display.js.map +1 -0
- package/lib/settings/engine.d.ts +37 -0
- package/lib/settings/engine.js +26 -0
- package/lib/settings/engine.js.map +1 -0
- package/lib/settings/render.d.ts +178 -0
- package/lib/settings/render.js +36 -0
- package/lib/settings/render.js.map +1 -0
- package/lib/tinybvh/LICENSE +21 -0
- package/lib/tinybvh/TinyBvhBuilder.d.ts +17 -0
- package/lib/tinybvh/TinyBvhBuilder.js +211 -0
- package/lib/tinybvh/TinyBvhBuilder.js.map +1 -0
- package/lib/tinybvh/tinybvh.wasm +0 -0
- package/lib/types.d.ts +13 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/util/canvas.d.ts +2 -0
- package/lib/util/canvas.js +13 -0
- package/lib/util/canvas.js.map +1 -0
- package/lib/util/commonGeometry.d.ts +15 -0
- package/lib/util/commonGeometry.js +240 -0
- package/lib/util/commonGeometry.js.map +1 -0
- package/lib/util/events.d.ts +7 -0
- package/lib/util/events.js +23 -0
- package/lib/util/events.js.map +1 -0
- package/lib/util/frame.d.ts +2 -0
- package/lib/util/frame.js +10 -0
- package/lib/util/frame.js.map +1 -0
- package/lib/util/fromTHREE.d.ts +105 -0
- package/lib/util/fromTHREE.js +1111 -0
- package/lib/util/fromTHREE.js.map +1 -0
- package/lib/util/geometry.d.ts +13 -0
- package/lib/util/geometry.js +292 -0
- package/lib/util/geometry.js.map +1 -0
- package/lib/util/loadRGBE.d.ts +7 -0
- package/lib/util/loadRGBE.js +168 -0
- package/lib/util/loadRGBE.js.map +1 -0
- package/lib/util/math.d.ts +8 -0
- package/lib/util/math.js +64 -0
- package/lib/util/math.js.map +1 -0
- package/lib/util/mesh.d.ts +7 -0
- package/lib/util/mesh.js +20 -0
- package/lib/util/mesh.js.map +1 -0
- package/lib/util/threeDeformation.d.ts +20 -0
- package/lib/util/threeDeformation.js +218 -0
- package/lib/util/threeDeformation.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.js +3 -0
- package/lib/version.js.map +1 -0
- package/llms.txt +62 -0
- package/oidn/weights/LICENSE.txt +202 -0
- package/oidn/weights/README.md +43 -0
- package/oidn/weights/rt_hdr_alb_nrm.tza +0 -0
- package/oidn/weights/rt_hdr_alb_nrm_small.tza +0 -0
- package/package.json +124 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rayTrace.compute.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/rayTrace.compute.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_PATH_EVENTS } from '../pathLimits.js';\nimport shadowCatcherAccumulationWGSL from './chunks/shadowCatcherAccumulation.wgsl.js';\nimport depthQueryWGSL from './depthQuery.wgsl.js';\n// Portions adapted from ray-tracing-renderer@0.10.15\n// (https://github.com/hoverinc/ray-tracing-renderer).\n// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.\n\nimport commonWgsl from './chunks/common.wgsl.js';\nimport { WGPU_SCENE_FEATURE_BITS } from '../WGPUSceneFeatures.js';\nimport rayTraceCoreWgsl from './chunks/rayTraceCore.wgsl.js';\nimport { createMaterialBufferWgsl } from './chunks/materialBuffer.wgsl.js';\nimport createIntersectionWgsl from './chunks/intersect.wgsl.js';\nimport randomWgsl from './chunks/random.wgsl.js';\nimport randWgsl from './chunks/rand.wgsl.js';\nimport { createSampleMaterialWgsl } from './chunks/sampleMaterial.wgsl.js';\nimport sampleLightWgsl from './chunks/sampleLight.wgsl.js';\nimport { createOpenPbrBsdfWgsl } from './chunks/openPbrBsdf.wgsl.js';\nimport samplingWgsl from './chunks/sampling.wgsl.js';\nimport sampleShadowCatcherWgsl from './chunks/sampleShadowCatcher.wgsl.js';\nimport envMapWgsl from './chunks/envMap.wgsl.js';\nimport uvProjectionWgsl from './chunks/uvProjection.wgsl.js';\nexport const WORKGROUP_SIZE = 8;\n\nexport interface RayTraceShaderOptions {\n hasDisplacement: boolean;\n /** Include direction frames only when used, preserving the legacy shader arithmetic otherwise. */\n hasAnisotropyDirections?: boolean;\n /** Include independent coat normals only when a material uses that slot. */\n hasCoatNormals?: boolean;\n /** Split glTF BLEND primary hits deterministically instead of stochastically. */\n hasAlpha?: boolean;\n /** Any scene material uses alpha mask or blend. */\n hasSceneAlpha?: boolean;\n /** Bit mask of the BLAS layouts present in the scene (bvh2, bvh4, bvh-gpu, cwbvh). */\n blasLayoutMask?: number;\n}\n\n/** Generates the WebGPU megakernel path tracing compute shader. */\nexport default function rayTraceCompute({\n hasDisplacement,\n hasAnisotropyDirections = false,\n hasCoatNormals = false,\n hasAlpha = true,\n hasSceneAlpha = true,\n blasLayoutMask = 1\n}: RayTraceShaderOptions) {\n hasAnisotropyDirections ||= hasCoatNormals;\n const deterministicPrimaryAlpha = hasAlpha;\n const source = /* wgsl */ `\n\n${commonWgsl}\n\n${rayTraceCoreWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals })}\n\n${uvProjectionWgsl}\n\n${createMaterialBufferWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals })}\n\n${createIntersectionWgsl({ hasDisplacement, blasLayoutMask, hasAnisotropyDirections, hasCoatNormals })}\n${randWgsl}\n${randomWgsl}\n${envMapWgsl}\n\n${samplingWgsl}\n${createOpenPbrBsdfWgsl(hasAnisotropyDirections, hasCoatNormals)}\n${sampleLightWgsl}\n\n// Index of the path vertex currently being shaded.\nvar<private> bounceIndex: u32 = 0u;\n\n// Number of light candidates resampled for each NEE estimate. Interactive\n// preview caps the budget at two.\nfn neeCandidateCount() -> u32 {\n return u32(max(rtUniform.directLightCandidates, 1));\n}\n\n// Hash-based random number used to select among light candidates. It is\n// independent of the path sample stream so the candidate count does not\n// change the dimensions consumed by later bounces.\nfn lightCandidateRandom(salt: u32) -> f32 {\n // Reservoir replacement needs the full [0, 1) interval: sample1D's EPS\n // remapping makes small positive replacement probabilities unreachable.\n // Preserve the legacy sequential RNG draw in the random sampling mode so\n // subsequent path samples retain their stream; selection uses the hash.\n if (SAMPLING_PATTERN == 2) { _ = rand(); }\n let pixelID = samplingPixel.x + samplingPixel.y * u32(rtUniform.outputSize.x);\n let key = sampleSeed(sampleSeed(pixelID, pixelSampleIndex), rtUniform.sequenceSeed);\n let dimension = sampleSeed(samplingBounce, salt) ^ 0xa511e9b3u;\n return f32(sampleHash(key ^ dimension) >> 8u) * (1.0 / 16777216.0);\n}\n\n// MIS weight of a light-sampled contribution. With several resampled\n// candidates the NEE technique is drawn neeCandidateCount() times.\nfn neeMISWeight(lightPdf: f32, scatteringPdf: f32) -> f32 {\n let candidateCount = neeCandidateCount();\n if (candidateCount <= 1u) {\n return sampling_power_heuristic(lightPdf, scatteringPdf);\n }\n let weightedLightPdf = f32(candidateCount) * lightPdf;\n return weightedLightPdf /\n max(weightedLightPdf + scatteringPdf, 1e-20);\n}\n\n// MIS weight of a BSDF-sampled ray that hits a light.\nfn bsdfMISWeight(scatteringPdf: f32, lightPdf: f32) -> f32 {\n let candidateCount = neeCandidateCount();\n if (candidateCount <= 1u) {\n return sampling_power_heuristic(scatteringPdf, lightPdf);\n }\n let weightedLightPdf = f32(candidateCount) * lightPdf;\n return scatteringPdf /\n max(scatteringPdf + weightedLightPdf, 1e-20);\n}\n\n${createSampleMaterialWgsl(hasAnisotropyDirections, hasCoatNormals)}\n${sampleShadowCatcherWgsl}\n\n// Output\n@group(3) @binding(0) var<storage, read_write> outColor: array<vec4f>;\n@group(3) @binding(1) var<storage, read_write> outNormal: array<vec4f>;\n@group(3) @binding(2) var<storage, read_write> outAlbedo: array<vec4f>;\n\n${shadowCatcherAccumulationWGSL}\n@group(3) @binding(3) var<storage, read_write> outShadowCatcher: array<ShadowCatcherAccumulation>;\n\n\nfn accumulateNormalOrVariance(\n pixelIndex: u32,\n radiance: vec3f,\n normal: vec3f\n) {\n if (rtUniform.varianceMoments != 0) {\n let value = dot(radiance, luminance);\n outNormal[pixelIndex] += vec4f(value * value, 0.0, 0.0, 1.0);\n }\n else {\n outNormal[pixelIndex] += vec4f(normal, 1.0);\n }\n}\n\n// Moments of the per-sample value the built-in denoiser compares, used to\n// estimate the variance of each pixel's mean.\nfn accumulateDenoiseMoments(pixelIndex: u32, value: f32) {\n outShadowCatcher[pixelIndex].moments += vec4f(value, value * value, 0.0, 0.0);\n}\n\n\nstruct RayTraceAuxiliary {\n // Denoising guides and auxiliary pixel classification.\n albedo: vec3f,\n isShadowCatcher: bool,\n normal: vec3f,\n isBlank: bool,\n}\n\nfn groundedSurfaceDistance(point: vec3f, height: f32, radius: f32) -> f32 {\n let pointLength = length(point);\n if (pointLength < 0.00001) {\n return -radius;\n }\n\n let originalY = radius * point.y / pointLength;\n let transitionY = -1.5 * height;\n var surfaceRadius: f32;\n if (originalY >= 0.0) {\n surfaceRadius = radius;\n }\n else if (originalY < transitionY) {\n surfaceRadius = -height * pointLength / point.y;\n }\n else {\n let factor = 1.0\n - originalY * originalY / (3.0 * transitionY * transitionY);\n surfaceRadius = radius * factor;\n }\n return pointLength - surfaceRadius;\n}\n\nfn groundedBackgroundDirection(origin: vec3f, direction: vec3f) -> vec3f {\n if (!USE_GROUNDED_BACKGROUND) {\n return direction;\n }\n let params = rtUniform.groundedBackgroundParams;\n let rayDirection = normalize(direction);\n let center = vec3f(\n rtUniform.groundedBackgroundCenter.x,\n params.z + params.x,\n rtUniform.groundedBackgroundCenter.y\n );\n let localOrigin = origin - center;\n let projectedOrigin = dot(localOrigin, rayDirection);\n let discriminant = projectedOrigin * projectedOrigin\n - dot(localOrigin, localOrigin) + params.y * params.y;\n if (\n discriminant <= 0.0\n || groundedSurfaceDistance(localOrigin, params.x, params.y) > 0.0\n ) {\n return direction;\n }\n\n var farDistance = -projectedOrigin + sqrt(discriminant);\n if (farDistance <= 0.0) {\n return direction;\n }\n\n let sphereHit = localOrigin + rayDirection * farDistance;\n if (sphereHit.y >= 0.0) {\n return normalize(sphereHit);\n }\n\n if (rayDirection.y < -0.00001 && params.y > 1.5 * params.x) {\n let groundDistance = (-params.x - localOrigin.y) / rayDirection.y;\n let groundHit = localOrigin + rayDirection * groundDistance;\n let groundRadius = (2.0 / 3.0)\n * sqrt(params.y * params.y - 2.25 * params.x * params.x);\n if (groundDistance > 0.0 && length(groundHit.xz) <= groundRadius) {\n return normalize(groundHit);\n }\n }\n\n var nearDistance = 0.0;\n for (var i = 0; i < 14; i++) {\n let middleDistance = (nearDistance + farDistance) * 0.5;\n let middlePoint = localOrigin + rayDirection * middleDistance;\n if (groundedSurfaceDistance(middlePoint, params.x, params.y) > 0.0) {\n farDistance = middleDistance;\n }\n else {\n nearDistance = middleDistance;\n }\n }\n let hit = localOrigin + rayDirection * ((nearDistance + farDistance) * 0.5);\n return normalize(hit);\n}\n\nfn sampleSceneBackground(ray: Ray) -> vec4f {\n var bg = vec4f(0.0);\n if (USE_BACKGROUND_MAP) {\n let backgroundDirection = groundedBackgroundDirection(ray.o, ray.d);\n bg = textureLinear(backgroundMap, cartesianToEquirect(backgroundDirection));\n }\n else if (USE_BACKGROUND) {\n bg = rtUniform.backgroundColor;\n }\n else if (USE_ENVMAP) {\n bg = textureLinear(envMap, cartesianToEquirect(ray.d));\n }\n return bg;\n}\n\nfn sampleSpectralSceneBackground(ray: Ray, wavelength: f32) -> vec4f {\n let bg = sampleSceneBackground(ray);\n if (SPECTRAL) {\n return vec4f(sampling_spectral_rgb_filter(bg.rgb, wavelength), bg.a);\n }\n return bg;\n}\n\nfn bounce(uv: vec2f, path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) {\n samplingBounce = u32(max(*depth, 0));\n let matType = (*ma).materialType;\n let isShadowCatcher = matType == SHADOW_CATCHER;\n if (isShadowCatcher) {\n if ((*path).fromEye) {\n (*si).hit = false;\n }\n else {\n // The catcher only contributes to the separate shadow mask. Secondary\n // rays must see the environment behind it instead of its default white\n // material, otherwise it appears in reflections.\n if (USE_ENVMAP) {\n if ((*path).isNextRefraction) {\n // A camera-visible transmitted ray can hit the invisible catcher\n // before the grounded skybox. Preserve the displayed projection.\n let bg = sampleSpectralSceneBackground(\n (*path).ray,\n (*si).wavelength\n );\n let backgroundMisWeight = select(bsdfMISWeight((*path).scatteringPdf,\n envMapPdf(cartesianToEquirect((*path).ray.d)) * rtUniform.envLightPmf),\n 1.0, (*path).scatteringIsDelta);\n (*path).li += backgroundMisWeight * (*path).beta * bg.rgb * bg.a;\n (*path).alpha = max((*path).alpha, bg.a);\n }\n else {\n let envUv = cartesianToEquirect((*path).ray.d);\n var emission = textureLinear(envMap, envUv).rgb;\n if (SPECTRAL) {\n emission = sampling_spectral_rgb_filter(emission, (*si).wavelength);\n }\n (*path).li += (*path).beta * emission *\n bsdfMISWeight((*path).scatteringPdf, envMapPdf(envUv));\n }\n }\n else {\n let bg = sampleSpectralSceneBackground(\n (*path).ray,\n (*si).wavelength\n );\n (*path).li += (*path).beta * bg.rgb * bg.a;\n }\n (*path).abort = true;\n return;\n }\n }\n if (!(*si).hit) {\n // The spectral integrator traces red, green, and blue paths separately.\n // Split background radiance by wavelength as well so the three paths\n // reconstruct the skybox instead of adding three full RGB copies.\n let bg = sampleSpectralSceneBackground(\n (*path).ray,\n (*si).wavelength\n );\n if ((*path).fromEye) {\n // Sample from background if first ray not hit anything.\n (*path).li = (*path).beta * bg.rgb * bg.a;\n (*path).alpha = bg.a;\n // Only treat as blank pixels when the background is transparent\n (*outAux).isBlank = bg.a < 0.001 ||\n (USE_BACKGROUND && !USE_BACKGROUND_MAP);\n }\n else {\n let cam = initCameraRay(uv);\n let towardsCam = dot(cam.d, (*path).ray.d) > 0.0;\n if (rtUniform.transmissiveOutputAlphaMin < 1.0) {\n if (towardsCam) {\n (*path).alpha = max((*path).alpha, bg.a);\n } else {\n (*path).alpha = 1.0;\n }\n }\n if (!USE_ENVMAP) {\n // A display background is not an illumination environment, but a\n // visible secondary ray (e.g. through glass) still resolves it.\n if (towardsCam) {\n // This is a terminal BSDF-hit contribution, not a replacement for\n // NEE accumulated at earlier vertices on the same path.\n (*path).li += (*path).beta *\n bsdfMISWeight((*path).scatteringPdf, 1.0) * bg.rgb;\n }\n }\n }\n (*path).abort = true;\n return;\n }\n\n var sampleIgnored = false;\n if ((matType == STANDARD || matType == UNLIT)) {\n let alpha = clamp((*ma).alpha, 0.0, 1.0);\n \n if (alpha < 1.0) {\n // Alpha is stochastic coverage. Keep accepted surface radiance at full\n // weight instead of multiplying it by alpha a second time.\n if (alpha <= 0.0 || hashedSample(3u) > alpha) {\n sampleIgnored = true;\n }\n }\n if (!sampleIgnored && rtUniform.transmissiveOutputAlphaMin < 1.0) {\n // A selected stochastic coverage sample is fully covered. Ignored\n // samples leave output alpha untouched and continue to the back layer.\n let outputAlpha = max(1.0 - (*ma).transmissionWeight, 1.0 - pow(1.0 - rtUniform.transmissiveOutputAlphaMin, f32(*depth)));\n (*path).alpha = max(outputAlpha, (*path).alpha);\n }\n if (!sampleIgnored) {\n bounceIndex = u32(max(*depth, 0));\n SampleMaterial(si, ma, path);\n }\n else {\n // Alpha-null traversal does not consume the receiver event. The first\n // accepted surface behind it is still the receiver for NEE/AOVs.\n (*path).ray.o = (*si).position + (*path).ray.d * EPS;\n }\n }\n\n if (!(*si).albedoSampled && !sampleIgnored) {\n // Select denoising guides.\n if ((matType == STANDARD || matType == UNLIT)) {\n if (!((*ma).transmissionWeight > 0.5 ||\n ((*ma).specularRoughness <= 0.02 && (*ma).baseMetalness > 0.98))) {\n (*outAux).albedo = (*ma).baseColor;\n (*outAux).normal = select(\n (*si).normal,\n -(*si).normal,\n dot(\n (*si).normal,\n (*si).position - cameraUniform.viewInv[3].xyz\n ) > 0.0\n );\n (*si).albedoSampled = true;\n }\n // TODO pick albedo and normal on the surface if ray is too deep and can't hit any rough or opaque surfaces.\n if (*depth > 4) {\n (*si).albedoSampled = true;\n }\n }\n }\n\n // Russian roulette with throughput compensation.\n if (USE_RR) {\n if (*depth >= RR_MAX && !sampleIgnored) {\n let rouletteBeta = (*path).beta;\n // Max-component survival (pbrt-v4) avoids over-amplifying saturated paths.\n let maxComponent = max(max(rouletteBeta.x, rouletteBeta.y), rouletteBeta.z);\n let q: f32 = max(0.0, 1.0 - maxComponent);\n if (sample1D(bounceDim(RUSSIAN_ROULETTE)) < q) {\n // TODO we force use alpha 1.0 here.\n // To avoid the glass pixels is transparent even if it's on an opaque object.\n (*path).alpha = 1.0;\n (*path).abort = true;\n }\n else {\n (*path).beta /= 1.0 - q;\n }\n }\n }\n if ((*path).abort) {\n return;\n }\n\n intersectScene((*path).ray, si, *depth, true, (*path).isNextRefraction);\n getMaterial(ma, (*si).materialIndex, (*si).uv, (*si).uv1, (*si).instanceIndex);\n\n if (SPECTRAL) {\n // Is glass\n if ((*ma).transmissionWeight > 0.001) {\n (*ma).specularIor = sampling_cauchy_ior(\n (*si).wavelength,\n (*ma).specularIor,\n (*ma).transmissionDispersionScale,\n (*ma).dispersionAbbeNumber\n );\n }\n }\n\n if (sampleIgnored) {\n return;\n }\n\n // Use light if hit the light\n var lightSample: LightSampleRec;\n let isAlphaOccluded = hashedSample(3u) < (*ma).alpha;\n for (var i = 0; i < rtUniform.lightsCount; i++) {\n // Fetch light Data\n let light: Light = analyticLights[i];\n let d = intersectLight((*path).ray, light, &lightSample);\n lightSample.pdf *= light.selectionPmf;\n let occluded = (*si).hit && d > distance((*si).position, (*path).ray.o);\n if (d != INF && !(occluded && isAlphaOccluded)) {\n let misWeight = bsdfMISWeight((*path).scatteringPdf, lightSample.pdf);\n if (SPECTRAL) {\n lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, (*si).wavelength);\n }\n (*path).li += misWeight * (*path).beta * lightSample.emission;\n (*path).alpha = 1.0;\n (*path).abort = true;\n }\n }\n\n if (USE_ENVMAP) {\n if (!((*si).hit && isAlphaOccluded)) {\n if ((*path).isNextRefraction) {\n // Camera-visible transmission follows the displayed background,\n // including grounded projection. Other rays use the raw environment\n // map as the physically sampled lighting source.\n let bg = sampleSpectralSceneBackground(\n (*path).ray,\n (*si).wavelength\n );\n let backgroundMisWeight = select(bsdfMISWeight((*path).scatteringPdf,\n envMapPdf(cartesianToEquirect((*path).ray.d)) * rtUniform.envLightPmf),\n 1.0, (*path).scatteringIsDelta);\n (*path).li += backgroundMisWeight * (*path).beta * bg.rgb * bg.a;\n (*path).alpha = max((*path).alpha, bg.a);\n (*path).abort = true;\n return;\n }\n let _uv = cartesianToEquirect((*path).ray.d);\n var emission = textureLinear(envMap, _uv).rgb;\n let misWeight = bsdfMISWeight(\n (*path).scatteringPdf,\n envMapPdf(_uv) * rtUniform.envLightPmf\n );\n if (SPECTRAL) {\n emission = sampling_spectral_rgb_filter(emission, (*si).wavelength);\n }\n // TODO force the min alpha to be 1 when showing envmap as background\n if (!USE_BACKGROUND) {\n (*path).alpha = 1.0;\n }\n (*path).li += (*path).beta * emission * misWeight;\n (*path).abort = true;\n }\n }\n\n *depth = *depth + 1;\n}\n\nfn initCameraRay(coord: vec2f) -> Ray {\n let origin = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, -1.0, 1.0);\n let center = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, 1.0, 1.0);\n var cam: Ray;\n initRay(&cam, origin.xyz / origin.w, normalize(center.xyz * origin.w - origin.xyz * center.w));\n\n return cam;\n}\n\n\nfn bevelCubicSample(radius: f32, xi: f32) -> vec2f {\n var x = 0.25;\n for (var iteration = 0; iteration < 10; iteration++) {\n let x2 = x * x;\n let x3 = x2 * x;\n let oneMinusX = 1.0 - x;\n let value = 10.0 * x2 - 20.0 * x3 + 15.0 * x2 * x2 -\n 4.0 * x2 * x3 - xi;\n let derivative = 20.0 * x * oneMinusX * oneMinusX * oneMinusX;\n if (abs(value) < 1e-6 || derivative == 0.0) { break; }\n x = clamp(x - value / derivative, 0.0, 1.0);\n }\n let diskRadius = x * radius;\n return vec2f(diskRadius, sqrt(max(radius * radius - diskRadius * diskRadius, 0.0)));\n}\n\nfn bevelCubicPdf(radius: f32, distanceToSource: f32) -> f32 {\n if (distanceToSource >= radius) { return 0.0; }\n let falloff = radius - distanceToSource;\n return falloff * falloff * falloff;\n}\n\n// Shader bevel. Usage: docs/materials.md (Renderer extensions)\nfn getBevelNormal(source: SurfaceInteraction, radius: f32) -> vec3f {\n var geometricNormal = source.faceNormal;\n if (dot(geometricNormal, source.vertexNormal) < 0.0) {\n geometricNormal = -geometricNormal;\n }\n var tangent: vec3f;\n var bitangent: vec3f;\n sampling_orthonormal_basis(geometricNormal, &tangent, &bitangent);\n var normalSum = vec3f(0.0);\n\n for (var sampleIndex = 0; sampleIndex < BEVEL_SAMPLES; sampleIndex++) {\n let bevelRnd = sample2D(CAMERA_BEVEL_BASE + u32(sampleIndex));\n var axisSample = bevelRnd.x;\n let radialSample = bevelRnd.y;\n var diskNormal = geometricNormal;\n var diskTangent = tangent;\n var diskBitangent = bitangent;\n var pickPdfNormal = 0.5;\n var pickPdfTangent = 0.25;\n var pickPdfBitangent = 0.25;\n if (axisSample < 0.5) {\n axisSample *= 2.0;\n }\n else if (axisSample < 0.75) {\n let swapAxis = diskNormal;\n diskNormal = diskTangent;\n diskTangent = swapAxis;\n pickPdfNormal = 0.25;\n pickPdfTangent = 0.5;\n axisSample = (axisSample - 0.5) * 4.0;\n }\n else {\n let swapAxis = diskNormal;\n diskNormal = diskBitangent;\n diskBitangent = swapAxis;\n pickPdfNormal = 0.25;\n pickPdfBitangent = 0.5;\n axisSample = (axisSample - 0.75) * 4.0;\n }\n\n let diskSample = bevelCubicSample(radius, radialSample);\n let phi = TWOPI * axisSample;\n let diskOffset = diskSample.x *\n (cos(phi) * diskTangent + sin(phi) * diskBitangent);\n var ray: Ray;\n initRay(\n &ray,\n source.position + diskNormal * diskSample.y + diskOffset,\n -diskNormal\n );\n var hit: SurfaceInteraction;\n intersectSceneBevel(\n ray,\n &hit,\n source.instanceIndex,\n max(2.0 * diskSample.y, EPS)\n );\n if (!hit.hit) { continue; }\n\n let pdfNormal = pickPdfNormal * abs(dot(diskNormal, hit.faceNormal));\n let pdfTangent = pickPdfTangent * abs(dot(diskTangent, hit.faceNormal));\n let pdfBitangent = pickPdfBitangent * abs(dot(diskBitangent, hit.faceNormal));\n var weight = pdfNormal / max(\n pdfNormal * pdfNormal + pdfTangent * pdfTangent +\n pdfBitangent * pdfBitangent,\n 1e-8\n );\n weight *= bevelCubicPdf(radius, distance(hit.position, source.position)) /\n max(bevelCubicPdf(radius, diskSample.x), 1e-8);\n normalSum += weight * hit.vertexNormal;\n }\n\n if (dot(normalSum, normalSum) <= 1e-12) { return source.normal; }\n let bevelVertexNormal = normalize(normalSum);\n let result = source.normal + bevelVertexNormal - source.vertexNormal;\n if (dot(result, result) > 1e-12) { return normalize(result); }\n return source.normal;\n}\n\nfn integrateOnePathSample(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {\n var path: Path;\n path.ray = ray;\n path.li = vec3f(0.0);\n path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);\n path.beta = vec3f(1.0);\n path.fromEye = true;\n path.scatteringPdf = 0.0;\n path.scatteringIsDelta = false;\n path.isNextRefraction = false;\n path.abort = false;\n\n let isNotTransparent = (*ma).transmissionWeight < 0.001 && (*ma).subsurfaceWeight < 0.001 && (*ma).alpha > 0.99;\n let bounceLimit = max(rtUniform.bounces, 0);\n var depth = 0;\n // Transparent paths may take up to three times the configured bounces.\n for (var idx: i32 = 0; idx < min(bounceLimit * 3, ${MAX_PATH_EVENTS}); idx = idx + 1) {\n if (isNotTransparent && idx > bounceLimit) {\n path.abort = true;\n }\n if (path.abort) {\n break;\n }\n bounce(uv, &path, &depth, si, ma, outAux);\n }\n\n return vec4f(path.li, path.alpha);\n}\n\nfn integrateOnePath(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {\n ${deterministicPrimaryAlpha ? /* wgsl */ `let coverage = clamp((*ma).alpha, 0.0, 1.0);\n if (!(*si).hit || ((*ma).materialType != STANDARD && (*ma).materialType != UNLIT) || coverage >= 1.0) {\n return integrateOnePathSample(uv, si, ray, ma, outAux);\n }\n\n // glTF BLEND is source-over opacity, not a physical glass boundary. Split\n // the primary ray so reflected radiance is attenuated by alpha every sample\n // while the complementary branch continues straight to the scene behind it.\n // Secondary alpha hits remain stochastic to avoid exponential path growth.\n var backRay = ray;\n backRay.o = (*si).position + ray.d * (EPS * 0.02);\n var backSi = *si;\n backSi.albedoSampled = false;\n intersectScene(backRay, &backSi, 0, false, false);\n var backMa: OpenPbrResolvedMaterial;\n getMaterial(&backMa, backSi.materialIndex, backSi.uv, backSi.uv1, backSi.instanceIndex);\n var backAux = *outAux;\n if (backSi.hit && backMa.materialType == STANDARD) {\n backAux.albedo = select(\n backMa.baseColor,\n vec3f(1.0),\n backMa.transmissionWeight > 0.5\n );\n backAux.normal = select(\n backSi.normal,\n -backSi.normal,\n dot(\n backSi.normal,\n backSi.position - cameraUniform.viewInv[3].xyz\n ) > 0.0\n );\n backSi.albedoSampled = backMa.transmissionWeight > 0.5;\n }\n let back = integrateOnePathSample(\n uv, &backSi, backRay, &backMa, &backAux\n );\n if (coverage <= 0.0) {\n *outAux = backAux;\n return back;\n }\n\n var frontSi = *si;\n var frontMa = *ma;\n frontMa.alpha = 1.0;\n var frontAux = *outAux;\n let front = integrateOnePathSample(\n uv, &frontSi, ray, &frontMa, &frontAux\n );\n (*outAux).albedo = mix(backAux.albedo, frontAux.albedo, coverage);\n let blendedNormal = mix(backAux.normal, frontAux.normal, coverage);\n (*outAux).normal = select(\n vec3f(0.0),\n normalize(blendedNormal),\n dot(blendedNormal, blendedNormal) > 1e-12\n );\n (*outAux).isBlank = backAux.isBlank && frontAux.isBlank;\n (*outAux).isShadowCatcher = backAux.isShadowCatcher && frontAux.isShadowCatcher;\n return mix(back, front, coverage);` : /* wgsl */ `return integrateOnePathSample(uv, si, ray, ma, outAux);`}\n}\n\n// Path tracing integrator as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Path_Tracing.html#\nfn integrator(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {\n var si: SurfaceInteraction;\n var ma: OpenPbrResolvedMaterial;\n si.albedoSampled = false;\n si.mediumType = 0;\n si.mediumExtinction = vec3f(0.0);\n si.mediumScattering = vec3f(0.0);\n si.mediumAnisotropy = 0.0;\n si.barycentrics = vec2f(0.0);\n\n // TODO not put tMax in ray. So we don't need to use pointer of ray here.\n intersectScene(ray, &si, 0, false, false);\n getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex);\n\n if (ma.materialType == SHADOW_CATCHER) {\n (*outAux).isShadowCatcher = true;\n // The composed denoising input includes this receiver's shadow. Supply\n // neutral reflectance and its shading normal, independent of visibility.\n (*outAux).albedo = vec3f(1.0);\n (*outAux).normal = select(si.normal, -si.normal, dot(si.normal, ray.d) > 0.0);\n var path: Path;\n path.ray = ray;\n path.fromEye = true;\n sampleShadowCatcher(si, 0, &path);\n // RGB stores primary catcher coverage independently from the stochastic\n // visibility in alpha. Composition uses this raw coverage to clip any\n // shadow-mask denoising bleed at model silhouettes.\n return vec4f(vec3f(1.0), path.alpha);\n }\n else {\n if (HAS_BEVEL && rtUniform.bevel != 0) {\n if (ma.bevel > 0.0) {\n si.normal = getBevelNormal(si, ma.bevel);\n }\n }\n\n // Store a clean first-hit fallback. Glass retains this stable guide;\n // other delta paths may replace it at their first non-delta hit.\n if (si.hit && (ma.materialType == STANDARD || ma.materialType == UNLIT)) {\n (*outAux).albedo = select(ma.baseColor, vec3f(1.0), ma.transmissionWeight > 0.5);\n (*outAux).normal = select(\n si.normal,\n -si.normal,\n dot(si.normal, si.position - cameraUniform.viewInv[3].xyz) > 0.0\n );\n\n // Do not replace a glass guide with a randomly selected downstream\n // refraction/reflection hit; OIDN auxiliary features must stay clean.\n si.albedoSampled = ma.transmissionWeight > 0.5;\n }\n\n (*outAux).isShadowCatcher = false;\n\n if (SPECTRAL) {\n // Keep one source-level integrateOnePath call for both interactive\n // preview and offline RGB splitting. A runtime loop bound prevents the\n // WGSL compiler from cloning the full path graph three times while the\n // uniform still selects the exact existing preview/offline behavior.\n let rgbWaveLengths = array<f32, 3>(650.0, 510.0, 475.0);\n var colAccum = vec3f(0.0);\n var alpha = 0.0;\n var accumulatedGuideAlbedo = vec3f(0.0);\n var accumulatedGuideNormal = vec3f(0.0);\n var allBlank = true;\n var si2 = si;\n var ma2 = ma;\n let wavelengthRngState = s0;\n let wavelengthHashedCounter = hashedCounter;\n let singleWavelength = rtUniform.dispersionWavelengths == 1;\n let dispersivePrimary = si.hit &&\n ma.transmissionWeight > 0.001 &&\n ma.transmissionDispersionScale > 0.001;\n let wavelengthCount = select(3, 1, singleWavelength);\n var heroWavelengthIndex = 0;\n if (singleWavelength && dispersivePrimary) {\n // Stochastic hero wavelength: one RGB channel per pixel keeps the\n // preview spectral at one-third of the full three-path cost.\n heroWavelengthIndex = min(i32(floor(sample1D(CAMERA_WAVELENGTH) * 3.0)), 2);\n }\n for (var i = 0; i < wavelengthCount; i++) {\n // Common random numbers keep Monte Carlo error correlated between\n // RGB wavelengths. This removes much of the colored variance that\n // otherwise turns into dirty chromatic patches after OIDN.\n if (!singleWavelength) {\n s0 = wavelengthRngState;\n hashedCounter = wavelengthHashedCounter;\n samplingBounce = 0u;\n }\n si.wavelength = 0.0;\n if (!singleWavelength || dispersivePrimary) {\n si.wavelength = rgbWaveLengths[select(i, heroWavelengthIndex, singleWavelength)];\n ma.specularIor = sampling_cauchy_ior(\n si.wavelength,\n ma.specularIor,\n ma.transmissionDispersionScale,\n ma.dispersionAbbeNumber\n );\n }\n var wavelengthAux: RayTraceAuxiliary;\n if (singleWavelength) {\n wavelengthAux = *outAux;\n } else {\n wavelengthAux.albedo = (*outAux).albedo;\n wavelengthAux.normal = (*outAux).normal;\n wavelengthAux.isBlank = false;\n wavelengthAux.isShadowCatcher = false;\n }\n let res = integrateOnePath(uv, &si, ray, &ma, &wavelengthAux);\n if (singleWavelength) {\n *outAux = wavelengthAux;\n let scale = select(1.0, 3.0, dispersivePrimary);\n return vec4f(res.rgb * scale, res.a);\n }\n colAccum += res.rgb;\n alpha = max(alpha, res.a);\n accumulatedGuideAlbedo += wavelengthAux.albedo;\n accumulatedGuideNormal += wavelengthAux.normal;\n allBlank = allBlank && wavelengthAux.isBlank;\n si = si2;\n ma = ma2;\n }\n (*outAux).albedo = accumulatedGuideAlbedo / 3.0;\n (*outAux).normal = accumulatedGuideNormal / 3.0;\n (*outAux).isBlank = allBlank;\n return vec4f(colAccum, alpha);\n }\n else {\n return integrateOnePath(uv, &si, ray, &ma, outAux);\n }\n }\n}\n\nfn sampleCircle(ip: vec2f) -> vec2f {\n let p = 2.0 * ip - 1.0;\n let greater = abs(p.x) > abs(p.y);\n let r = select(p.y, p.x, greater);\n let theta = select(PI * (0.5 - 0.25 * p.x / p.y), 0.25 * PI * p.y / p.x, greater);\n return r * vec2f(cos(theta), sin(theta));\n}\n\n\n@compute @workgroup_size(${WORKGROUP_SIZE}, ${WORKGROUP_SIZE}, 1)\nfn main(@builtin(global_invocation_id) globalId: vec3u) {\n let outputSize = rtUniform.outputSize;\n let scaleOffset = rtUniform.scaleOffset;\n var jitter = rtUniform.jitter;\n // TODO if outputSize is not multiple of 8?\n let coord = globalId.xy * vec2u(scaleOffset.xy) + vec2u(scaleOffset.zw);\n if (coord.x >= u32(outputSize.x) || coord.y >= u32(outputSize.y)) {\n return;\n }\n let idx = coord.x + coord.y * u32(outputSize.x);\n\n if (\n rtUniform.adaptiveSampling != 0 &&\n outNormal[idx].a >= textureLoad(\n adaptiveSampleTargets,\n vec2i(coord),\n 0\n ).r\n ) {\n return;\n }\n\n // Match WebGL's rasterized v_Texcoord, whose sample is at the center of\n // each pixel. Keeping the same origin is material relevant: a half-pixel\n // shift moves a narrow metal highlight across several pixels.\n let uv = (vec2<f32>(f32(coord.x), f32(coord.y)) + vec2f(0.5)) / outputSize;\n\n samplingPixel = coord;\n pixelSampleIndex = u32(outNormal[idx].a) + rtUniform.sampleSequenceOffset;\n samplingBounce = 0u; hashedCounter = 0u;\n if (SAMPLING_PATTERN == 0 || SAMPLING_PATTERN == 1) {\n jitter = (sample2D(CAMERA_PIXEL) - 0.5) / outputSize;\n }\n rng_initialize(coord, i32(pixelSampleIndex ^ sampleHash(rtUniform.sequenceSeed)));\n var cam = initCameraRay(uv + jitter);\n\n if (cameraUniform.apertureRadius > 0.0) {\n // Thin lens: the focus plane is perpendicular to the view direction.\n let eye = cameraUniform.viewInv[3].xyz;\n let forward = -normalize(cameraUniform.viewInv[2].xyz);\n let focusPoint = eye + cam.d * (cameraUniform.focusDistance / dot(cam.d, forward));\n let lensPoint = cameraUniform.apertureRadius * sampleCircle(sample2D(CAMERA_LENS));\n let origin = (cameraUniform.viewInv * vec4f(lensPoint, 0.0, 1.0)).xyz;\n let dir = normalize(focusPoint - origin);\n initRay(&cam, origin, dir);\n }\n\n var outAux: RayTraceAuxiliary;\n outAux.albedo = vec3f(0.0);\n outAux.normal = vec3f(0.0);\n outAux.isBlank = false;\n outAux.isShadowCatcher = false;\n var liAndAlpha = integrator(uv + jitter, cam, &outAux);\n\n // Clamp at Integration Level to reduce fireflies.\n // TODO Path level configuration?\n if (rtUniform.clamping > 0.0) {\n let clamping = rtUniform.clamping;\n liAndAlpha = vec4(clamp(liAndAlpha.rgb, -vec3f(clamping), vec3f(clamping)), liAndAlpha.a);\n }\n if (!(liAndAlpha.x < INF && liAndAlpha.x > -EPS)) {\n liAndAlpha = vec4f(0.0, 0.0, 0.0, 1.0);\n }\n\n if (outAux.isShadowCatcher) {\n // The catcher is invisible, so the main color at this pixel must still\n // contain whatever the camera ray would have seen behind it.\n let backgroundSample = sampleSceneBackground(cam);\n let backgroundHit = select(0.0, 1.0, backgroundSample.a >= 0.01);\n let backgroundPremultiplied = vec4f(backgroundSample.rgb * backgroundSample.a, backgroundSample.a);\n // Keep the background contribution separate from geometry at silhouettes.\n // mask: catcher coverage, background alpha, background hits, shadow opacity.\n outShadowCatcher[idx].mask += vec4f(1.0, backgroundSample.a, backgroundHit, liAndAlpha.a);\n outShadowCatcher[idx].background += backgroundPremultiplied;\n outColor[idx] += backgroundPremultiplied;\n outAlbedo[idx] += vec4f(outAux.albedo, backgroundHit);\n accumulateNormalOrVariance(idx, backgroundSample.rgb, outAux.normal);\n // The composed catcher is the background darkened by the shadow. Over a\n // transparent background the shadow is only its opacity.\n let visibility = 1.0 - liAndAlpha.a;\n accumulateDenoiseMoments(idx, visibility * select(\n 1.0, dot(backgroundSample.rgb, luminance), backgroundSample.a >= 0.01\n ));\n }\n else {\n outColor[idx] += liAndAlpha;\n outAlbedo[idx] += vec4f(outAux.albedo, select(1.0, 0.0, outAux.isBlank));\n accumulateNormalOrVariance(idx, liAndAlpha.rgb, outAux.normal);\n accumulateDenoiseMoments(idx, dot(liAndAlpha.rgb, luminance));\n }\n}\n`;\n // The query entry point shares the exact BVH and material implementation.\n // It has no effect on the beauty entry point or its bindings.\n // Gate optional material layers on scene-level feature flags so drivers can\n // skip the unused BSDF lobes.\n let specializedSource = source + depthQueryWGSL;\n const backgroundBits: Record<string, number> = {\n USE_BACKGROUND: 1,\n USE_BACKGROUND_MAP: 2,\n USE_GROUNDED_BACKGROUND: 4\n };\n specializedSource = specializedSource.replace(\n /\\b(?:USE_BACKGROUND|USE_BACKGROUND_MAP|USE_GROUNDED_BACKGROUND)\\b/g,\n (name) => `((rtUniform.backgroundFlags & ${backgroundBits[name]}) != 0)`\n );\n specializedSource = specializedSource.replace(\n new RegExp(`\\\\b(?:${Object.keys(WGPU_SCENE_FEATURE_BITS).join('|')})\\\\b`, 'g'),\n name => `((rtUniform.sceneFeatureFlags & ${WGPU_SCENE_FEATURE_BITS[name]}u) != 0u)`\n );\n return specializedSource;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ColorRGB } from '../types.js';
|
|
2
|
+
/** Uniform environment radiance. */
|
|
3
|
+
export default class AmbientLight {
|
|
4
|
+
/** Light discriminator. */
|
|
5
|
+
readonly type: "AmbientLight";
|
|
6
|
+
/** Linear RGB color. Default `[1, 1, 1]`. */
|
|
7
|
+
color: ColorRGB;
|
|
8
|
+
/** Uniform radiance multiplier. Default `1`. */
|
|
9
|
+
intensity: number;
|
|
10
|
+
/** Creates a light; omitted options retain the field defaults. */
|
|
11
|
+
constructor(params?: {
|
|
12
|
+
/** Linear RGB color. Default `[1, 1, 1]`. */
|
|
13
|
+
color?: ColorRGB;
|
|
14
|
+
/** Uniform radiance multiplier. Default `1`. */
|
|
15
|
+
intensity?: number;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Uniform environment radiance. */
|
|
2
|
+
export default class AmbientLight {
|
|
3
|
+
/** Light discriminator. */
|
|
4
|
+
type = 'AmbientLight';
|
|
5
|
+
/** Linear RGB color. Default `[1, 1, 1]`. */
|
|
6
|
+
color = [1, 1, 1];
|
|
7
|
+
/** Uniform radiance multiplier. Default `1`. */
|
|
8
|
+
intensity = 1;
|
|
9
|
+
/** Creates a light; omitted options retain the field defaults. */
|
|
10
|
+
constructor(params = {}) {
|
|
11
|
+
this.color = params.color ?? [1, 1, 1];
|
|
12
|
+
this.intensity = params.intensity ?? 1;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=AmbientLight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AmbientLight.js","sourceRoot":"","sources":["../../src/scene/AmbientLight.ts"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,2BAA2B;IAClB,IAAI,GAAG,cAAuB,CAAC;IACxC,6CAA6C;IAC7C,KAAK,GAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,gDAAgD;IAChD,SAAS,GAAW,CAAC,CAAC;IAEtB,kEAAkE;IAClE,YAAY,SAKR,EAAE;QACJ,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACzC,CAAC;CACF","sourcesContent":["import type { ColorRGB } from '../types.js';\n\n/** Uniform environment radiance. */\nexport default class AmbientLight {\n /** Light discriminator. */\n readonly type = 'AmbientLight' as const;\n /** Linear RGB color. Default `[1, 1, 1]`. */\n color: ColorRGB = [1, 1, 1];\n /** Uniform radiance multiplier. Default `1`. */\n intensity: number = 1;\n\n /** Creates a light; omitted options retain the field defaults. */\n constructor(params: {\n /** Linear RGB color. Default `[1, 1, 1]`. */\n color?: ColorRGB;\n /** Uniform radiance multiplier. Default `1`. */\n intensity?: number;\n } = {}) {\n this.color = params.color ?? [1, 1, 1];\n this.intensity = params.intensity ?? 1;\n }\n}\n"]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Mat4 } from '../types.js';
|
|
2
|
+
import SceneNode from './SceneNode.js';
|
|
3
|
+
export type Projection = 'perspective' | 'orthographic';
|
|
4
|
+
/**
|
|
5
|
+
* Perspective or orthographic camera. Position and orient it with
|
|
6
|
+
* `transform` (camera-to-world), via `position` and `lookAt()`.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const camera = new Camera({ projection: 'perspective', fov: 45, near: 0.1, far: 100 });
|
|
10
|
+
* camera.position = [0, 1, 5]; camera.lookAt([0, 0, 0]);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export default class Camera extends SceneNode {
|
|
14
|
+
/** Camera projection mode. Default `perspective`. */
|
|
15
|
+
projection: Projection;
|
|
16
|
+
/**
|
|
17
|
+
* Lens f-number (focal length / aperture diameter) for depth of field.
|
|
18
|
+
* Smaller values blur more. `0` disables depth of field (pinhole camera).
|
|
19
|
+
* Orthographic cameras ignore it. Default `0`.
|
|
20
|
+
*/
|
|
21
|
+
fStop: number;
|
|
22
|
+
/**
|
|
23
|
+
* Distance from the lens to the plane in focus, measured along the view
|
|
24
|
+
* direction, in scene units. Default `10`.
|
|
25
|
+
*/
|
|
26
|
+
focusDistance: number;
|
|
27
|
+
/**
|
|
28
|
+
* Sensor height in millimetres. With `fov` and `zoom` it defines the focal
|
|
29
|
+
* length, and so the aperture size for a given `fStop`. Default `24`
|
|
30
|
+
* (full-frame 35 mm).
|
|
31
|
+
*/
|
|
32
|
+
sensorHeight: number;
|
|
33
|
+
/**
|
|
34
|
+
* Length of one scene unit in metres, used to convert the lens size in
|
|
35
|
+
* millimetres to scene units. glTF scenes are in metres. Default `1`.
|
|
36
|
+
*/
|
|
37
|
+
metersPerUnit: number;
|
|
38
|
+
/** Vertical field of view in degrees (perspective). Default `45`. */
|
|
39
|
+
fov: number;
|
|
40
|
+
/** Near clip distance. Default `0.1`. */
|
|
41
|
+
near: number;
|
|
42
|
+
/** Far clip distance. Default `2000`. */
|
|
43
|
+
far: number;
|
|
44
|
+
/** Width / height (perspective). Default undefined uses the renderer canvas aspect. */
|
|
45
|
+
aspect: number | undefined;
|
|
46
|
+
/** Left orthographic frustum bound in scene units. Default `-1`. */
|
|
47
|
+
left: number;
|
|
48
|
+
/** Right orthographic frustum bound in scene units. Default `1`. */
|
|
49
|
+
right: number;
|
|
50
|
+
/** Top orthographic frustum bound in scene units. Default `1`. */
|
|
51
|
+
top: number;
|
|
52
|
+
/** Bottom orthographic frustum bound in scene units. Default `-1`. */
|
|
53
|
+
bottom: number;
|
|
54
|
+
/** Zoom factor applied to the field of view or orthographic bounds. Default `1`. */
|
|
55
|
+
zoom: number;
|
|
56
|
+
/** Creates a camera; projection is required and other options use the documented defaults. */
|
|
57
|
+
constructor(params: {
|
|
58
|
+
/** Perspective projection. Required. */ projection: 'perspective';
|
|
59
|
+
/** Vertical field of view, in degrees. Default 45. */ fov?: number;
|
|
60
|
+
/** Width / height. Default undefined uses the renderer canvas aspect. */ aspect?: number;
|
|
61
|
+
/** Near clip distance. Default 0.1. */ near?: number;
|
|
62
|
+
/** Far clip distance. Default 2000. */ far?: number;
|
|
63
|
+
} | {
|
|
64
|
+
/** Orthographic projection. Required. */ projection: 'orthographic';
|
|
65
|
+
/** Left bound. Default -1. */ left?: number;
|
|
66
|
+
/** Right bound. Default 1. */ right?: number;
|
|
67
|
+
/** Bottom bound. Default -1. */ bottom?: number;
|
|
68
|
+
/** Top bound. Default 1. */ top?: number;
|
|
69
|
+
/** Near clip distance. Default 0.1. */ near?: number;
|
|
70
|
+
/** Far clip distance. Default 2000. */ far?: number;
|
|
71
|
+
});
|
|
72
|
+
/** Copies camera parameters and world matrix from source into target. */
|
|
73
|
+
copy(source: Camera): this;
|
|
74
|
+
/** Creates an independent camera with copied settings and transform. */
|
|
75
|
+
clone(): Camera;
|
|
76
|
+
/** Returns a new column-major projection matrix including zoom. Default targetAspect 1, used only when aspect is undefined. */
|
|
77
|
+
getProjectionMatrix(targetAspect?: number): Mat4;
|
|
78
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { mat4 } from '../math.js';
|
|
2
|
+
import SceneNode from './SceneNode.js';
|
|
3
|
+
/**
|
|
4
|
+
* Perspective or orthographic camera. Position and orient it with
|
|
5
|
+
* `transform` (camera-to-world), via `position` and `lookAt()`.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const camera = new Camera({ projection: 'perspective', fov: 45, near: 0.1, far: 100 });
|
|
9
|
+
* camera.position = [0, 1, 5]; camera.lookAt([0, 0, 0]);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export default class Camera extends SceneNode {
|
|
13
|
+
/** Camera projection mode. Default `perspective`. */
|
|
14
|
+
projection = 'perspective';
|
|
15
|
+
/**
|
|
16
|
+
* Lens f-number (focal length / aperture diameter) for depth of field.
|
|
17
|
+
* Smaller values blur more. `0` disables depth of field (pinhole camera).
|
|
18
|
+
* Orthographic cameras ignore it. Default `0`.
|
|
19
|
+
*/
|
|
20
|
+
fStop = 0;
|
|
21
|
+
/**
|
|
22
|
+
* Distance from the lens to the plane in focus, measured along the view
|
|
23
|
+
* direction, in scene units. Default `10`.
|
|
24
|
+
*/
|
|
25
|
+
focusDistance = 10;
|
|
26
|
+
/**
|
|
27
|
+
* Sensor height in millimetres. With `fov` and `zoom` it defines the focal
|
|
28
|
+
* length, and so the aperture size for a given `fStop`. Default `24`
|
|
29
|
+
* (full-frame 35 mm).
|
|
30
|
+
*/
|
|
31
|
+
sensorHeight = 24;
|
|
32
|
+
/**
|
|
33
|
+
* Length of one scene unit in metres, used to convert the lens size in
|
|
34
|
+
* millimetres to scene units. glTF scenes are in metres. Default `1`.
|
|
35
|
+
*/
|
|
36
|
+
metersPerUnit = 1;
|
|
37
|
+
/** Vertical field of view in degrees (perspective). Default `45`. */
|
|
38
|
+
fov = 45;
|
|
39
|
+
/** Near clip distance. Default `0.1`. */
|
|
40
|
+
near;
|
|
41
|
+
/** Far clip distance. Default `2000`. */
|
|
42
|
+
far;
|
|
43
|
+
/** Width / height (perspective). Default undefined uses the renderer canvas aspect. */
|
|
44
|
+
aspect = undefined;
|
|
45
|
+
/** Left orthographic frustum bound in scene units. Default `-1`. */
|
|
46
|
+
left = -1;
|
|
47
|
+
/** Right orthographic frustum bound in scene units. Default `1`. */
|
|
48
|
+
right = 1;
|
|
49
|
+
/** Top orthographic frustum bound in scene units. Default `1`. */
|
|
50
|
+
top = 1;
|
|
51
|
+
/** Bottom orthographic frustum bound in scene units. Default `-1`. */
|
|
52
|
+
bottom = -1;
|
|
53
|
+
/** Zoom factor applied to the field of view or orthographic bounds. Default `1`. */
|
|
54
|
+
zoom = 1;
|
|
55
|
+
/** Creates a camera; projection is required and other options use the documented defaults. */
|
|
56
|
+
constructor(params) {
|
|
57
|
+
super();
|
|
58
|
+
this.projection = params.projection;
|
|
59
|
+
this.near = params.near ?? .1;
|
|
60
|
+
this.far = params.far ?? 2000;
|
|
61
|
+
if (params.projection === 'perspective') {
|
|
62
|
+
this.fov = params.fov ?? 45;
|
|
63
|
+
this.aspect = params.aspect;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
this.left = params.left ?? -1;
|
|
67
|
+
this.right = params.right ?? 1;
|
|
68
|
+
this.bottom = params.bottom ?? -1;
|
|
69
|
+
this.top = params.top ?? 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Copies camera parameters and world matrix from source into target. */
|
|
73
|
+
copy(source) {
|
|
74
|
+
const target = this;
|
|
75
|
+
target.projection = source.projection;
|
|
76
|
+
target.fov = source.fov;
|
|
77
|
+
target.near = source.near;
|
|
78
|
+
target.far = source.far;
|
|
79
|
+
target.aspect = source.aspect;
|
|
80
|
+
target.zoom = source.zoom;
|
|
81
|
+
target.fStop = source.fStop;
|
|
82
|
+
target.focusDistance = source.focusDistance;
|
|
83
|
+
target.sensorHeight = source.sensorHeight;
|
|
84
|
+
target.metersPerUnit = source.metersPerUnit;
|
|
85
|
+
target.left = source.left;
|
|
86
|
+
target.right = source.right;
|
|
87
|
+
target.top = source.top;
|
|
88
|
+
target.bottom = source.bottom;
|
|
89
|
+
mat4.copy(target.transform, source.transform);
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/** Creates an independent camera with copied settings and transform. */
|
|
93
|
+
clone() {
|
|
94
|
+
return new Camera({ projection: this.projection }).copy(this);
|
|
95
|
+
}
|
|
96
|
+
/** Returns a new column-major projection matrix including zoom. Default targetAspect 1, used only when aspect is undefined. */
|
|
97
|
+
getProjectionMatrix(targetAspect = 1) {
|
|
98
|
+
const camera = this;
|
|
99
|
+
if (camera.projection === 'perspective') {
|
|
100
|
+
const fov = (camera.fov * Math.PI) / 180;
|
|
101
|
+
const effectiveFov = 2 * Math.atan(Math.tan(fov / 2) / Math.max(camera.zoom, Number.EPSILON));
|
|
102
|
+
return mat4.perspective([], effectiveFov, camera.aspect ?? targetAspect, camera.near, camera.far);
|
|
103
|
+
}
|
|
104
|
+
return mat4.ortho([], (camera.left + camera.right) / 2 -
|
|
105
|
+
(camera.right - camera.left) / (2 * camera.zoom), (camera.left + camera.right) / 2 +
|
|
106
|
+
(camera.right - camera.left) / (2 * camera.zoom), (camera.bottom + camera.top) / 2 -
|
|
107
|
+
(camera.top - camera.bottom) / (2 * camera.zoom), (camera.bottom + camera.top) / 2 +
|
|
108
|
+
(camera.top - camera.bottom) / (2 * camera.zoom), camera.near, camera.far);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=Camera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Camera.js","sourceRoot":"","sources":["../../src/scene/Camera.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Mat4 } from '../types.js';\nimport { mat4 } from '../math.js';\nimport SceneNode from './SceneNode.js';\n\nexport type Projection = 'perspective' | 'orthographic';\n\n/**\n * Perspective or orthographic camera. Position and orient it with\n * `transform` (camera-to-world), via `position` and `lookAt()`.\n *\n * ```ts\n * const camera = new Camera({ projection: 'perspective', fov: 45, near: 0.1, far: 100 });\n * camera.position = [0, 1, 5]; camera.lookAt([0, 0, 0]);\n * ```\n */\nexport default class Camera extends SceneNode {\n /** Camera projection mode. Default `perspective`. */\n projection: Projection = 'perspective';\n\n /**\n * Lens f-number (focal length / aperture diameter) for depth of field.\n * Smaller values blur more. `0` disables depth of field (pinhole camera).\n * Orthographic cameras ignore it. Default `0`.\n */\n fStop = 0;\n /**\n * Distance from the lens to the plane in focus, measured along the view\n * direction, in scene units. Default `10`.\n */\n focusDistance = 10;\n /**\n * Sensor height in millimetres. With `fov` and `zoom` it defines the focal\n * length, and so the aperture size for a given `fStop`. Default `24`\n * (full-frame 35 mm).\n */\n sensorHeight = 24;\n /**\n * Length of one scene unit in metres, used to convert the lens size in\n * millimetres to scene units. glTF scenes are in metres. Default `1`.\n */\n metersPerUnit = 1;\n\n /** Vertical field of view in degrees (perspective). Default `45`. */\n fov = 45;\n /** Near clip distance. Default `0.1`. */\n near;\n /** Far clip distance. Default `2000`. */\n far;\n /** Width / height (perspective). Default undefined uses the renderer canvas aspect. */\n aspect: number | undefined = undefined;\n\n /** Left orthographic frustum bound in scene units. Default `-1`. */\n left = -1;\n /** Right orthographic frustum bound in scene units. Default `1`. */\n right = 1;\n /** Top orthographic frustum bound in scene units. Default `1`. */\n top = 1;\n /** Bottom orthographic frustum bound in scene units. Default `-1`. */\n bottom = -1;\n\n /** Zoom factor applied to the field of view or orthographic bounds. Default `1`. */\n zoom = 1;\n\n /** Creates a camera; projection is required and other options use the documented defaults. */\n constructor(params:\n | {\n /** Perspective projection. Required. */ projection: 'perspective';\n /** Vertical field of view, in degrees. Default 45. */ fov?: number;\n /** Width / height. Default undefined uses the renderer canvas aspect. */ aspect?: number;\n /** Near clip distance. Default 0.1. */ near?: number;\n /** Far clip distance. Default 2000. */ far?: number;\n }\n | {\n /** Orthographic projection. Required. */ projection: 'orthographic';\n /** Left bound. Default -1. */ left?: number;\n /** Right bound. Default 1. */ right?: number;\n /** Bottom bound. Default -1. */ bottom?: number;\n /** Top bound. Default 1. */ top?: number;\n /** Near clip distance. Default 0.1. */ near?: number;\n /** Far clip distance. Default 2000. */ far?: number;\n }\n ) {\n super();\n this.projection = params.projection;\n this.near = params.near ?? .1;\n this.far = params.far ?? 2000;\n if(params.projection === 'perspective') {\n this.fov = params.fov ?? 45;\n this.aspect = params.aspect;\n } else {\n this.left = params.left ?? -1; this.right = params.right ?? 1;\n this.bottom = params.bottom ?? -1; this.top = params.top ?? 1;\n }\n }\n\n /** Copies camera parameters and world matrix from source into target. */\n copy(source: Camera): this {\n const target = this;\n target.projection = source.projection;\n target.fov = source.fov;\n target.near = source.near;\n target.far = source.far;\n target.aspect = source.aspect;\n target.zoom = source.zoom;\n target.fStop = source.fStop;\n target.focusDistance = source.focusDistance;\n target.sensorHeight = source.sensorHeight;\n target.metersPerUnit = source.metersPerUnit;\n target.left = source.left;\n target.right = source.right;\n target.top = source.top;\n target.bottom = source.bottom;\n\n mat4.copy(target.transform, source.transform);\n return this;\n }\n\n /** Creates an independent camera with copied settings and transform. */\n clone(): Camera {\n return new Camera({ projection: this.projection }).copy(this);\n }\n\n /** Returns a new column-major projection matrix including zoom. Default targetAspect 1, used only when aspect is undefined. */\n getProjectionMatrix(targetAspect = 1): Mat4 {\n const camera = this;\n if (camera.projection === 'perspective') {\n const fov = (camera.fov * Math.PI) / 180;\n const effectiveFov =\n 2 * Math.atan(Math.tan(fov / 2) / Math.max(camera.zoom, Number.EPSILON));\n return mat4.perspective(\n [] as any as Mat4,\n effectiveFov,\n camera.aspect ?? targetAspect,\n camera.near,\n camera.far\n );\n }\n return mat4.ortho(\n [] as any as Mat4,\n (camera.left + camera.right) / 2 -\n (camera.right - camera.left) / (2 * camera.zoom),\n (camera.left + camera.right) / 2 +\n (camera.right - camera.left) / (2 * camera.zoom),\n (camera.bottom + camera.top) / 2 -\n (camera.top - camera.bottom) / (2 * camera.zoom),\n (camera.bottom + camera.top) / 2 +\n (camera.top - camera.bottom) / (2 * camera.zoom),\n camera.near,\n camera.far\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ColorRGB } from '../types.js';
|
|
2
|
+
import SceneNode from './SceneNode.js';
|
|
3
|
+
/** Analytic light placed with transform; local -Z is the emission direction and local +X is the IES reference. */
|
|
4
|
+
export default class DirectionalLight extends SceneNode {
|
|
5
|
+
/** Light discriminator. */
|
|
6
|
+
readonly type: "DirectionalLight";
|
|
7
|
+
/** Linear RGB color. Default `[1, 1, 1]`. */
|
|
8
|
+
color: ColorRGB;
|
|
9
|
+
/** Irradiance on a surface facing the light. Default `1`. */
|
|
10
|
+
intensity: number;
|
|
11
|
+
/** Creates a light; omitted options retain the field defaults. */
|
|
12
|
+
constructor(params?: {
|
|
13
|
+
/** Linear RGB color. Default `[1, 1, 1]`. */
|
|
14
|
+
color?: ColorRGB;
|
|
15
|
+
/** Irradiance on a surface facing the light. Default `1`. */
|
|
16
|
+
intensity?: number;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import SceneNode from './SceneNode.js';
|
|
2
|
+
/** Analytic light placed with transform; local -Z is the emission direction and local +X is the IES reference. */
|
|
3
|
+
export default class DirectionalLight extends SceneNode {
|
|
4
|
+
/** Light discriminator. */
|
|
5
|
+
type = 'DirectionalLight';
|
|
6
|
+
/** Linear RGB color. Default `[1, 1, 1]`. */
|
|
7
|
+
color = [1, 1, 1];
|
|
8
|
+
/** Irradiance on a surface facing the light. Default `1`. */
|
|
9
|
+
intensity = 1;
|
|
10
|
+
/** Creates a light; omitted options retain the field defaults. */
|
|
11
|
+
constructor(params = {}) {
|
|
12
|
+
super();
|
|
13
|
+
this.color = params.color ?? [1, 1, 1];
|
|
14
|
+
this.intensity = params.intensity ?? 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=DirectionalLight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DirectionalLight.js","sourceRoot":"","sources":["../../src/scene/DirectionalLight.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAEvC,kHAAkH;AAClH,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,SAAS;IACrD,2BAA2B;IAClB,IAAI,GAAG,kBAA2B,CAAC;IAC5C,6CAA6C;IAC7C,KAAK,GAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,6DAA6D;IAC7D,SAAS,GAAW,CAAC,CAAC;IAEtB,kEAAkE;IAClE,YAAY,SAKR,EAAE;QACJ,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;IACzC,CAAC;CACF","sourcesContent":["import type { ColorRGB } from '../types.js';\nimport SceneNode from './SceneNode.js';\n\n/** Analytic light placed with transform; local -Z is the emission direction and local +X is the IES reference. */\nexport default class DirectionalLight extends SceneNode {\n /** Light discriminator. */\n readonly type = 'DirectionalLight' as const;\n /** Linear RGB color. Default `[1, 1, 1]`. */\n color: ColorRGB = [1, 1, 1];\n /** Irradiance on a surface facing the light. Default `1`. */\n intensity: number = 1;\n\n /** Creates a light; omitted options retain the field defaults. */\n constructor(params: {\n /** Linear RGB color. Default `[1, 1, 1]`. */\n color?: ColorRGB;\n /** Irradiance on a surface facing the light. Default `1`. */\n intensity?: number;\n } = {}) {\n super();\n this.color = params.color ?? [1, 1, 1];\n this.intensity = params.intensity ?? 1;\n }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Texture from './Texture.js';
|
|
2
|
+
/**
|
|
3
|
+
* Image-based lighting from an equirectangular (latitude-longitude) HDR map,
|
|
4
|
+
* for example one loaded with `loadRGBE()`. Importance sampled.
|
|
5
|
+
*/
|
|
6
|
+
export default class EnvironmentLight {
|
|
7
|
+
/** Light discriminator; always `EnvironmentLight`. */
|
|
8
|
+
readonly type: "EnvironmentLight";
|
|
9
|
+
/** Equirectangular radiance map in linear color. */
|
|
10
|
+
map: Texture;
|
|
11
|
+
constructor(params: {
|
|
12
|
+
map: Texture;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image-based lighting from an equirectangular (latitude-longitude) HDR map,
|
|
3
|
+
* for example one loaded with `loadRGBE()`. Importance sampled.
|
|
4
|
+
*/
|
|
5
|
+
export default class EnvironmentLight {
|
|
6
|
+
/** Light discriminator; always `EnvironmentLight`. */
|
|
7
|
+
type = 'EnvironmentLight';
|
|
8
|
+
/** Equirectangular radiance map in linear color. */
|
|
9
|
+
map;
|
|
10
|
+
constructor(params) {
|
|
11
|
+
this.map = params.map;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=EnvironmentLight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentLight.js","sourceRoot":"","sources":["../../src/scene/EnvironmentLight.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAgB;IACnC,sDAAsD;IAC7C,IAAI,GAAG,kBAA2B,CAAC;IAC5C,oDAAoD;IACpD,GAAG,CAAU;IACb,YAAY,MAAkF;QAC5F,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACxB,CAAC;CACF","sourcesContent":["import Texture from './Texture.js';\n\n/**\n * Image-based lighting from an equirectangular (latitude-longitude) HDR map,\n * for example one loaded with `loadRGBE()`. Importance sampled.\n */\nexport default class EnvironmentLight {\n /** Light discriminator; always `EnvironmentLight`. */\n readonly type = 'EnvironmentLight' as const;\n /** Equirectangular radiance map in linear color. */\n map: Texture;\n constructor(params: { /** Required equirectangular radiance map; no default. */ map: Texture }) {\n this.map = params.map;\n }\n}\n"]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Vec3 } from '../types.js';
|
|
2
|
+
type AttributeData = Float32Array | Uint16Array | Uint32Array | Int32Array;
|
|
3
|
+
export declare class Attribute<T extends AttributeData = AttributeData> {
|
|
4
|
+
array: T;
|
|
5
|
+
itemSize: number;
|
|
6
|
+
constructor(array: T, itemSize: number);
|
|
7
|
+
static getItem(attr: Attribute, out: number[], vertexIndex: number): void;
|
|
8
|
+
static getCount(attr: Attribute): number;
|
|
9
|
+
}
|
|
10
|
+
export type AttributeName = 'position' | 'normal' | 'tangent' | 'uv' | 'uv1' | 'color';
|
|
11
|
+
export declare const AVAILABLE_ATTRIBUTES: AttributeName[];
|
|
12
|
+
/** Triangle geometry construction data. */
|
|
13
|
+
export interface GeometryInit {
|
|
14
|
+
/** Required vertex positions in scene units, itemSize 3. */
|
|
15
|
+
position: Attribute<Float32Array>;
|
|
16
|
+
/** Triangle vertex indices, itemSize 1. Default: sequential indices 0..vertexCount-1. */
|
|
17
|
+
indices?: Attribute<Uint16Array | Uint32Array>;
|
|
18
|
+
/** Vertex normals, itemSize 3. Default: generated smooth area-weighted normals. */
|
|
19
|
+
normal?: Attribute<Float32Array>;
|
|
20
|
+
/** Vertex tangents (XYZ, optional W handedness). Default undefined. */
|
|
21
|
+
tangent?: Attribute<Float32Array>;
|
|
22
|
+
/** Primary UV coordinates. Default undefined. */
|
|
23
|
+
uv?: Attribute<Float32Array>;
|
|
24
|
+
/** Secondary UV coordinates. Default undefined. */
|
|
25
|
+
uv1?: Attribute<Float32Array>;
|
|
26
|
+
/** Vertex RGB colors. Default undefined. */
|
|
27
|
+
color?: Attribute<Float32Array>;
|
|
28
|
+
/** Raw per-vertex material indices, itemSize 1. Default undefined selects material 0. */
|
|
29
|
+
materialIndex?: Attribute<Int32Array>;
|
|
30
|
+
}
|
|
31
|
+
/** Triangle mesh data. Only position is required; missing indices and normals are generated at construction. */
|
|
32
|
+
export default class Geometry {
|
|
33
|
+
/** Incremented by either update method. Default `0`. */
|
|
34
|
+
version: number;
|
|
35
|
+
private _topologyVersion;
|
|
36
|
+
/** Index/material-index revision, advanced by markUpdated(). Default `0`. */
|
|
37
|
+
get topologyVersion(): number;
|
|
38
|
+
/**
|
|
39
|
+
* Hint that vertices change often (skinning, morph targets). Keeps a built-in
|
|
40
|
+
* BVH2 layout that can be refit in place. Default `false`.
|
|
41
|
+
*/
|
|
42
|
+
dynamic: boolean;
|
|
43
|
+
/** Required vertex positions in scene units; provided by the constructor. */
|
|
44
|
+
position: Attribute<Float32Array>;
|
|
45
|
+
/** Vertex normals; supplied or generated at construction. */
|
|
46
|
+
normal: Attribute<Float32Array>;
|
|
47
|
+
/** Optional vertex tangents (XYZ, optional W handedness). Default undefined. */
|
|
48
|
+
tangent?: Attribute<Float32Array>;
|
|
49
|
+
/** Optional primary texture coordinates. Default undefined. */
|
|
50
|
+
uv?: Attribute<Float32Array>;
|
|
51
|
+
/** Optional secondary UV set (glTF TEXCOORD_1 / Three.js uv1). Default undefined. */
|
|
52
|
+
uv1?: Attribute<Float32Array>;
|
|
53
|
+
/** Optional vertex RGB colors. Default undefined. */
|
|
54
|
+
color?: Attribute<Float32Array>;
|
|
55
|
+
/** Required triangle vertex indices; three entries per triangle. */
|
|
56
|
+
indices: Attribute<Uint16Array | Uint32Array>;
|
|
57
|
+
/** Optional per-vertex raw material indices, itemSize 1. All three triangle corners must match. Default undefined selects material 0. */
|
|
58
|
+
materialIndex?: Attribute<Int32Array>;
|
|
59
|
+
/** Local-space bounds in scene units; initial min/max are `[0, 0, 0]`. */
|
|
60
|
+
boundingBox: {
|
|
61
|
+
min: Vec3;
|
|
62
|
+
max: Vec3;
|
|
63
|
+
};
|
|
64
|
+
constructor(data: GeometryInit);
|
|
65
|
+
/**
|
|
66
|
+
* Call after index/material-index edits or a general geometry update.
|
|
67
|
+
* Advances version and topologyVersion to request topology processing and
|
|
68
|
+
* BVH rebuilding. For vertex-only edits with unchanged indices
|
|
69
|
+
* and materialIndex, use markVerticesUpdated() to allow refitting instead.
|
|
70
|
+
* Neither notification recalculates normals or tangents.
|
|
71
|
+
* Replacing a mesh's Geometry object is detected without this call.
|
|
72
|
+
*/
|
|
73
|
+
markUpdated(): this;
|
|
74
|
+
/**
|
|
75
|
+
* Call after editing vertex attributes without changing indices or materialIndex.
|
|
76
|
+
* Advances version while preserving topologyVersion, allowing vertex-only uploads.
|
|
77
|
+
* With stable arrays, lengths and item sizes, the next render refits supported
|
|
78
|
+
* BVHs or rebuilds when needed. Changed storage or displacement still requires
|
|
79
|
+
* full scene data preparation. Does not recalculate normals or tangents.
|
|
80
|
+
*/
|
|
81
|
+
markVerticesUpdated(): this;
|
|
82
|
+
/** Returns the number of vertices in the position attribute. */
|
|
83
|
+
get vertexCount(): number;
|
|
84
|
+
/** Number of triangles in the index attribute. */
|
|
85
|
+
get triangleCount(): number;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { generateVertexNormals } from '../util/geometry.js';
|
|
2
|
+
import { vec3 } from '../math.js';
|
|
3
|
+
export class Attribute {
|
|
4
|
+
array;
|
|
5
|
+
itemSize;
|
|
6
|
+
constructor(array, itemSize) {
|
|
7
|
+
this.array = array;
|
|
8
|
+
this.itemSize = itemSize;
|
|
9
|
+
}
|
|
10
|
+
static getItem(attr, out, vertexIndex) {
|
|
11
|
+
const array = attr.array;
|
|
12
|
+
const itemSize = attr.itemSize;
|
|
13
|
+
const offset = vertexIndex * itemSize;
|
|
14
|
+
for (let i = 0; i < itemSize; i++) {
|
|
15
|
+
out[i] = array[offset + i];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
static getCount(attr) {
|
|
19
|
+
return attr.array.length / attr.itemSize;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export const AVAILABLE_ATTRIBUTES = [
|
|
23
|
+
'position',
|
|
24
|
+
'normal',
|
|
25
|
+
'tangent',
|
|
26
|
+
'uv',
|
|
27
|
+
'uv1',
|
|
28
|
+
'color'
|
|
29
|
+
];
|
|
30
|
+
/** Triangle mesh data. Only position is required; missing indices and normals are generated at construction. */
|
|
31
|
+
export default class Geometry {
|
|
32
|
+
/** Incremented by either update method. Default `0`. */
|
|
33
|
+
version = 0;
|
|
34
|
+
_topologyVersion = 0;
|
|
35
|
+
/** Index/material-index revision, advanced by markUpdated(). Default `0`. */
|
|
36
|
+
get topologyVersion() { return this._topologyVersion; }
|
|
37
|
+
/**
|
|
38
|
+
* Hint that vertices change often (skinning, morph targets). Keeps a built-in
|
|
39
|
+
* BVH2 layout that can be refit in place. Default `false`.
|
|
40
|
+
*/
|
|
41
|
+
dynamic = false;
|
|
42
|
+
/** Required vertex positions in scene units; provided by the constructor. */
|
|
43
|
+
position;
|
|
44
|
+
/** Vertex normals; supplied or generated at construction. */
|
|
45
|
+
normal;
|
|
46
|
+
/** Optional vertex tangents (XYZ, optional W handedness). Default undefined. */
|
|
47
|
+
tangent;
|
|
48
|
+
/** Optional primary texture coordinates. Default undefined. */
|
|
49
|
+
uv;
|
|
50
|
+
/** Optional secondary UV set (glTF TEXCOORD_1 / Three.js uv1). Default undefined. */
|
|
51
|
+
uv1;
|
|
52
|
+
/** Optional vertex RGB colors. Default undefined. */
|
|
53
|
+
color;
|
|
54
|
+
/** Required triangle vertex indices; three entries per triangle. */
|
|
55
|
+
indices;
|
|
56
|
+
/** Optional per-vertex raw material indices, itemSize 1. All three triangle corners must match. Default undefined selects material 0. */
|
|
57
|
+
materialIndex;
|
|
58
|
+
/** Local-space bounds in scene units; initial min/max are `[0, 0, 0]`. */
|
|
59
|
+
boundingBox = {
|
|
60
|
+
min: vec3.create(),
|
|
61
|
+
max: vec3.create()
|
|
62
|
+
};
|
|
63
|
+
constructor(data) {
|
|
64
|
+
this.position = data.position;
|
|
65
|
+
this.indices = data.indices ?? new Attribute(Uint32Array.from({ length: this.vertexCount }, (_, index) => index), 1);
|
|
66
|
+
this.normal = data.normal ?? new Attribute(new Float32Array(this.vertexCount * 3), 3);
|
|
67
|
+
if (!data.normal)
|
|
68
|
+
generateVertexNormals(this);
|
|
69
|
+
this.tangent = data.tangent;
|
|
70
|
+
this.uv = data.uv;
|
|
71
|
+
this.uv1 = data.uv1;
|
|
72
|
+
this.color = data.color;
|
|
73
|
+
this.materialIndex = data.materialIndex;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Call after index/material-index edits or a general geometry update.
|
|
77
|
+
* Advances version and topologyVersion to request topology processing and
|
|
78
|
+
* BVH rebuilding. For vertex-only edits with unchanged indices
|
|
79
|
+
* and materialIndex, use markVerticesUpdated() to allow refitting instead.
|
|
80
|
+
* Neither notification recalculates normals or tangents.
|
|
81
|
+
* Replacing a mesh's Geometry object is detected without this call.
|
|
82
|
+
*/
|
|
83
|
+
markUpdated() {
|
|
84
|
+
this._topologyVersion++;
|
|
85
|
+
this.version++;
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Call after editing vertex attributes without changing indices or materialIndex.
|
|
90
|
+
* Advances version while preserving topologyVersion, allowing vertex-only uploads.
|
|
91
|
+
* With stable arrays, lengths and item sizes, the next render refits supported
|
|
92
|
+
* BVHs or rebuilds when needed. Changed storage or displacement still requires
|
|
93
|
+
* full scene data preparation. Does not recalculate normals or tangents.
|
|
94
|
+
*/
|
|
95
|
+
markVerticesUpdated() {
|
|
96
|
+
this.version++;
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/** Returns the number of vertices in the position attribute. */
|
|
100
|
+
get vertexCount() {
|
|
101
|
+
return this.position.array.length / this.position.itemSize;
|
|
102
|
+
}
|
|
103
|
+
/** Number of triangles in the index attribute. */
|
|
104
|
+
get triangleCount() {
|
|
105
|
+
return this.indices.array.length / 3;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=Geometry.js.map
|