@meimu/mutracer 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/Classroom-CC0.txt +121 -0
- package/README.md +7 -7
- package/THIRD_PARTY_NOTICES.md +13 -8
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +10421 -8363
- package/docs/api.md +202 -11
- package/docs/denoising.md +30 -15
- package/docs/materials.md +18 -27
- package/docs/performance.md +5 -2
- package/docs/progressive-rendering.md +32 -1
- package/docs/threejs.md +19 -10
- package/docs/updates.md +44 -2
- package/docs/viewer.md +41 -3
- package/lib/Display.d.ts +13 -2
- package/lib/Display.js +27 -6
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -0
- package/lib/Engine.js +52 -25
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +44 -9
- package/lib/Render.js +115 -17
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +7 -1
- package/lib/RenderLoop.js +94 -13
- package/lib/RenderLoop.js.map +1 -1
- package/lib/main.d.ts +6 -3
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/math/access.d.ts +4 -0
- package/lib/math/access.js +10 -0
- package/lib/math/access.js.map +1 -0
- package/lib/math/mat3.d.ts +4 -0
- package/lib/math/mat3.js +54 -0
- package/lib/math/mat3.js.map +1 -0
- package/lib/math/mat4.d.ts +19 -0
- package/lib/math/mat4.js +413 -0
- package/lib/math/mat4.js.map +1 -0
- package/lib/math/storage.d.ts +6 -0
- package/lib/math/storage.js +22 -0
- package/lib/math/storage.js.map +1 -0
- package/lib/math/types.d.ts +3 -0
- package/lib/math/types.js +2 -0
- package/lib/math/types.js.map +1 -0
- package/lib/math/vec2.d.ts +13 -0
- package/lib/math/vec2.js +52 -0
- package/lib/math/vec2.js.map +1 -0
- package/lib/math/vec3.d.ts +23 -0
- package/lib/math/vec3.js +139 -0
- package/lib/math/vec3.js.map +1 -0
- package/lib/math.d.ts +5 -17
- package/lib/math.js +5 -55
- package/lib/math.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/oidn.js +4 -2
- package/lib/oidn.js.map +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/AovPrimitiveCache.d.ts +10 -0
- package/lib/renderer/AovPrimitiveCache.js +48 -0
- package/lib/renderer/AovPrimitiveCache.js.map +1 -0
- package/lib/renderer/Box3.d.ts +5 -0
- package/lib/renderer/Box3.js +9 -0
- package/lib/renderer/Box3.js.map +1 -0
- package/lib/renderer/GPUTraceQueue.d.ts +10 -0
- package/lib/renderer/GPUTraceQueue.js +31 -0
- package/lib/renderer/GPUTraceQueue.js.map +1 -0
- package/lib/renderer/MaterialData.d.ts +15 -0
- package/lib/renderer/MaterialData.js +61 -0
- package/lib/renderer/MaterialData.js.map +1 -0
- package/lib/renderer/MaterialTable.d.ts +11 -98
- package/lib/renderer/MaterialTable.js +34 -412
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +32 -13
- package/lib/renderer/RenderingPipeline.js +1 -17
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +0 -1
- package/lib/renderer/TileRender.js +14 -1
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +39 -0
- package/lib/renderer/WGPUAov.js +239 -0
- package/lib/renderer/WGPUAov.js.map +1 -0
- package/lib/renderer/WGPUBindlessMaterialData.d.ts +17 -0
- package/lib/renderer/WGPUBindlessMaterialData.js +48 -0
- package/lib/renderer/WGPUBindlessMaterialData.js.map +1 -0
- package/lib/renderer/WGPUBindlessTextures.d.ts +47 -0
- package/lib/renderer/WGPUBindlessTextures.js +180 -0
- package/lib/renderer/WGPUBindlessTextures.js.map +1 -0
- package/lib/renderer/WGPUBloomPass.js +17 -97
- package/lib/renderer/WGPUBloomPass.js.map +1 -1
- package/lib/renderer/WGPUComputePass.d.ts +1 -1
- package/lib/renderer/WGPUComputePass.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.d.ts +12 -0
- package/lib/renderer/WGPUEnvMapDistribution.js +150 -0
- package/lib/renderer/WGPUEnvMapDistribution.js.map +1 -0
- package/lib/renderer/WGPUFullQuadPass.js +10 -9
- package/lib/renderer/WGPUFullQuadPass.js.map +1 -1
- package/lib/renderer/WGPUJNLMDenoiser.d.ts +1 -20
- package/lib/renderer/WGPUJNLMDenoiser.js +4 -267
- package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WGPURayTraceOutput.js +26 -17
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +36 -40
- package/lib/renderer/WGPURayTracePass.js +399 -548
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
- package/lib/renderer/WGPURenderingPipeline.js +239 -60
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WGPUShaderCache.d.ts +2 -2
- package/lib/renderer/WGPUShaderCache.js +10 -5
- package/lib/renderer/WGPUShaderCache.js.map +1 -1
- package/lib/renderer/WGPUShaderCapabilities.d.ts +10 -0
- package/lib/renderer/WGPUShaderCapabilities.js +54 -0
- package/lib/renderer/WGPUShaderCapabilities.js.map +1 -0
- package/lib/renderer/WGPUSkyBaker.d.ts +13 -0
- package/lib/renderer/WGPUSkyBaker.js +85 -0
- package/lib/renderer/WGPUSkyBaker.js.map +1 -0
- package/lib/renderer/WebGLAov.d.ts +41 -0
- package/lib/renderer/WebGLAov.js +106 -0
- package/lib/renderer/WebGLAov.js.map +1 -0
- package/lib/renderer/WebGLFullQuadPass.d.ts +5 -3
- package/lib/renderer/WebGLFullQuadPass.js +18 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.d.ts +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +83 -74
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +7 -4
- package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -1
- package/lib/renderer/WebGLRayTracePass.d.ts +12 -2
- package/lib/renderer/WebGLRayTracePass.js +83 -7
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +116 -8
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.d.ts +39 -0
- package/lib/renderer/WebGLSkyBaker.js +422 -0
- package/lib/renderer/WebGLSkyBaker.js.map +1 -0
- package/lib/renderer/WebGLSkySource.d.ts +9 -0
- package/lib/renderer/WebGLSkySource.js +28 -0
- package/lib/renderer/WebGLSkySource.js.map +1 -0
- package/lib/renderer/accumulationTarget.d.ts +5 -0
- package/lib/renderer/accumulationTarget.js.map +1 -1
- package/lib/renderer/aov.d.ts +42 -0
- package/lib/renderer/aov.js +50 -0
- package/lib/renderer/aov.js.map +1 -0
- package/lib/renderer/aovDisplay.d.ts +14 -0
- package/lib/renderer/aovDisplay.js +32 -0
- package/lib/renderer/aovDisplay.js.map +1 -0
- package/lib/renderer/aovScene.d.ts +21 -0
- package/lib/renderer/aovScene.js +139 -0
- package/lib/renderer/aovScene.js.map +1 -0
- package/lib/renderer/binnedSahBvh.js +2 -1
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +20 -10
- package/lib/renderer/bvhAccel.js +168 -58
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +1 -0
- package/lib/renderer/cameraSnapshot.js +2 -1
- package/lib/renderer/cameraSnapshot.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +2 -0
- package/lib/renderer/cameraUniform.js +12 -0
- package/lib/renderer/cameraUniform.js.map +1 -0
- package/lib/renderer/committedScene.js +4 -0
- package/lib/renderer/committedScene.js.map +1 -1
- package/lib/renderer/denoiser.d.ts +3 -11
- package/lib/renderer/denoiser.js.map +1 -1
- package/lib/renderer/depthQuery.js +4 -1
- package/lib/renderer/depthQuery.js.map +1 -1
- package/lib/renderer/displacementPreparation.d.ts +11 -0
- package/lib/renderer/displacementPreparation.js +351 -0
- package/lib/renderer/displacementPreparation.js.map +1 -0
- package/lib/renderer/displacementRange.d.ts +1 -0
- package/lib/renderer/displacementRange.js +9 -0
- package/lib/renderer/displacementRange.js.map +1 -0
- package/lib/renderer/displayParityDiagnostics.d.ts +11 -0
- package/lib/renderer/displayParityDiagnostics.js +2 -0
- package/lib/renderer/displayParityDiagnostics.js.map +1 -0
- package/lib/renderer/envMapCreation.d.ts +9 -8
- package/lib/renderer/envMapCreation.js +36 -12
- package/lib/renderer/envMapCreation.js.map +1 -1
- package/lib/renderer/envMapDistribution.d.ts +12 -2
- package/lib/renderer/envMapDistribution.js +43 -34
- package/lib/renderer/envMapDistribution.js.map +1 -1
- package/lib/renderer/geometryBvhBounds.d.ts +4 -0
- package/lib/renderer/geometryBvhBounds.js +82 -0
- package/lib/renderer/geometryBvhBounds.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +32 -0
- package/lib/renderer/geometryUpdateState.js +2 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -0
- package/lib/renderer/geometryUpdates.d.ts +17 -9
- package/lib/renderer/geometryUpdates.js +92 -33
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.d.ts +3 -0
- package/lib/renderer/glsl/aovDisplay.frag.js +54 -0
- package/lib/renderer/glsl/aovDisplay.frag.js.map +1 -0
- package/lib/renderer/glsl/aovReflectance.glsl.d.ts +2 -0
- package/lib/renderer/glsl/aovReflectance.glsl.js +87 -0
- package/lib/renderer/glsl/aovReflectance.glsl.js.map +1 -0
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.d.ts +2 -0
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +135 -0
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js.map +1 -0
- package/lib/renderer/glsl/aovTrace.frag.d.ts +2 -0
- package/lib/renderer/glsl/aovTrace.frag.js +121 -0
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/envMap.glsl.js +80 -74
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +437 -435
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +146 -145
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +821 -821
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +51 -51
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +80 -80
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +108 -108
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +20 -17
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampling.glsl.js +93 -93
- package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -1
- package/lib/renderer/glsl/depthQuery.frag.js +7 -7
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +17 -9
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +191 -191
- package/lib/renderer/glsl/shadowCatcher.frag.js +25 -20
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +65 -60
- package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -1
- package/lib/renderer/lightConstants.d.ts +10 -0
- package/lib/renderer/lightConstants.js +11 -0
- package/lib/renderer/lightConstants.js.map +1 -0
- package/lib/renderer/lightCore.d.ts +12 -0
- package/lib/renderer/lightCore.js +13 -0
- package/lib/renderer/lightCore.js.map +1 -0
- package/lib/renderer/lightSampling.d.ts +20 -17
- package/lib/renderer/lightSampling.js +123 -56
- package/lib/renderer/lightSampling.js.map +1 -1
- package/lib/renderer/lightsData.d.ts +21 -0
- package/lib/renderer/lightsData.js +192 -0
- package/lib/renderer/lightsData.js.map +1 -0
- package/lib/renderer/lightsUtil.d.ts +3 -26
- package/lib/renderer/lightsUtil.js +3 -153
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialBufferData.d.ts +70 -0
- package/lib/renderer/materialBufferData.js +2 -0
- package/lib/renderer/materialBufferData.js.map +1 -0
- package/lib/renderer/materialConstants.d.ts +11 -0
- package/lib/renderer/materialConstants.js +11 -0
- package/lib/renderer/materialConstants.js.map +1 -1
- package/lib/renderer/materialCore.d.ts +8 -0
- package/lib/renderer/materialCore.js +9 -0
- package/lib/renderer/materialCore.js.map +1 -0
- package/lib/renderer/materialEmission.d.ts +2 -2
- package/lib/renderer/materialEmission.js +3 -3
- package/lib/renderer/materialEmission.js.map +1 -1
- package/lib/renderer/materialLayout.d.ts +2 -101
- package/lib/renderer/materialLayout.js +110 -172
- package/lib/renderer/materialLayout.js.map +1 -1
- package/lib/renderer/materialLayoutSchema.d.ts +26 -0
- package/lib/renderer/materialLayoutSchema.js +172 -0
- package/lib/renderer/materialLayoutSchema.js.map +1 -0
- package/lib/renderer/materialParams.d.ts +69 -0
- package/lib/renderer/materialParams.js +272 -0
- package/lib/renderer/materialParams.js.map +1 -0
- package/lib/renderer/materialTextureSlots.d.ts +14 -324
- package/lib/renderer/materialTextureSlots.js +21 -8
- package/lib/renderer/materialTextureSlots.js.map +1 -1
- package/lib/renderer/materialTextures.d.ts +6 -0
- package/lib/renderer/{texturesFromMaterials.js → materialTextures.js} +1 -2
- package/lib/renderer/materialTextures.js.map +1 -0
- package/lib/renderer/mergeMeshesToGeometry.js +6 -147
- package/lib/renderer/mergeMeshesToGeometry.js.map +1 -1
- package/lib/renderer/meshInstances.d.ts +4 -21
- package/lib/renderer/meshInstances.js +10 -56
- package/lib/renderer/meshInstances.js.map +1 -1
- package/lib/renderer/oidnNetwork.d.ts +2 -2
- package/lib/renderer/oidnNetwork.js +1 -1
- package/lib/renderer/oidnNetwork.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.js +850 -846
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/ownedDenoiser.d.ts +9 -0
- package/lib/renderer/ownedDenoiser.js +2 -0
- package/lib/renderer/ownedDenoiser.js.map +1 -0
- package/lib/renderer/packedMeshInstances.d.ts +23 -0
- package/lib/renderer/packedMeshInstances.js +80 -0
- package/lib/renderer/packedMeshInstances.js.map +1 -0
- package/lib/renderer/prepareMeshBVH.d.ts +12 -47
- package/lib/renderer/prepareMeshBVH.js +21 -642
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/proceduralEnvironmentPower.d.ts +3 -0
- package/lib/renderer/proceduralEnvironmentPower.js +8 -0
- package/lib/renderer/proceduralEnvironmentPower.js.map +1 -0
- package/lib/renderer/progressiveScheduler.d.ts +1 -0
- package/lib/renderer/progressiveScheduler.js +3 -0
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +3 -1
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/renderingLimits.d.ts +9 -0
- package/lib/renderer/renderingLimits.js +18 -0
- package/lib/renderer/renderingLimits.js.map +1 -0
- package/lib/renderer/sceneAssembly.d.ts +73 -0
- package/lib/renderer/sceneAssembly.js +109 -0
- package/lib/renderer/sceneAssembly.js.map +1 -0
- package/lib/renderer/sceneChangeCore.d.ts +39 -0
- package/lib/renderer/sceneChangeCore.js +307 -0
- package/lib/renderer/sceneChangeCore.js.map +1 -0
- package/lib/renderer/sceneChangeDetector.d.ts +3 -6
- package/lib/renderer/sceneChangeDetector.js +24 -150
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +118 -0
- package/lib/renderer/sceneLayoutSchema.js +111 -0
- package/lib/renderer/sceneLayoutSchema.js.map +1 -0
- package/lib/renderer/sceneLightChanges.d.ts +3 -3
- package/lib/renderer/sceneLightChanges.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +55 -0
- package/lib/renderer/scenePreparation.js +360 -0
- package/lib/renderer/scenePreparation.js.map +1 -0
- package/lib/renderer/scratchSampling.js +18 -18
- package/lib/renderer/scratchSampling.js.map +1 -1
- package/lib/renderer/shader.d.ts +2 -0
- package/lib/renderer/shader.js +2 -0
- package/lib/renderer/shader.js.map +1 -1
- package/lib/renderer/shaderCapabilities.d.ts +23 -0
- package/lib/renderer/shaderCapabilities.js +55 -0
- package/lib/renderer/shaderCapabilities.js.map +1 -0
- package/lib/renderer/shaderCapacity.d.ts +2 -0
- package/lib/renderer/shaderCapacity.js +5 -0
- package/lib/renderer/shaderCapacity.js.map +1 -0
- package/lib/renderer/skyModel.d.ts +9 -0
- package/lib/renderer/skyModel.js +10 -0
- package/lib/renderer/skyModel.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +60 -0
- package/lib/renderer/textureAtlas.js +145 -0
- package/lib/renderer/textureAtlas.js.map +1 -0
- package/lib/renderer/textureAtlasPixels.d.ts +7 -0
- package/lib/renderer/textureAtlasPixels.js +68 -0
- package/lib/renderer/textureAtlasPixels.js.map +1 -0
- package/lib/renderer/util.d.ts +1 -1
- package/lib/renderer/util.js.map +1 -1
- package/lib/renderer/webgl.d.ts +9 -2
- package/lib/renderer/webgl.js +54 -9
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/wgpuBindless.d.ts +26 -0
- package/lib/renderer/wgpuBindless.js +95 -0
- package/lib/renderer/wgpuBindless.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.d.ts +2 -0
- package/lib/renderer/wgpuBindlessSource.js +51 -0
- package/lib/renderer/wgpuBindlessSource.js.map +1 -0
- package/lib/renderer/wgpuMaterialConstants.d.ts +4 -0
- package/lib/renderer/wgpuMaterialConstants.js +52 -0
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -0
- package/lib/renderer/wgpuSceneUniform.d.ts +42 -0
- package/lib/renderer/wgpuSceneUniform.js +125 -0
- package/lib/renderer/wgpuSceneUniform.js.map +1 -0
- package/lib/renderer/wgpuShaderSource.d.ts +15 -0
- package/lib/renderer/wgpuShaderSource.js +31 -0
- package/lib/renderer/wgpuShaderSource.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +70 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovReflectance.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +98 -0
- package/lib/renderer/wgsl/aovReflectance.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +135 -0
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +5 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +38 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovSnapshot.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +21 -0
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovTrace.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTrace.wgsl.js +115 -0
- package/lib/renderer/wgsl/aovTrace.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.d.ts +13 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +92 -0
- package/lib/renderer/wgsl/bloom.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +43 -37
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +13 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +743 -706
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +16 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +3 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +86 -83
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +855 -857
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +42 -32
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +152 -148
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +239 -232
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +26 -13
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -91
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +1 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +12 -12
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +8 -3
- package/lib/renderer/wgsl/compose.frag.wgsl.js +143 -118
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.js +7 -7
- package/lib/renderer/wgsl/jnlm.compute.d.ts +25 -0
- package/lib/renderer/wgsl/jnlm.compute.js +315 -0
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +17 -0
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.d.ts +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js +198 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js.map +1 -0
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +17 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +612 -393
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Camera.js +7 -3
- package/lib/scene/Camera.js.map +1 -1
- package/lib/scene/EnvironmentLight.d.ts +5 -9
- package/lib/scene/EnvironmentLight.js +4 -14
- package/lib/scene/EnvironmentLight.js.map +1 -1
- package/lib/scene/EnvironmentLightState.d.ts +18 -0
- package/lib/scene/EnvironmentLightState.js +19 -0
- package/lib/scene/EnvironmentLightState.js.map +1 -0
- package/lib/scene/Geometry.d.ts +12 -6
- package/lib/scene/Geometry.js +37 -13
- package/lib/scene/Geometry.js.map +1 -1
- package/lib/scene/InstanceState.d.ts +39 -0
- package/lib/scene/InstanceState.js +77 -0
- package/lib/scene/InstanceState.js.map +1 -0
- package/lib/scene/InstancedMesh.d.ts +1 -1
- package/lib/scene/InstancedMesh.js +3 -0
- package/lib/scene/InstancedMesh.js.map +1 -1
- package/lib/scene/MaterialState.d.ts +209 -0
- package/lib/scene/MaterialState.js +231 -0
- package/lib/scene/MaterialState.js.map +1 -0
- package/lib/scene/Mesh.d.ts +4 -6
- package/lib/scene/Mesh.js +3 -11
- package/lib/scene/Mesh.js.map +1 -1
- package/lib/scene/MeshState.d.ts +20 -0
- package/lib/scene/MeshState.js +35 -0
- package/lib/scene/MeshState.js.map +1 -0
- package/lib/scene/OpenPBRMaterial.d.ts +7 -169
- package/lib/scene/OpenPBRMaterial.js +5 -223
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/PixelTexture.d.ts +6 -0
- package/lib/scene/PixelTexture.js +10 -0
- package/lib/scene/PixelTexture.js.map +1 -0
- package/lib/scene/ProceduralSky.d.ts +24 -0
- package/lib/scene/ProceduralSky.js +40 -0
- package/lib/scene/ProceduralSky.js.map +1 -0
- package/lib/scene/RectLight.d.ts +2 -13
- package/lib/scene/RectLight.js +3 -21
- package/lib/scene/RectLight.js.map +1 -1
- package/lib/scene/RectLightState.d.ts +31 -0
- package/lib/scene/RectLightState.js +26 -0
- package/lib/scene/RectLightState.js.map +1 -0
- package/lib/scene/Scene.d.ts +15 -4
- package/lib/scene/Scene.js.map +1 -1
- package/lib/scene/SceneNode.js +7 -6
- package/lib/scene/SceneNode.js.map +1 -1
- package/lib/scene/Texture.d.ts +10 -41
- package/lib/scene/Texture.js +4 -33
- package/lib/scene/Texture.js.map +1 -1
- package/lib/scene/TextureState.d.ts +35 -0
- package/lib/scene/TextureState.js +35 -0
- package/lib/scene/TextureState.js.map +1 -0
- package/lib/scene/attributeData.d.ts +4 -0
- package/lib/scene/attributeData.js +10 -0
- package/lib/scene/attributeData.js.map +1 -0
- package/lib/scene/lightState.d.ts +8 -0
- package/lib/scene/lightState.js +2 -0
- package/lib/scene/lightState.js.map +1 -0
- package/lib/scene/openPbrSchema.d.ts +7 -12
- package/lib/scene/openPbrSchema.js +273 -28
- package/lib/scene/openPbrSchema.js.map +1 -1
- package/lib/scene/skyParameters.d.ts +20 -0
- package/lib/scene/skyParameters.js +28 -0
- package/lib/scene/skyParameters.js.map +1 -0
- package/lib/scene/textureData.d.ts +9 -0
- package/lib/scene/textureData.js +2 -0
- package/lib/scene/textureData.js.map +1 -0
- package/lib/scene/texturePixels.d.ts +6 -0
- package/lib/scene/texturePixels.js +10 -0
- package/lib/scene/texturePixels.js.map +1 -0
- package/lib/settings/display.d.ts +33 -0
- package/lib/settings/display.js +7 -0
- package/lib/settings/display.js.map +1 -1
- package/lib/settings/render.d.ts +25 -3
- package/lib/settings/render.js +3 -1
- package/lib/settings/render.js.map +1 -1
- package/lib/tinybvh/tinybvh.wasm +0 -0
- package/lib/util/commonGeometry.js +7 -7
- package/lib/util/commonGeometry.js.map +1 -1
- package/lib/util/fromTHREE.d.ts +4 -1
- package/lib/util/fromTHREE.js +18 -5
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/util/geometry.js +42 -29
- package/lib/util/geometry.js.map +1 -1
- package/lib/util/loadRGBE.js +3 -4
- package/lib/util/loadRGBE.js.map +1 -1
- package/lib/util/studioLighting.d.ts +18 -0
- package/lib/util/studioLighting.js +36 -0
- package/lib/util/studioLighting.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/llms.txt +4 -0
- package/package.json +31 -5
- package/lib/renderer/texturesFromMaterials.d.ts +0 -6
- package/lib/renderer/texturesFromMaterials.js.map +0 -1
|
@@ -1,15 +1,13 @@
|
|
|
1
|
+
import { matrixStorage } from '../math/storage.js';
|
|
2
|
+
import { pixelLength, pixelValue } from '../scene/texturePixels.js';
|
|
1
3
|
import { materialEmission } from './materialEmission.js';
|
|
2
|
-
import InstancedMesh from '../scene/InstancedMesh.js';
|
|
3
4
|
import { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';
|
|
4
|
-
import { getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getSpotLightShapingFluxFactor } from './
|
|
5
|
+
import { getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getSpotLightShapingFluxFactor } from './lightsData.js';
|
|
5
6
|
import { localMaterialIndex } from './materialIndices.js';
|
|
7
|
+
import { attributeLength, attributeValue } from '../scene/attributeData.js';
|
|
6
8
|
import { vec3 } from '../math.js';
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
export const LIGHT_CHOICE_EMISSIVE_TRIANGLE = 3;
|
|
10
|
-
export const LIGHT_DOMAIN_ENVIRONMENT = 0;
|
|
11
|
-
export const LIGHT_DOMAIN_INFINITE = 1;
|
|
12
|
-
export const LIGHT_DOMAIN_LOCAL_AND_EMISSIVE = 2;
|
|
9
|
+
import { LIGHT_CHOICE_EMISSIVE_TRIANGLE } from './lightConstants.js';
|
|
10
|
+
export * from './lightConstants.js';
|
|
13
11
|
const luminanceCoefficients = [0.2126, 0.7152, 0.0722];
|
|
14
12
|
export function colorLuminance(color) {
|
|
15
13
|
return Math.max(color[0] * luminanceCoefficients[0] +
|
|
@@ -71,6 +69,7 @@ export function packIESProfiles(lights, firstTexel = 0) {
|
|
|
71
69
|
profiles.forEach((profile, index) => data.set(profile.data, index * 128 * 128));
|
|
72
70
|
return { data, offsets, texelCount: data.length / 4 };
|
|
73
71
|
}
|
|
72
|
+
// Keep the input object identity across native record-width conversions.
|
|
74
73
|
const environmentPowers = new WeakMap();
|
|
75
74
|
export function estimateEnvironmentPower(image) {
|
|
76
75
|
if (!image?.data || !image.width || !image.height)
|
|
@@ -79,22 +78,7 @@ export function estimateEnvironmentPower(image) {
|
|
|
79
78
|
if (cached !== undefined)
|
|
80
79
|
return cached;
|
|
81
80
|
const { data, width, height } = image;
|
|
82
|
-
const
|
|
83
|
-
let weightedLuminance = 0;
|
|
84
|
-
for (let y = 0; y < height; y++) {
|
|
85
|
-
const sinTheta = Math.sin(Math.PI * (y + 0.5) / height);
|
|
86
|
-
for (let x = 0; x < width; x++) {
|
|
87
|
-
const offset = (y * width + x) * channels;
|
|
88
|
-
const scale = (data instanceof Uint8Array || data instanceof Uint8ClampedArray) ? 1 / 255 : 1;
|
|
89
|
-
weightedLuminance +=
|
|
90
|
-
colorLuminance([
|
|
91
|
-
data[offset] * scale,
|
|
92
|
-
data[offset + Math.min(1, channels - 1)] * scale,
|
|
93
|
-
data[offset + Math.min(2, channels - 1)] * scale
|
|
94
|
-
]) * sinTheta;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const power = weightedLuminance * (2 * Math.PI * Math.PI) / (width * height);
|
|
81
|
+
const power = environmentPower(data, width, height);
|
|
98
82
|
environmentPowers.set(image, power);
|
|
99
83
|
return power;
|
|
100
84
|
}
|
|
@@ -124,7 +108,7 @@ export class LightChoiceBuffer {
|
|
|
124
108
|
/** Builds a Walker alias table. Each 16-byte entry is probability/alias/type/index. */
|
|
125
109
|
export function buildLightAliasTable(inputs) {
|
|
126
110
|
let active;
|
|
127
|
-
if (inputs
|
|
111
|
+
if (!Array.isArray(inputs))
|
|
128
112
|
active = inputs;
|
|
129
113
|
else {
|
|
130
114
|
active = new LightChoiceBuffer();
|
|
@@ -153,7 +137,7 @@ export function buildLightAliasTable(inputs) {
|
|
|
153
137
|
const buffer = new ArrayBuffer(count * 16);
|
|
154
138
|
const floats = new Float32Array(buffer), ints = new Int32Array(buffer);
|
|
155
139
|
while (smallCount && largeCount) {
|
|
156
|
-
const low = small[--smallCount], high = large[--largeCount];
|
|
140
|
+
const low = small[--smallCount] + 0, high = large[--largeCount] + 0;
|
|
157
141
|
floats[low * 4] = scaled[low];
|
|
158
142
|
ints[low * 4 + 1] = high;
|
|
159
143
|
scaled[high] = scaled[high] + scaled[low] - 1;
|
|
@@ -178,9 +162,33 @@ export function buildLightAliasTable(inputs) {
|
|
|
178
162
|
}
|
|
179
163
|
return { choices: new Uint32Array(buffer), pmfs, totalWeight };
|
|
180
164
|
}
|
|
181
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Builds the table a shadow catcher draws its occlusion tests from: the
|
|
167
|
+
* environment and analytic lights of `choices` at their relative weights.
|
|
168
|
+
* Emissive meshes are scene objects, not light already present in the plate
|
|
169
|
+
* the catcher darkens, so their occlusion is not catcher shadow. Returns
|
|
170
|
+
* `undefined` when `choices` holds no emissive triangle and the catcher can
|
|
171
|
+
* share the main table.
|
|
172
|
+
*/
|
|
173
|
+
export function buildShadowCatcherLightAliasTable(choices, scratch = new LightChoiceBuffer()) {
|
|
174
|
+
let emissive = 0;
|
|
175
|
+
for (let i = 0; i < choices.count; i++) {
|
|
176
|
+
if (choices.sourceTypes[i] === LIGHT_CHOICE_EMISSIVE_TRIANGLE)
|
|
177
|
+
emissive++;
|
|
178
|
+
}
|
|
179
|
+
if (!emissive)
|
|
180
|
+
return undefined;
|
|
181
|
+
scratch.reserve(choices.count - emissive);
|
|
182
|
+
for (let i = 0; i < choices.count; i++) {
|
|
183
|
+
if (choices.sourceTypes[i] !== LIGHT_CHOICE_EMISSIVE_TRIANGLE) {
|
|
184
|
+
scratch.push(choices.sourceTypes[i], choices.sourceIndices[i], choices.weights[i]);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return buildLightAliasTable(scratch);
|
|
188
|
+
}
|
|
189
|
+
function dominantLocalMaterial(geometry, indices, triangleOffset, materialCount) {
|
|
182
190
|
// Public triangles have the same raw material index on all three corners.
|
|
183
|
-
return localMaterialIndex(geometry,
|
|
191
|
+
return localMaterialIndex(geometry, indices[triangleOffset], materialCount);
|
|
184
192
|
}
|
|
185
193
|
export function collectEmissiveTriangles(bindings, materials) {
|
|
186
194
|
const triangles = [];
|
|
@@ -190,26 +198,31 @@ export function collectEmissiveTriangles(bindings, materials) {
|
|
|
190
198
|
const edge1 = vec3.create();
|
|
191
199
|
const cross = vec3.create();
|
|
192
200
|
for (const { mesh, geometry, materialIndices } of bindings) {
|
|
193
|
-
|
|
201
|
+
// Emission is constant during this synchronous collection. Compute it once
|
|
202
|
+
// per local material table instead of allocating an RGB array per triangle.
|
|
203
|
+
const samplingLuminances = [];
|
|
204
|
+
for (let local = 0; local < Math.max(1, materialIndices.length); local++) {
|
|
205
|
+
const material = materials[materialIndices[local] ?? materialIndices[0] ?? 0];
|
|
206
|
+
samplingLuminances.push(!material || material.shadowCatcher || material.unlit
|
|
207
|
+
? 0 : colorLuminance(materialEmission(material)));
|
|
208
|
+
}
|
|
209
|
+
const matrix = new Float64Array(16), parent = matrixStorage(mesh.transform);
|
|
194
210
|
for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {
|
|
195
|
-
meshInstanceTransform(mesh, instance, matrix);
|
|
196
|
-
const indices = geometry.
|
|
211
|
+
meshInstanceTransform(mesh, instance, matrix, parent);
|
|
212
|
+
const indices = geometry.indexArray;
|
|
197
213
|
const positions = geometry.position.array;
|
|
198
214
|
const uvs = geometry.uv?.array;
|
|
199
215
|
const secondaryUvs = geometry.uv1?.array ?? uvs;
|
|
200
|
-
for (let triangleOffset = 0; triangleOffset < indices
|
|
201
|
-
const localMaterialIndex = dominantLocalMaterial(geometry, triangleOffset, materialIndices.length);
|
|
216
|
+
for (let triangleOffset = 0; triangleOffset < attributeLength(indices); triangleOffset += 3) {
|
|
217
|
+
const localMaterialIndex = dominantLocalMaterial(geometry, indices, triangleOffset, materialIndices.length);
|
|
202
218
|
const materialIndex = materialIndices[localMaterialIndex] ?? materialIndices[0] ?? 0;
|
|
203
|
-
const
|
|
204
|
-
if (!material || material.shadowCatcher || material.unlit)
|
|
205
|
-
continue;
|
|
206
|
-
const samplingLuminance = colorLuminance(materialEmission(material));
|
|
219
|
+
const samplingLuminance = samplingLuminances[localMaterialIndex];
|
|
207
220
|
if (!(samplingLuminance > 1e-8))
|
|
208
221
|
continue;
|
|
209
222
|
const triangleIndices = [
|
|
210
|
-
indices
|
|
211
|
-
indices
|
|
212
|
-
indices
|
|
223
|
+
attributeValue(indices, triangleOffset),
|
|
224
|
+
attributeValue(indices, triangleOffset + 1),
|
|
225
|
+
attributeValue(indices, triangleOffset + 2)
|
|
213
226
|
];
|
|
214
227
|
for (let corner = 0; corner < 3; corner++) {
|
|
215
228
|
const vertex = triangleIndices[corner];
|
|
@@ -248,29 +261,49 @@ export function collectEmissiveTriangles(bindings, materials) {
|
|
|
248
261
|
}
|
|
249
262
|
return triangles;
|
|
250
263
|
}
|
|
264
|
+
function packEmissivePoint(data, offset, point) {
|
|
265
|
+
// Preserve TypedArray.set's overlapping-view semantics for callers with aliases.
|
|
266
|
+
if (data.buffer === point.buffer) {
|
|
267
|
+
data.set(point, offset);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
data[offset] = point[0];
|
|
271
|
+
data[offset + 1] = point[1];
|
|
272
|
+
data[offset + 2] = point[2];
|
|
273
|
+
}
|
|
251
274
|
export function packEmissiveTriangles(triangles, data = new Float32Array(Math.max(triangles.length, 1) * 24)) {
|
|
252
275
|
triangles.forEach((triangle, index) => {
|
|
253
276
|
const offset = index * 24;
|
|
254
|
-
data
|
|
277
|
+
packEmissivePoint(data, offset, triangle.p0);
|
|
255
278
|
data[offset + 3] = triangle.selectionPmf;
|
|
256
|
-
data
|
|
279
|
+
packEmissivePoint(data, offset + 4, triangle.p1);
|
|
257
280
|
data[offset + 7] = triangle.area;
|
|
258
|
-
data
|
|
281
|
+
packEmissivePoint(data, offset + 8, triangle.p2);
|
|
259
282
|
data[offset + 11] = triangle.materialIndex;
|
|
260
|
-
data
|
|
261
|
-
data
|
|
262
|
-
data
|
|
263
|
-
data
|
|
264
|
-
data
|
|
265
|
-
data
|
|
283
|
+
data[offset + 12] = triangle.uv0[0];
|
|
284
|
+
data[offset + 13] = triangle.uv0[1];
|
|
285
|
+
data[offset + 14] = triangle.uv1[0];
|
|
286
|
+
data[offset + 15] = triangle.uv1[1];
|
|
287
|
+
data[offset + 16] = triangle.uv2[0];
|
|
288
|
+
data[offset + 17] = triangle.uv2[1];
|
|
289
|
+
data[offset + 18] = triangle.secondaryUv0[0];
|
|
290
|
+
data[offset + 19] = triangle.secondaryUv0[1];
|
|
291
|
+
data[offset + 20] = triangle.secondaryUv1[0];
|
|
292
|
+
data[offset + 21] = triangle.secondaryUv1[1];
|
|
293
|
+
data[offset + 22] = triangle.secondaryUv2[0];
|
|
294
|
+
data[offset + 23] = triangle.secondaryUv2[1];
|
|
266
295
|
});
|
|
267
296
|
return data;
|
|
268
297
|
}
|
|
298
|
+
// WeakMap class fields have no native representation in scriptc 0.3.2.
|
|
299
|
+
// Keep the same per-cache weak ownership in a module-owned registry.
|
|
300
|
+
const emissiveBindings = new WeakMap();
|
|
269
301
|
/** Caches world-space vertices per mesh, independently of emission strength. */
|
|
270
302
|
export class EmissiveTriangleCache {
|
|
271
|
-
|
|
303
|
+
constructor() { emissiveBindings.set(this, new WeakMap()); }
|
|
272
304
|
_triangles = [];
|
|
273
305
|
collect(bindings, materials) {
|
|
306
|
+
const cachedBindings = emissiveBindings.get(this);
|
|
274
307
|
this._triangles.length = 0;
|
|
275
308
|
for (const binding of bindings) {
|
|
276
309
|
const { mesh, geometry, materialIndices } = binding;
|
|
@@ -278,17 +311,17 @@ export class EmissiveTriangleCache {
|
|
|
278
311
|
const m = materials[index];
|
|
279
312
|
return !!m && !m.unlit && !m.shadowCatcher && colorLuminance(materialEmission(m)) > 1e-8;
|
|
280
313
|
};
|
|
281
|
-
const instanceVersion = mesh
|
|
314
|
+
const instanceVersion = mesh.instanceData?.transformsVersion ?? 0;
|
|
282
315
|
const instanceCount = meshInstanceCount(mesh);
|
|
283
|
-
const instanceTransforms = mesh
|
|
284
|
-
let cached =
|
|
316
|
+
const instanceTransforms = mesh.instanceData?.transforms;
|
|
317
|
+
let cached = cachedBindings.get(mesh);
|
|
285
318
|
if (!cached || cached.geometry !== geometry || cached.version !== geometry.version || cached.instanceVersion !== instanceVersion || cached.instanceCount !== instanceCount || cached.instanceTransforms !== instanceTransforms ||
|
|
286
319
|
cached.indices.length !== materialIndices.length || materialIndices.some((index, i) => cached.indices[i] !== index || cached.activity[i] !== isActive(index)) ||
|
|
287
|
-
mesh
|
|
288
|
-
cached = { geometry, version: geometry.version, instanceVersion, instanceCount, instanceTransforms, matrix:
|
|
320
|
+
meshMatrixChanged(mesh, cached.matrix)) {
|
|
321
|
+
cached = { geometry, version: geometry.version, instanceVersion, instanceCount, instanceTransforms, matrix: copyMeshMatrix(mesh),
|
|
289
322
|
indices: materialIndices.slice(), activity: materialIndices.map(isActive),
|
|
290
323
|
triangles: collectEmissiveTriangles([binding], materials) };
|
|
291
|
-
|
|
324
|
+
cachedBindings.set(mesh, cached);
|
|
292
325
|
}
|
|
293
326
|
else {
|
|
294
327
|
for (const triangle of cached.triangles) {
|
|
@@ -302,4 +335,38 @@ export class EmissiveTriangleCache {
|
|
|
302
335
|
return this._triangles;
|
|
303
336
|
}
|
|
304
337
|
}
|
|
338
|
+
function copyMeshMatrix(mesh) { return matrixStorage(mesh.transform); }
|
|
339
|
+
function meshMatrixChanged(mesh, previous) {
|
|
340
|
+
const matrix = matrixStorage(mesh.transform);
|
|
341
|
+
for (let i = 0; i < matrix.length; i++)
|
|
342
|
+
if (!Object.is(matrix[i], previous[i]))
|
|
343
|
+
return true;
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
function environmentPower(data, width, height) {
|
|
347
|
+
if (data instanceof Uint8Array)
|
|
348
|
+
return environmentPowerKernel(data, width, height, 1 / 255);
|
|
349
|
+
if (data instanceof Uint8ClampedArray)
|
|
350
|
+
return environmentPowerKernel(data, width, height, 1 / 255);
|
|
351
|
+
if (data instanceof Float32Array)
|
|
352
|
+
return environmentPowerKernel(data, width, height, 1);
|
|
353
|
+
return environmentPowerKernel(data, width, height, 1);
|
|
354
|
+
}
|
|
355
|
+
function environmentPowerKernel(data, width, height, scale) {
|
|
356
|
+
const channels = Math.max(Math.floor(pixelLength(data) / (width * height)), 1);
|
|
357
|
+
let weightedLuminance = 0;
|
|
358
|
+
for (let y = 0; y < height; y++) {
|
|
359
|
+
const sinTheta = Math.sin(Math.PI * (y + 0.5) / height);
|
|
360
|
+
for (let x = 0; x < width; x++) {
|
|
361
|
+
const offset = (y * width + x) * channels;
|
|
362
|
+
weightedLuminance +=
|
|
363
|
+
colorLuminance([
|
|
364
|
+
pixelValue(data, offset) * scale,
|
|
365
|
+
pixelValue(data, offset + Math.min(1, channels - 1)) * scale,
|
|
366
|
+
pixelValue(data, offset + Math.min(2, channels - 1)) * scale
|
|
367
|
+
]) * sinTheta;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return weightedLuminance * (2 * Math.PI * Math.PI) / (width * height);
|
|
371
|
+
}
|
|
305
372
|
//# sourceMappingURL=lightSampling.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightSampling.js","sourceRoot":"","sources":["../../src/renderer/lightSampling.ts"],"names":[],"mappings":"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","sourcesContent":["import { materialEmission } from './materialEmission.js';\nimport InstancedMesh from '../scene/InstancedMesh.js';\nimport { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';\nimport { getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getSpotLightShapingFluxFactor } from './lightsUtil.js';\nimport { localMaterialIndex } from './materialIndices.js';\nimport { TexturePixelSource, vec3 } from '../math.js';\nimport DirectionalLight from '../scene/DirectionalLight.js';\nimport Geometry from '../scene/Geometry.js';\nimport Mesh from '../scene/Mesh.js';\nimport RectLight from '../scene/RectLight.js';\nimport SphereLight from '../scene/SphereLight.js';\nimport SpotLight from '../scene/SpotLight.js';\nimport IESProfile from '../scene/IESProfile.js';\nimport OpenPBRMaterial from '../scene/OpenPBRMaterial.js';\n\nexport const LIGHT_CHOICE_ENVIRONMENT = 1;\nexport const LIGHT_CHOICE_ANALYTIC = 2;\nexport const LIGHT_CHOICE_EMISSIVE_TRIANGLE = 3;\n\nexport const LIGHT_DOMAIN_ENVIRONMENT = 0;\nexport const LIGHT_DOMAIN_INFINITE = 1;\nexport const LIGHT_DOMAIN_LOCAL_AND_EMISSIVE = 2;\ntype AnalyticLight = DirectionalLight | SphereLight | SpotLight | RectLight;\n\nexport interface EmissiveTriangle {\n p0: vec3.Vec3Array;\n p1: vec3.Vec3Array;\n p2: vec3.Vec3Array;\n uv0: [number, number];\n uv1: [number, number];\n uv2: [number, number];\n secondaryUv0: [number, number];\n secondaryUv1: [number, number];\n secondaryUv2: [number, number];\n materialIndex: number;\n area: number;\n samplingLuminance: number;\n selectionPmf: number;\n}\n\nexport interface EmissiveMeshBinding {\n mesh: Mesh;\n geometry: Geometry;\n materialIndices: number[];\n}\n\nexport interface LightChoiceInput {\n sourceType: number;\n sourceIndex: number;\n weight: number;\n}\n\nexport interface LightSamplingDistribution {\n choices: Uint32Array;\n pmfs: Float32Array;\n totalWeight: number;\n}\n\nconst luminanceCoefficients = [0.2126, 0.7152, 0.0722] as const;\n\nexport function colorLuminance(color: ArrayLike<number>) {\n return Math.max(\n color[0] * luminanceCoefficients[0] +\n color[1] * luminanceCoefficients[1] +\n color[2] * luminanceCoefficients[2],\n 0\n );\n}\n\nexport function estimateAnalyticLightPower(light: AnalyticLight) {\n const emittedLuminance = colorLuminance(light.color) * light.intensity;\n if (!(emittedLuminance > 0)) return 0;\n if (light.type === 'RectLight') {\n return emittedLuminance * Math.PI * Math.max(getRectLightArea(light), 0);\n }\n if (light.type === 'SphereLight') {\n if (light.radius === 0) return emittedLuminance * 4 * Math.PI;\n return emittedLuminance * Math.PI * Math.max(getSphereLightArea(light), 0);\n }\n if (light.type === 'SpotLight') {\n const radianceLuminance =\n colorLuminance(light.color) * getSpotLightRadiance(light);\n // The selection power is an approximation and ignores the IES profile.\n if (light.radius === 0) {\n return emittedLuminance *\n 4 * Math.PI *\n getSpotLightShapingFluxFactor(light);\n }\n return (\n radianceLuminance *\n Math.PI *\n getSpotLightArea(light) *\n getSpotLightShapingFluxFactor(light)\n );\n }\n // A directional light has no finite emitting area. 4π keeps its heuristic\n // weight on roughly the same scale as an environment map integral.\n return emittedLuminance * 4 * Math.PI;\n}\n\nexport function sphereSolidAnglePdf(distanceToCenter: number, radius: number) {\n if (distanceToCenter <= radius) return 1 / (4 * Math.PI);\n const cosThetaMax = Math.sqrt(\n Math.max(0, 1 - radius * radius / (distanceToCenter * distanceToCenter))\n );\n return 1 / Math.max(2 * Math.PI * (1 - cosThetaMax), 1e-8);\n}\n\n/** Packs unique 128² peak-normalized IES profiles four scalar samples per texel. */\nexport function packIESProfiles(lights: AnalyticLight[], firstTexel = 0) {\n const offsets = new Int32Array(lights.length).fill(-1);\n const profiles: IESProfile[] = [];\n const indices = new Map<IESProfile, number>();\n lights.forEach((light, index) => {\n if (light.type !== 'SpotLight' || !light.iesProfile) return;\n let profileIndex = indices.get(light.iesProfile);\n if (profileIndex == null) {\n profileIndex = profiles.length;\n indices.set(light.iesProfile, profileIndex);\n profiles.push(light.iesProfile);\n }\n offsets[index] = firstTexel + profileIndex * ((128 * 128) / 4);\n });\n const data = new Float32Array(profiles.length * 128 * 128);\n profiles.forEach((profile, index) => data.set(profile.data, index * 128 * 128));\n return { data, offsets, texelCount: data.length / 4 };\n}\n\nconst environmentPowers = new WeakMap<TexturePixelSource, number>();\n\nexport function estimateEnvironmentPower(image?: TexturePixelSource) {\n if (!image?.data || !image.width || !image.height) return 0;\n const cached = environmentPowers.get(image);\n if (cached !== undefined) return cached;\n const { data, width, height } = image;\n const channels = Math.max(Math.floor(data.length / (width * height)), 1);\n let weightedLuminance = 0;\n for (let y = 0; y < height; y++) {\n const sinTheta = Math.sin(Math.PI * (y + 0.5) / height);\n for (let x = 0; x < width; x++) {\n const offset = (y * width + x) * channels;\n const scale = (data instanceof Uint8Array || data instanceof Uint8ClampedArray) ? 1 / 255 : 1;\n weightedLuminance +=\n colorLuminance([\n data[offset] * scale,\n data[offset + Math.min(1, channels - 1)] * scale,\n data[offset + Math.min(2, channels - 1)] * scale\n ]) * sinTheta;\n }\n }\n const power = weightedLuminance * (2 * Math.PI * Math.PI) / (width * height);\n environmentPowers.set(image, power);\n return power;\n}\n\n/** Reusable typed choices; insertion order matches the sampling distribution. */\nexport class LightChoiceBuffer {\n count = 0;\n sourceTypes = new Uint32Array(0);\n sourceIndices = new Uint32Array(0);\n weights = new Float64Array(0);\n reserve(capacity: number) {\n this.count = 0;\n if (this.weights.length < capacity) {\n this.sourceTypes = new Uint32Array(capacity);\n this.sourceIndices = new Uint32Array(capacity);\n this.weights = new Float64Array(capacity);\n }\n }\n push(sourceType: number, sourceIndex: number, weight: number) {\n if (!(weight > 0) || !isFinite(weight)) return;\n const i = this.count++;\n this.sourceTypes[i] = sourceType; this.sourceIndices[i] = sourceIndex; this.weights[i] = weight;\n }\n}\n\n/** Builds a Walker alias table. Each 16-byte entry is probability/alias/type/index. */\nexport function buildLightAliasTable(inputs: LightChoiceInput[] | LightChoiceBuffer): LightSamplingDistribution {\n let active: LightChoiceBuffer;\n if (inputs instanceof LightChoiceBuffer) active = inputs;\n else {\n active = new LightChoiceBuffer(); active.reserve(inputs.length);\n for (const input of inputs) active.push(input.sourceType, input.sourceIndex, input.weight);\n }\n const count = active.count;\n let totalWeight = 0;\n for (let i = 0; i < count; i++) totalWeight += active.weights[i];\n if (!count || !(totalWeight > 0)) return { choices: new Uint32Array(4), pmfs: new Float32Array(0), totalWeight: 0 };\n const pmfs = new Float32Array(count);\n const scaled = new Float64Array(count);\n const small = new Uint32Array(count), large = new Uint32Array(count);\n let smallCount = 0, largeCount = 0;\n for (let i = 0; i < count; i++) {\n pmfs[i] = active.weights[i] / totalWeight;\n scaled[i] = pmfs[i] * count;\n if (scaled[i] < 1) small[smallCount++] = i; else large[largeCount++] = i;\n }\n const buffer = new ArrayBuffer(count * 16);\n const floats = new Float32Array(buffer), ints = new Int32Array(buffer);\n while (smallCount && largeCount) {\n const low = small[--smallCount], high = large[--largeCount];\n floats[low * 4] = scaled[low]; ints[low * 4 + 1] = high;\n scaled[high] = scaled[high] + scaled[low] - 1;\n if (scaled[high] < 1) small[smallCount++] = high; else large[largeCount++] = high;\n }\n for (let i = 0; i < smallCount; i++) { const index = small[i]; floats[index * 4] = 1; ints[index * 4 + 1] = index; }\n for (let i = 0; i < largeCount; i++) { const index = large[i]; floats[index * 4] = 1; ints[index * 4 + 1] = index; }\n for (let i = 0; i < count; i++) { ints[i * 4 + 2] = active.sourceTypes[i]; ints[i * 4 + 3] = active.sourceIndices[i]; }\n return { choices: new Uint32Array(buffer), pmfs, totalWeight };\n}\n\nfunction dominantLocalMaterial(geometry: Geometry, triangleOffset: number, materialCount: number) {\n // Public triangles have the same raw material index on all three corners.\n return localMaterialIndex(geometry, geometry.indices.array[triangleOffset], materialCount);\n}\n\nexport function collectEmissiveTriangles(\n bindings: EmissiveMeshBinding[],\n materials: OpenPBRMaterial[]\n) {\n const triangles: EmissiveTriangle[] = [];\n const local = [vec3.create(), vec3.create(), vec3.create()];\n const world = [vec3.create(), vec3.create(), vec3.create()];\n const edge0 = vec3.create();\n const edge1 = vec3.create();\n const cross = vec3.create();\n\n for (const { mesh, geometry, materialIndices } of bindings) {\n const matrix = Array(16).fill(0);\n for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {\n meshInstanceTransform(mesh, instance, matrix);\n const indices = geometry.indices.array;\n const positions = geometry.position.array;\n const uvs = geometry.uv?.array;\n const secondaryUvs = geometry.uv1?.array ?? uvs;\n for (let triangleOffset = 0; triangleOffset < indices.length; triangleOffset += 3) {\n const localMaterialIndex = dominantLocalMaterial(geometry, triangleOffset, materialIndices.length);\n const materialIndex = materialIndices[localMaterialIndex] ?? materialIndices[0] ?? 0;\n const material = materials[materialIndex];\n if (!material || material.shadowCatcher || material.unlit) continue;\n const samplingLuminance =\n colorLuminance(materialEmission(material));\n if (!(samplingLuminance > 1e-8)) continue;\n\n const triangleIndices = [\n indices[triangleOffset],\n indices[triangleOffset + 1],\n indices[triangleOffset + 2]\n ];\n for (let corner = 0; corner < 3; corner++) {\n const vertex = triangleIndices[corner];\n vec3.set(\n local[corner],\n positions[vertex * geometry.position.itemSize],\n positions[vertex * geometry.position.itemSize + 1],\n positions[vertex * geometry.position.itemSize + 2]\n );\n vec3.transformMat4(world[corner], local[corner], matrix);\n }\n vec3.sub(edge0, world[1], world[0]);\n vec3.sub(edge1, world[2], world[0]);\n vec3.cross(cross, edge0, edge1);\n const area = 0.5 * vec3.length(cross);\n if (!(area > 1e-10) || !isFinite(area)) continue;\n\n const triangleUvs = triangleIndices.map((vertex) =>\n uvs\n ? [uvs[vertex * 2], uvs[vertex * 2 + 1]] as [number, number]\n : [0, 0] as [number, number]\n );\n const triangleSecondaryUvs = triangleIndices.map((vertex) =>\n secondaryUvs\n ? [secondaryUvs[vertex * 2], secondaryUvs[vertex * 2 + 1]] as [number, number]\n : [0, 0] as [number, number]\n );\n triangles.push({\n p0: vec3.clone(world[0]),\n p1: vec3.clone(world[1]),\n p2: vec3.clone(world[2]),\n uv0: triangleUvs[0],\n uv1: triangleUvs[1],\n uv2: triangleUvs[2],\n secondaryUv0: triangleSecondaryUvs[0],\n secondaryUv1: triangleSecondaryUvs[1],\n secondaryUv2: triangleSecondaryUvs[2],\n materialIndex,\n area,\n samplingLuminance,\n selectionPmf: 0\n });\n }\n }\n }\n return triangles;\n}\n\nexport function packEmissiveTriangles(triangles: EmissiveTriangle[], data: Float32Array = new Float32Array(Math.max(triangles.length, 1) * 24)) {\n triangles.forEach((triangle, index) => {\n const offset = index * 24;\n data.set(triangle.p0, offset);\n data[offset + 3] = triangle.selectionPmf;\n data.set(triangle.p1, offset + 4);\n data[offset + 7] = triangle.area;\n data.set(triangle.p2, offset + 8);\n data[offset + 11] = triangle.materialIndex;\n data.set(triangle.uv0, offset + 12);\n data.set(triangle.uv1, offset + 14);\n data.set(triangle.uv2, offset + 16);\n data.set(triangle.secondaryUv0, offset + 18);\n data.set(triangle.secondaryUv1, offset + 20);\n data.set(triangle.secondaryUv2, offset + 22);\n });\n return data;\n}\n\n\n/** Caches world-space vertices per mesh, independently of emission strength. */\nexport class EmissiveTriangleCache {\n private _bindings = new WeakMap<Mesh, { geometry: Geometry; version: number; instanceVersion: number; instanceCount: number; instanceTransforms?: Float32Array; matrix: Float64Array;\n indices: number[]; activity: boolean[]; triangles: EmissiveTriangle[] }>();\n private _triangles: EmissiveTriangle[] = [];\n collect(bindings: EmissiveMeshBinding[], materials: OpenPBRMaterial[]) {\n this._triangles.length = 0;\n for (const binding of bindings) {\n const { mesh, geometry, materialIndices } = binding;\n const isActive = (index: number) => {\n const m = materials[index];\n return !!m && !m.unlit && !m.shadowCatcher && colorLuminance(materialEmission(m)) > 1e-8;\n };\n const instanceVersion = mesh instanceof InstancedMesh ? mesh.transformsVersion : 0;\n const instanceCount = meshInstanceCount(mesh);\n const instanceTransforms = mesh instanceof InstancedMesh ? mesh.transforms : undefined;\n let cached = this._bindings.get(mesh);\n if (!cached || cached.geometry !== geometry || cached.version !== geometry.version || cached.instanceVersion !== instanceVersion || cached.instanceCount !== instanceCount || cached.instanceTransforms !== instanceTransforms ||\n cached.indices.length !== materialIndices.length || materialIndices.some((index, i) =>\n cached!.indices[i] !== index || cached!.activity[i] !== isActive(index)) ||\n mesh.transform.some((value: number, i: number) => !Object.is(value, cached!.matrix[i]))) {\n cached = { geometry, version: geometry.version, instanceVersion, instanceCount, instanceTransforms, matrix: Float64Array.from(mesh.transform),\n indices: materialIndices.slice(), activity: materialIndices.map(isActive),\n triangles: collectEmissiveTriangles([binding], materials) };\n this._bindings.set(mesh, cached);\n } else {\n for (const triangle of cached.triangles) {\n const m = materials[triangle.materialIndex];\n triangle.samplingLuminance = colorLuminance(materialEmission(m));\n }\n }\n for (const triangle of cached.triangles) this._triangles.push(triangle);\n }\n return this._triangles;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lightSampling.js","sourceRoot":"","sources":["../../src/renderer/lightSampling.ts"],"names":[],"mappings":"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","sourcesContent":["import {matrixStorage} from '../math/storage.js';\nimport { pixelLength, pixelValue } from '../scene/texturePixels.js';\nimport { materialEmission } from './materialEmission.js';\nimport { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';\nimport { getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getSpotLightShapingFluxFactor } from './lightsData.js';\nimport { localMaterialIndex } from './materialIndices.js';\nimport { attributeLength, attributeValue } from '../scene/attributeData.js';\nimport { type TexturePixelSource, vec3 } from '../math.js';\nimport DirectionalLight from '../scene/DirectionalLight.js';\nimport Geometry from '../scene/Geometry.js';\nimport type Mesh from '../scene/MeshState.js';\nimport type RectLight from '../scene/RectLightState.js';\nimport SphereLight from '../scene/SphereLight.js';\nimport SpotLight from '../scene/SpotLight.js';\nimport IESProfile from '../scene/IESProfile.js';\nimport type OpenPBRMaterial from '../scene/MaterialState.js';\n\nimport { LIGHT_CHOICE_EMISSIVE_TRIANGLE } from './lightConstants.js';\nexport * from './lightConstants.js';\ntype AnalyticLight = DirectionalLight | SphereLight | SpotLight | RectLight;\n\nexport interface EmissiveTriangle {\n p0: Float32Array;\n p1: Float32Array;\n p2: Float32Array;\n uv0: [number, number];\n uv1: [number, number];\n uv2: [number, number];\n secondaryUv0: [number, number];\n secondaryUv1: [number, number];\n secondaryUv2: [number, number];\n materialIndex: number;\n area: number;\n samplingLuminance: number;\n selectionPmf: number;\n}\n\nexport interface EmissiveMeshBinding {\n mesh: Mesh;\n geometry: Geometry;\n materialIndices: number[];\n}\n\nexport interface LightChoiceInput {\n sourceType: number;\n sourceIndex: number;\n weight: number;\n}\n\nexport interface LightSamplingDistribution {\n choices: Uint32Array;\n pmfs: Float32Array;\n totalWeight: number;\n}\n\nconst luminanceCoefficients = [0.2126, 0.7152, 0.0722] as const;\n\nexport function colorLuminance<T extends ArrayLike<number>>(color: T) {\n return Math.max(\n color[0] * luminanceCoefficients[0] +\n color[1] * luminanceCoefficients[1] +\n color[2] * luminanceCoefficients[2],\n 0\n );\n}\n\nexport function estimateAnalyticLightPower(light: AnalyticLight) {\n const emittedLuminance = colorLuminance(light.color) * light.intensity;\n if (!(emittedLuminance > 0)) return 0;\n if (light.type === 'RectLight') {\n return emittedLuminance * Math.PI * Math.max(getRectLightArea(light), 0);\n }\n if (light.type === 'SphereLight') {\n if (light.radius === 0) return emittedLuminance * 4 * Math.PI;\n return emittedLuminance * Math.PI * Math.max(getSphereLightArea(light), 0);\n }\n if (light.type === 'SpotLight') {\n const radianceLuminance =\n colorLuminance(light.color) * getSpotLightRadiance(light);\n // The selection power is an approximation and ignores the IES profile.\n if (light.radius === 0) {\n return emittedLuminance *\n 4 * Math.PI *\n getSpotLightShapingFluxFactor(light);\n }\n return (\n radianceLuminance *\n Math.PI *\n getSpotLightArea(light) *\n getSpotLightShapingFluxFactor(light)\n );\n }\n // A directional light has no finite emitting area. 4π keeps its heuristic\n // weight on roughly the same scale as an environment map integral.\n return emittedLuminance * 4 * Math.PI;\n}\n\nexport function sphereSolidAnglePdf(distanceToCenter: number, radius: number) {\n if (distanceToCenter <= radius) return 1 / (4 * Math.PI);\n const cosThetaMax = Math.sqrt(\n Math.max(0, 1 - radius * radius / (distanceToCenter * distanceToCenter))\n );\n return 1 / Math.max(2 * Math.PI * (1 - cosThetaMax), 1e-8);\n}\n\n/** Packs unique 128² peak-normalized IES profiles four scalar samples per texel. */\nexport function packIESProfiles(lights: AnalyticLight[], firstTexel = 0) {\n const offsets = new Int32Array(lights.length).fill(-1);\n const profiles: IESProfile[] = [];\n const indices = new Map<IESProfile, number>();\n lights.forEach((light, index) => {\n if (light.type !== 'SpotLight' || !light.iesProfile) return;\n let profileIndex = indices.get(light.iesProfile);\n if (profileIndex == null) {\n profileIndex = profiles.length;\n indices.set(light.iesProfile, profileIndex);\n profiles.push(light.iesProfile);\n }\n offsets[index] = firstTexel + profileIndex * ((128 * 128) / 4);\n });\n const data = new Float32Array(profiles.length * 128 * 128);\n profiles.forEach((profile, index) => data.set(profile.data, index * 128 * 128));\n return { data, offsets, texelCount: data.length / 4 };\n}\n\n// Keep the input object identity across native record-width conversions.\nconst environmentPowers = new WeakMap<object, number>();\n\nexport function estimateEnvironmentPower<T extends TexturePixelSource>(image?: T) {\n if (!image?.data || !image.width || !image.height) return 0;\n const cached = environmentPowers.get(image);\n if (cached !== undefined) return cached;\n const { data, width, height } = image;\n const power = environmentPower(data, width, height);\n environmentPowers.set(image, power);\n return power;\n}\n\n/** Reusable typed choices; insertion order matches the sampling distribution. */\nexport class LightChoiceBuffer {\n count = 0;\n sourceTypes = new Uint32Array(0);\n sourceIndices = new Uint32Array(0);\n weights = new Float64Array(0);\n reserve(capacity: number) {\n this.count = 0;\n if (this.weights.length < capacity) {\n this.sourceTypes = new Uint32Array(capacity);\n this.sourceIndices = new Uint32Array(capacity);\n this.weights = new Float64Array(capacity);\n }\n }\n push(sourceType: number, sourceIndex: number, weight: number) {\n if (!(weight > 0) || !isFinite(weight)) return;\n const i = this.count++;\n this.sourceTypes[i] = sourceType; this.sourceIndices[i] = sourceIndex; this.weights[i] = weight;\n }\n}\n\n/** Builds a Walker alias table. Each 16-byte entry is probability/alias/type/index. */\nexport function buildLightAliasTable(inputs: LightChoiceInput[] | LightChoiceBuffer): LightSamplingDistribution {\n let active: LightChoiceBuffer;\n if (!Array.isArray(inputs)) active = inputs;\n else {\n active = new LightChoiceBuffer(); active.reserve(inputs.length);\n for (const input of inputs) active.push(input.sourceType, input.sourceIndex, input.weight);\n }\n const count = active.count;\n let totalWeight = 0;\n for (let i = 0; i < count; i++) totalWeight += active.weights[i];\n if (!count || !(totalWeight > 0)) return { choices: new Uint32Array(4), pmfs: new Float32Array(0), totalWeight: 0 };\n const pmfs = new Float32Array(count);\n const scaled = new Float64Array(count);\n const small = new Uint32Array(count), large = new Uint32Array(count);\n let smallCount = 0, largeCount = 0;\n for (let i = 0; i < count; i++) {\n pmfs[i] = active.weights[i] / totalWeight;\n scaled[i] = pmfs[i] * count;\n if (scaled[i] < 1) small[smallCount++] = i; else large[largeCount++] = i;\n }\n const buffer = new ArrayBuffer(count * 16);\n const floats = new Float32Array(buffer), ints = new Int32Array(buffer);\n while (smallCount && largeCount) {\n const low = small[--smallCount] + 0, high = large[--largeCount] + 0;\n floats[low * 4] = scaled[low]; ints[low * 4 + 1] = high;\n scaled[high] = scaled[high] + scaled[low] - 1;\n if (scaled[high] < 1) small[smallCount++] = high; else large[largeCount++] = high;\n }\n for (let i = 0; i < smallCount; i++) { const index = small[i]; floats[index * 4] = 1; ints[index * 4 + 1] = index; }\n for (let i = 0; i < largeCount; i++) { const index = large[i]; floats[index * 4] = 1; ints[index * 4 + 1] = index; }\n for (let i = 0; i < count; i++) { ints[i * 4 + 2] = active.sourceTypes[i]; ints[i * 4 + 3] = active.sourceIndices[i]; }\n return { choices: new Uint32Array(buffer), pmfs, totalWeight };\n}\n\n/**\n * Builds the table a shadow catcher draws its occlusion tests from: the\n * environment and analytic lights of `choices` at their relative weights.\n * Emissive meshes are scene objects, not light already present in the plate\n * the catcher darkens, so their occlusion is not catcher shadow. Returns\n * `undefined` when `choices` holds no emissive triangle and the catcher can\n * share the main table.\n */\nexport function buildShadowCatcherLightAliasTable(\n choices: LightChoiceBuffer,\n scratch = new LightChoiceBuffer()\n): LightSamplingDistribution | undefined {\n let emissive = 0;\n for (let i = 0; i < choices.count; i++) {\n if (choices.sourceTypes[i] === LIGHT_CHOICE_EMISSIVE_TRIANGLE) emissive++;\n }\n if (!emissive) return undefined;\n scratch.reserve(choices.count - emissive);\n for (let i = 0; i < choices.count; i++) {\n if (choices.sourceTypes[i] !== LIGHT_CHOICE_EMISSIVE_TRIANGLE) {\n scratch.push(choices.sourceTypes[i], choices.sourceIndices[i], choices.weights[i]);\n }\n }\n return buildLightAliasTable(scratch);\n}\n\nfunction dominantLocalMaterial(geometry: Geometry, indices: Uint32Array, triangleOffset: number, materialCount: number) {\n // Public triangles have the same raw material index on all three corners.\n return localMaterialIndex(geometry, indices[triangleOffset], materialCount);\n}\n\nexport function collectEmissiveTriangles(\n bindings: EmissiveMeshBinding[],\n materials: OpenPBRMaterial[]\n) {\n const triangles: EmissiveTriangle[] = [];\n const local = [vec3.create(), vec3.create(), vec3.create()];\n const world = [vec3.create(), vec3.create(), vec3.create()];\n const edge0 = vec3.create();\n const edge1 = vec3.create();\n const cross = vec3.create();\n\n for (const { mesh, geometry, materialIndices } of bindings) {\n // Emission is constant during this synchronous collection. Compute it once\n // per local material table instead of allocating an RGB array per triangle.\n const samplingLuminances: number[] = [];\n for (let local = 0; local < Math.max(1, materialIndices.length); local++) {\n const material = materials[materialIndices[local] ?? materialIndices[0] ?? 0];\n samplingLuminances.push(!material || material.shadowCatcher || material.unlit\n ? 0 : colorLuminance(materialEmission(material)));\n }\n const matrix = new Float64Array(16), parent = matrixStorage(mesh.transform);\n for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {\n meshInstanceTransform(mesh, instance, matrix, parent);\n const indices = geometry.indexArray;\n const positions = geometry.position.array;\n const uvs = geometry.uv?.array;\n const secondaryUvs = geometry.uv1?.array ?? uvs;\n for (let triangleOffset = 0; triangleOffset < attributeLength(indices); triangleOffset += 3) {\n const localMaterialIndex = dominantLocalMaterial(geometry, indices, triangleOffset, materialIndices.length);\n const materialIndex = materialIndices[localMaterialIndex] ?? materialIndices[0] ?? 0;\n const samplingLuminance = samplingLuminances[localMaterialIndex];\n if (!(samplingLuminance > 1e-8)) continue;\n\n const triangleIndices = [\n attributeValue(indices, triangleOffset),\n attributeValue(indices, triangleOffset + 1),\n attributeValue(indices, triangleOffset + 2)\n ];\n for (let corner = 0; corner < 3; corner++) {\n const vertex = triangleIndices[corner];\n vec3.set(\n local[corner],\n positions[vertex * geometry.position.itemSize],\n positions[vertex * geometry.position.itemSize + 1],\n positions[vertex * geometry.position.itemSize + 2]\n );\n vec3.transformMat4(world[corner], local[corner], matrix);\n }\n vec3.sub(edge0, world[1], world[0]);\n vec3.sub(edge1, world[2], world[0]);\n vec3.cross(cross, edge0, edge1);\n const area = 0.5 * vec3.length(cross);\n if (!(area > 1e-10) || !isFinite(area)) continue;\n\n const triangleUvs = triangleIndices.map((vertex) =>\n uvs\n ? [uvs[vertex * 2], uvs[vertex * 2 + 1]] as [number, number]\n : [0, 0] as [number, number]\n );\n const triangleSecondaryUvs = triangleIndices.map((vertex) =>\n secondaryUvs\n ? [secondaryUvs[vertex * 2], secondaryUvs[vertex * 2 + 1]] as [number, number]\n : [0, 0] as [number, number]\n );\n triangles.push({\n p0: vec3.clone(world[0]),\n p1: vec3.clone(world[1]),\n p2: vec3.clone(world[2]),\n uv0: triangleUvs[0],\n uv1: triangleUvs[1],\n uv2: triangleUvs[2],\n secondaryUv0: triangleSecondaryUvs[0],\n secondaryUv1: triangleSecondaryUvs[1],\n secondaryUv2: triangleSecondaryUvs[2],\n materialIndex,\n area,\n samplingLuminance,\n selectionPmf: 0\n });\n }\n }\n }\n return triangles;\n}\n\nfunction packEmissivePoint(data: Float32Array, offset: number, point: Float32Array) {\n // Preserve TypedArray.set's overlapping-view semantics for callers with aliases.\n if (data.buffer === point.buffer) {data.set(point, offset); return;}\n data[offset] = point[0]; data[offset + 1] = point[1]; data[offset + 2] = point[2];\n}\nexport function packEmissiveTriangles(triangles: EmissiveTriangle[], data: Float32Array = new Float32Array(Math.max(triangles.length, 1) * 24)) {\n triangles.forEach((triangle, index) => {\n const offset = index * 24;\n packEmissivePoint(data, offset, triangle.p0);\n data[offset + 3] = triangle.selectionPmf;\n packEmissivePoint(data, offset + 4, triangle.p1);\n data[offset + 7] = triangle.area;\n packEmissivePoint(data, offset + 8, triangle.p2);\n data[offset + 11] = triangle.materialIndex;\n data[offset + 12] = triangle.uv0[0]; data[offset + 13] = triangle.uv0[1];\n data[offset + 14] = triangle.uv1[0]; data[offset + 15] = triangle.uv1[1];\n data[offset + 16] = triangle.uv2[0]; data[offset + 17] = triangle.uv2[1];\n data[offset + 18] = triangle.secondaryUv0[0]; data[offset + 19] = triangle.secondaryUv0[1];\n data[offset + 20] = triangle.secondaryUv1[0]; data[offset + 21] = triangle.secondaryUv1[1];\n data[offset + 22] = triangle.secondaryUv2[0]; data[offset + 23] = triangle.secondaryUv2[1];\n });\n return data;\n}\n\n\ninterface EmissiveCacheEntry { geometry: Geometry; version: number; instanceVersion: number; instanceCount: number; instanceTransforms?: Float32Array; matrix: Float64Array;\n indices: number[]; activity: boolean[]; triangles: EmissiveTriangle[] }\n\n// WeakMap class fields have no native representation in scriptc 0.3.2.\n// Keep the same per-cache weak ownership in a module-owned registry.\nconst emissiveBindings = new WeakMap<EmissiveTriangleCache, WeakMap<Mesh, EmissiveCacheEntry>>();\n\n/** Caches world-space vertices per mesh, independently of emission strength. */\nexport class EmissiveTriangleCache {\n constructor() { emissiveBindings.set(this, new WeakMap()); }\n private _triangles: EmissiveTriangle[] = [];\n collect(bindings: EmissiveMeshBinding[], materials: OpenPBRMaterial[]) {\n const cachedBindings = emissiveBindings.get(this)!;\n this._triangles.length = 0;\n for (const binding of bindings) {\n const { mesh, geometry, materialIndices } = binding;\n const isActive = (index: number) => {\n const m = materials[index];\n return !!m && !m.unlit && !m.shadowCatcher && colorLuminance(materialEmission(m)) > 1e-8;\n };\n const instanceVersion = mesh.instanceData?.transformsVersion ?? 0;\n const instanceCount = meshInstanceCount(mesh);\n const instanceTransforms = mesh.instanceData?.transforms;\n let cached = cachedBindings.get(mesh);\n if (!cached || cached.geometry !== geometry || cached.version !== geometry.version || cached.instanceVersion !== instanceVersion || cached.instanceCount !== instanceCount || cached.instanceTransforms !== instanceTransforms ||\n cached.indices.length !== materialIndices.length || materialIndices.some((index, i) =>\n cached!.indices[i] !== index || cached!.activity[i] !== isActive(index)) ||\n meshMatrixChanged(mesh, cached.matrix)) {\n cached = { geometry, version: geometry.version, instanceVersion, instanceCount, instanceTransforms, matrix: copyMeshMatrix(mesh),\n indices: materialIndices.slice(), activity: materialIndices.map(isActive),\n triangles: collectEmissiveTriangles([binding], materials) };\n cachedBindings.set(mesh, cached);\n } else {\n for (const triangle of cached.triangles) {\n const m = materials[triangle.materialIndex];\n triangle.samplingLuminance = colorLuminance(materialEmission(m));\n }\n }\n for (const triangle of cached.triangles) this._triangles.push(triangle);\n }\n return this._triangles;\n }\n}\n\nfunction copyMeshMatrix(mesh: Mesh): Float64Array { return matrixStorage(mesh.transform); }\nfunction meshMatrixChanged(mesh: Mesh, previous: Float64Array): boolean {\n const matrix = matrixStorage(mesh.transform);\n for (let i = 0; i < matrix.length; i++) if (!Object.is(matrix[i], previous[i])) return true;\n return false;\n}\n\nfunction environmentPower(data: NonNullable<TexturePixelSource['data']>, width: number, height: number): number {\n if (data instanceof Uint8Array) return environmentPowerKernel(data, width, height, 1 / 255);\n if (data instanceof Uint8ClampedArray) return environmentPowerKernel(data, width, height, 1 / 255);\n if (data instanceof Float32Array) return environmentPowerKernel(data, width, height, 1);\n return environmentPowerKernel(data, width, height, 1);\n}\n\nfunction environmentPowerKernel<T extends NonNullable<TexturePixelSource['data']>>(data: T, width: number, height: number, scale: number): number {\n const channels = Math.max(Math.floor(pixelLength(data) / (width * height)), 1);\n let weightedLuminance = 0;\n for (let y = 0; y < height; y++) {\n const sinTheta = Math.sin(Math.PI * (y + 0.5) / height);\n for (let x = 0; x < width; x++) {\n const offset = (y * width + x) * channels;\n weightedLuminance +=\n colorLuminance([\n pixelValue(data, offset) * scale,\n pixelValue(data, offset + Math.min(1, channels - 1)) * scale,\n pixelValue(data, offset + Math.min(2, channels - 1)) * scale\n ]) * sinTheta;\n }\n }\n return weightedLuminance * (2 * Math.PI * Math.PI) / (width * height);\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SceneLightState as SceneLight, AnalyticLightState as AnalyticLight } from '../scene/lightState.js';
|
|
2
|
+
import DirectionalLight from '../scene/DirectionalLight.js';
|
|
3
|
+
import SphereLight from '../scene/SphereLight.js';
|
|
4
|
+
import type RectLight from '../scene/RectLightState.js';
|
|
5
|
+
import SpotLight from '../scene/SpotLight.js';
|
|
6
|
+
export { CONSTANT_DIRECTIONAL_LIGHT, CONSTANT_SPHERE_LIGHT, CONSTANT_RECT_LIGHT, CONSTANT_SPOT_LIGHT } from './lightConstants.js';
|
|
7
|
+
export declare function packLightsData(lights: (DirectionalLight | RectLight | SphereLight | SpotLight)[], texturesIndices: number[], selectionPmf: (index: number) => number | undefined, selectionCdf: (index: number) => number | undefined, iesProfileTexelOffset: (index: number) => number | undefined): Float32Array<ArrayBuffer>;
|
|
8
|
+
export declare function getRigidLightFrame(light: AnalyticLight): {
|
|
9
|
+
x: number[];
|
|
10
|
+
y: number[];
|
|
11
|
+
direction: number[];
|
|
12
|
+
};
|
|
13
|
+
export declare function getLightDirection(light: AnalyticLight): number[];
|
|
14
|
+
export declare function getRectLightUOrV(light: RectLight, uOrV: 0 | 1): number[];
|
|
15
|
+
export declare function getRectLightArea(light: RectLight): number;
|
|
16
|
+
export declare function getSphereLightArea(light: SphereLight): number;
|
|
17
|
+
export declare function getSpotLightArea(light: SpotLight): number;
|
|
18
|
+
export declare function getSpotLightRadiance(light: SpotLight): number;
|
|
19
|
+
export declare function getSpotLightShapingFluxFactor(light: SpotLight): number;
|
|
20
|
+
/** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */
|
|
21
|
+
export declare function validateSceneLights(lights: readonly SceneLight[], onError?: (error: Error) => void): void;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { matrixStorage } from '../math/storage.js';
|
|
2
|
+
import { read, write } from '../math/access.js';
|
|
3
|
+
export { CONSTANT_DIRECTIONAL_LIGHT, CONSTANT_SPHERE_LIGHT, CONSTANT_RECT_LIGHT, CONSTANT_SPOT_LIGHT } from './lightConstants.js';
|
|
4
|
+
import { CONSTANT_DIRECTIONAL_LIGHT, CONSTANT_SPHERE_LIGHT, CONSTANT_RECT_LIGHT, CONSTANT_SPOT_LIGHT } from './lightConstants.js';
|
|
5
|
+
export function packLightsData(lights, texturesIndices, selectionPmf, selectionCdf, iesProfileTexelOffset) {
|
|
6
|
+
validateSceneLights(lights);
|
|
7
|
+
const numLights = lights.length;
|
|
8
|
+
const PIXELS_PER_LIGHT = 6;
|
|
9
|
+
const data = new Float32Array(numLights * PIXELS_PER_LIGHT * 4);
|
|
10
|
+
function packVec3(idx, v) {
|
|
11
|
+
for (let i = 0; i < 3; i++) {
|
|
12
|
+
data[i + idx * 4] = read(v, i);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
for (let i = 0; i < numLights; i++) {
|
|
16
|
+
const light = lights[i];
|
|
17
|
+
const color = light.color;
|
|
18
|
+
const intensity = light.intensity;
|
|
19
|
+
const off = i * PIXELS_PER_LIGHT;
|
|
20
|
+
packVec3(off, [read(light.transform, 12), read(light.transform, 13), read(light.transform, 14)]);
|
|
21
|
+
data[off * 4 + 3] = selectionPmf(i) ?? 1 / Math.max(numLights, 1);
|
|
22
|
+
// emission
|
|
23
|
+
const emissionScale = light.type === 'SpotLight' ? getSpotLightRadiance(light) : intensity;
|
|
24
|
+
packVec3(off + 1, [
|
|
25
|
+
color[0] * emissionScale,
|
|
26
|
+
color[1] * emissionScale,
|
|
27
|
+
color[2] * emissionScale
|
|
28
|
+
]);
|
|
29
|
+
data[(off + 1) * 4 + 3] = selectionCdf(i) ?? (i + 1) / numLights;
|
|
30
|
+
if (light.type === 'RectLight') {
|
|
31
|
+
packVec3(off + 2, getRectLightUOrV(light, 0));
|
|
32
|
+
data[(off + 2) * 4 + 3] = light.spread;
|
|
33
|
+
packVec3(off + 3, getRectLightUOrV(light, 1));
|
|
34
|
+
data[(off + 3) * 4 + 3] = texturesIndices[i] ?? -1;
|
|
35
|
+
packVec3(off + 4, [
|
|
36
|
+
light.spread,
|
|
37
|
+
getRectLightArea(light),
|
|
38
|
+
CONSTANT_RECT_LIGHT
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
else if (light.type === 'SphereLight') {
|
|
42
|
+
packVec3(off + 4, [
|
|
43
|
+
light.radius,
|
|
44
|
+
getSphereLightArea(light),
|
|
45
|
+
CONSTANT_SPHERE_LIGHT
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
else if (light.type === 'SpotLight') {
|
|
49
|
+
packVec3(off + 2, getLightDirection(light));
|
|
50
|
+
packVec3(off + 3, [
|
|
51
|
+
Math.cos((light.outerAngle * Math.PI) / 180),
|
|
52
|
+
Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180),
|
|
53
|
+
0
|
|
54
|
+
]);
|
|
55
|
+
data[(off + 3) * 4 + 3] = iesProfileTexelOffset(i) ?? -1;
|
|
56
|
+
packVec3(off + 4, [
|
|
57
|
+
light.radius,
|
|
58
|
+
getSpotLightArea(light),
|
|
59
|
+
CONSTANT_SPOT_LIGHT
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
else if (light.type === 'DirectionalLight') {
|
|
63
|
+
packVec3(off + 2, getLightDirection(light));
|
|
64
|
+
packVec3(off + 4, [0, 0, CONSTANT_DIRECTIONAL_LIGHT]);
|
|
65
|
+
}
|
|
66
|
+
packVec3(off + 5, getRigidLightFrame(light).x);
|
|
67
|
+
}
|
|
68
|
+
return data;
|
|
69
|
+
}
|
|
70
|
+
export function getRigidLightFrame(light) {
|
|
71
|
+
const m = matrixStorage(light.transform);
|
|
72
|
+
const normalize = (v, fallback) => {
|
|
73
|
+
const length = Math.hypot(read(v, 0), read(v, 1), read(v, 2));
|
|
74
|
+
return length > 1e-12 ? [read(v, 0) / length, read(v, 1) / length, read(v, 2) / length] : fallback;
|
|
75
|
+
};
|
|
76
|
+
const z = normalize([read(m, 8), read(m, 9), read(m, 10)], [0, 0, 1]);
|
|
77
|
+
const projection = read(m, 0) * read(z, 0) + read(m, 1) * read(z, 1) + read(m, 2) * read(z, 2);
|
|
78
|
+
let x = [read(m, 0) - projection * read(z, 0), read(m, 1) - projection * read(z, 1), read(m, 2) - projection * read(z, 2)];
|
|
79
|
+
if (Math.hypot(...x) <= 1e-12)
|
|
80
|
+
x = Math.abs(read(z, 1)) < .99 ? [read(z, 2), 0, -read(z, 0)] : [1, 0, 0];
|
|
81
|
+
x = normalize(x, [1, 0, 0]);
|
|
82
|
+
const y = [read(z, 1) * read(x, 2) - read(z, 2) * read(x, 1), read(z, 2) * read(x, 0) - read(z, 0) * read(x, 2), read(z, 0) * read(x, 1) - read(z, 1) * read(x, 0)];
|
|
83
|
+
return { x, y, direction: [-read(z, 0) || 0, -read(z, 1) || 0, -read(z, 2) || 0] };
|
|
84
|
+
}
|
|
85
|
+
export function getLightDirection(light) { return getRigidLightFrame(light).direction; }
|
|
86
|
+
export function getRectLightUOrV(light, uOrV) {
|
|
87
|
+
const frame = getRigidLightFrame(light), axis = uOrV ? frame.y : frame.x;
|
|
88
|
+
const dimensions = matrixStorage(light.size);
|
|
89
|
+
const size = dimensions[uOrV] * (uOrV ? -1 : 1);
|
|
90
|
+
return [read(axis, 0) * size, read(axis, 1) * size, read(axis, 2) * size];
|
|
91
|
+
}
|
|
92
|
+
export function getRectLightArea(light) {
|
|
93
|
+
const size = matrixStorage(light.size);
|
|
94
|
+
return size[0] * size[1];
|
|
95
|
+
}
|
|
96
|
+
export function getSphereLightArea(light) {
|
|
97
|
+
return 4 * Math.PI * light.radius ** 2;
|
|
98
|
+
}
|
|
99
|
+
export function getSpotLightArea(light) {
|
|
100
|
+
return 4 * Math.PI * light.radius ** 2;
|
|
101
|
+
}
|
|
102
|
+
export function getSpotLightRadiance(light) {
|
|
103
|
+
// A zero-radius spot is a point emitter. Its stored emission is luminous
|
|
104
|
+
// intensity (cd), and the shader applies inverse-square attenuation.
|
|
105
|
+
if (light.radius === 0)
|
|
106
|
+
return light.intensity;
|
|
107
|
+
return light.intensity / (Math.PI * light.radius ** 2);
|
|
108
|
+
}
|
|
109
|
+
export function getSpotLightShapingFluxFactor(light) {
|
|
110
|
+
const cosOuter = Math.cos((light.outerAngle * Math.PI) / 180);
|
|
111
|
+
const cosInner = Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180);
|
|
112
|
+
return 0.5 * (1 - 0.5 * (cosInner + cosOuter));
|
|
113
|
+
}
|
|
114
|
+
const warnedLights = new WeakSet();
|
|
115
|
+
/** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */
|
|
116
|
+
export function validateSceneLights(lights, onError) {
|
|
117
|
+
for (const light of lights) {
|
|
118
|
+
if (light.type === 'EnvironmentLight')
|
|
119
|
+
continue;
|
|
120
|
+
let invalid = false;
|
|
121
|
+
const clamp = (value, min, max, fallback) => {
|
|
122
|
+
const normalized = Math.min(max, Math.max(min, Number.isFinite(value) ? value : fallback));
|
|
123
|
+
invalid ||= !Object.is(normalized, value);
|
|
124
|
+
return normalized;
|
|
125
|
+
};
|
|
126
|
+
switch (light.type) {
|
|
127
|
+
case 'AmbientLight':
|
|
128
|
+
sanitizeIntensity(light, clamp);
|
|
129
|
+
break;
|
|
130
|
+
case 'DirectionalLight':
|
|
131
|
+
sanitizeIntensity(light, clamp);
|
|
132
|
+
break;
|
|
133
|
+
case 'RectLight':
|
|
134
|
+
sanitizeIntensity(light, clamp);
|
|
135
|
+
break;
|
|
136
|
+
case 'SphereLight':
|
|
137
|
+
sanitizeIntensity(light, clamp);
|
|
138
|
+
break;
|
|
139
|
+
case 'SpotLight':
|
|
140
|
+
sanitizeIntensity(light, clamp);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
if (light.type !== 'AmbientLight') {
|
|
144
|
+
const matrix = light.transform;
|
|
145
|
+
invalid = (matrix instanceof Float32Array ? sanitizeMatrix(matrix) : sanitizeMatrix(matrix)) || invalid;
|
|
146
|
+
}
|
|
147
|
+
if (light.type === 'RectLight') {
|
|
148
|
+
// A tuple widened to number[] is copied by this native compiler. Mutate
|
|
149
|
+
// each concrete storage directly so invalid edits still sanitize in place.
|
|
150
|
+
const size = light.size;
|
|
151
|
+
if (size instanceof Float32Array) {
|
|
152
|
+
size[0] = clamp(size[0], 0, Number.MAX_VALUE, 1);
|
|
153
|
+
size[1] = clamp(size[1], 0, Number.MAX_VALUE, 1);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
size[0] = clamp(size[0], 0, Number.MAX_VALUE, 1);
|
|
157
|
+
size[1] = clamp(size[1], 0, Number.MAX_VALUE, 1);
|
|
158
|
+
}
|
|
159
|
+
light.spread = clamp(light.spread, 0, 1, 1);
|
|
160
|
+
}
|
|
161
|
+
if (light.type === 'SphereLight')
|
|
162
|
+
light.radius = clamp(light.radius, 0, Number.MAX_VALUE, 1);
|
|
163
|
+
if (light.type === 'SpotLight')
|
|
164
|
+
light.radius = clamp(light.radius, 0, Number.MAX_VALUE, .01);
|
|
165
|
+
if (light.type === 'SpotLight') {
|
|
166
|
+
light.outerAngle = clamp(light.outerAngle, Number.EPSILON, 180, 45);
|
|
167
|
+
light.innerAngle = clamp(light.innerAngle, 0, light.outerAngle, 30);
|
|
168
|
+
}
|
|
169
|
+
if (invalid && !warnedLights.has(light)) {
|
|
170
|
+
warnedLights.add(light);
|
|
171
|
+
const error = new Error(`Invalid ${light.type} values were clamped.`);
|
|
172
|
+
console.warn(error.message);
|
|
173
|
+
onError?.(error);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function sanitizeIntensity(light, clamp) {
|
|
178
|
+
light.intensity = clamp(light.intensity, 0, Number.MAX_VALUE, 1);
|
|
179
|
+
light.color[0] = clamp(light.color[0], 0, Number.MAX_VALUE, 1);
|
|
180
|
+
light.color[1] = clamp(light.color[1], 0, Number.MAX_VALUE, 1);
|
|
181
|
+
light.color[2] = clamp(light.color[2], 0, Number.MAX_VALUE, 1);
|
|
182
|
+
}
|
|
183
|
+
function sanitizeMatrix(matrix) {
|
|
184
|
+
let invalid = false;
|
|
185
|
+
for (let i = 0; i < 16; i++)
|
|
186
|
+
if (!Number.isFinite(read(matrix, i))) {
|
|
187
|
+
write(matrix, i, i % 5 === 0 ? 1 : 0);
|
|
188
|
+
invalid = true;
|
|
189
|
+
}
|
|
190
|
+
return invalid;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=lightsData.js.map
|