@meimu/mutracer 0.1.5 → 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 +10407 -8353
- package/docs/api.md +200 -10
- package/docs/denoising.md +30 -15
- package/docs/materials.md +1 -1
- package/docs/performance.md +5 -2
- package/docs/progressive-rendering.md +32 -1
- package/docs/threejs.md +14 -5
- package/docs/updates.md +44 -2
- package/docs/viewer.md +11 -6
- 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 -550
- 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 +82 -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 +429 -429
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +144 -144
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +801 -801
- 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 +49 -49
- 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 +102 -102
- 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 +742 -705
- 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 +84 -82
- 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 +6 -168
- 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,7 +1,20 @@
|
|
|
1
|
+
import { AovPrimitiveCache } from './AovPrimitiveCache.js';
|
|
2
|
+
import { packAovScene } from './aovScene.js';
|
|
3
|
+
import { aovMask } from './aov.js';
|
|
4
|
+
import { proceduralEnvironmentPower } from './proceduralEnvironmentPower.js';
|
|
5
|
+
import { WGPUSkyBaker } from './WGPUSkyBaker.js';
|
|
6
|
+
import { initialSceneConstants, sceneAttributeLayout, sceneTraversalConstants, prepareSceneLightSampling, writeTraceLighting, packSceneAnalyticLights, writeTraceQuality, traceSampling, writeTraceSampling } from './sceneAssembly.js';
|
|
7
|
+
import { rayTraceBindGroupLayouts } from './sceneLayoutSchema.js';
|
|
8
|
+
import { WGPUBindlessMaterialData } from './WGPUBindlessMaterialData.js';
|
|
9
|
+
import { WGPUBindlessTextures } from './WGPUBindlessTextures.js';
|
|
10
|
+
import { bindlessBindGroupLayouts, bindlessShaderSource } from './wgpuBindlessSource.js';
|
|
11
|
+
import { bindlessLimitReason, resourceTableLayout, setResourceTable } from './wgpuBindless.js';
|
|
12
|
+
import { wgpuMaterialConstants } from './wgpuMaterialConstants.js';
|
|
13
|
+
import { wgpuShaderSource, wgpuPipelineConstantKeys, WGPU_SHADER_DEFINE_KEYS } from './wgpuShaderSource.js';
|
|
14
|
+
import { makeRayTraceUniform, WGPU_SCENE_BUFFER_MIN_BYTES } from './wgpuSceneUniform.js';
|
|
1
15
|
import { constants } from './webgl.js';
|
|
2
|
-
import { MATERIAL_FLOAT_COUNT } from './
|
|
16
|
+
import { MATERIAL_FLOAT_COUNT } from './materialLayoutSchema.js';
|
|
3
17
|
import { normalizeBounces } from './pathLimits.js';
|
|
4
|
-
import { MATERIAL_TEXTURE_DEFINES, materialTextureFeatures } from './materialTextureSlots.js';
|
|
5
18
|
import { updateMeshInstanceColors } from './prepareMeshBVH.js';
|
|
6
19
|
import { updateTLASInstanceColors } from './bvhAccel.js';
|
|
7
20
|
import { getMaterialHashKey } from '../scene/openPbrSchema.js';
|
|
@@ -9,31 +22,31 @@ import { sameInstanceMembership } from './meshInstances.js';
|
|
|
9
22
|
import InstancedMesh from '../scene/InstancedMesh.js';
|
|
10
23
|
import { dirtyMeshInstanceIndices } from './prepareMeshBVH.js';
|
|
11
24
|
import { cameraApertureRadius } from './cameraLens.js';
|
|
12
|
-
import { getRectLightUOrV, getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getLightDirection, getRigidLightFrame, validateSceneLights } from './lightsUtil.js';
|
|
13
25
|
import { getGeometryBvh, setGeometryBvh } from './geometryBvh.js';
|
|
26
|
+
import { packCameraUniform } from './cameraUniform.js';
|
|
14
27
|
import { SHADOW_CATCHER_ACCUMULATION_BYTES } from './wgsl/chunks/shadowCatcherAccumulation.wgsl.js';
|
|
15
|
-
import { samplingPatternCode, zSobolLog2SPP } from './sampling.js';
|
|
16
28
|
import { DEPTH_SAMPLE_COUNT, packDepthSampleArea, unpackDepthSamples } from './depthQuery.js';
|
|
17
29
|
import { MeshMembershipCache } from './meshMembership.js';
|
|
18
30
|
import { mergeRefitRanges } from './bvhAccel.js';
|
|
19
31
|
import { updatePreparedGeometries, canUpdateGeometries, geometryTopologyChanged, packVertexAttributes } from './geometryUpdates.js';
|
|
20
32
|
import { SceneEnvironmentCache, RectLightTextureTracker } from './sceneLightChanges.js';
|
|
21
33
|
import { MaterialChangeTracker, materialIsEmissive } from './materialChanges.js';
|
|
34
|
+
import { WGPUEnvMapDistribution } from './WGPUEnvMapDistribution.js';
|
|
22
35
|
import { WGPUShaderCache, retainedShaderCapacity } from './WGPUShaderCache.js';
|
|
23
|
-
import {
|
|
36
|
+
import { WGPUShaderCapabilities } from './WGPUShaderCapabilities.js';
|
|
37
|
+
import { wgpuSceneFeatureFlags } from './WGPUSceneFeatures.js';
|
|
38
|
+
import { lightShaderCapabilities, retainedShaderCapabilities } from './shaderCapabilities.js';
|
|
24
39
|
import { mat4 } from '../math.js';
|
|
25
|
-
import MaterialTable, { DEFAULT_MAX_TEXTURE_ARRAY_BYTES
|
|
40
|
+
import MaterialTable, { DEFAULT_MAX_TEXTURE_ARRAY_BYTES } from './MaterialTable.js';
|
|
26
41
|
import { numberArraysEqual } from './util.js';
|
|
27
|
-
import { generateBackgroundMapFromSceneBackground, environmentRotation, backgroundMapTransform } from './envMapCreation.js';
|
|
28
|
-
import
|
|
29
|
-
import { CONSTANT_DIRECTIONAL_LIGHT, CONSTANT_RECT_LIGHT, CONSTANT_SPHERE_LIGHT, CONSTANT_SPOT_LIGHT } from './lightsUtil.js';
|
|
42
|
+
import { generateBackgroundMapFromSceneBackground, environmentRotation, backgroundMapTransform, backgroundMapRotation } from './envMapCreation.js';
|
|
43
|
+
import { WORKGROUP_SIZE } from './wgsl/rayTrace.compute.js';
|
|
30
44
|
import { envMapDistribution, environmentMapSourcesMatch } from './envMapDistribution.js';
|
|
31
45
|
import { updateMeshInstances, updateMeshInstanceTransforms } from './prepareMeshBVH.js';
|
|
32
46
|
import { buildTLAS, concatBLASBuffers, getTraversalStackSizes, refitBLAS, refitTLAS } from './bvhAccel.js';
|
|
33
47
|
import { isTextureDataSource } from '../scene/Texture.js';
|
|
34
|
-
import { resolveMaterialAlphaMode } from '../scene/OpenPBRMaterial.js';
|
|
35
48
|
import { DEFAULT_BEVEL_SAMPLES, DEFAULT_DIRECT_LIGHT_CANDIDATES, normalizeBevelSamples, normalizeDirectLightCandidates } from './RenderingPipeline.js';
|
|
36
|
-
import {
|
|
49
|
+
import { EmissiveTriangleCache, LightChoiceBuffer, estimateEnvironmentPower, } from './lightSampling.js';
|
|
37
50
|
import { getOpenPbrEnergyLutData, OPENPBR_ENERGY_LUT_HEIGHT, OPENPBR_ENERGY_LUT_WIDTH } from './openPbrEnergyLut.js';
|
|
38
51
|
import { offlineAdaptiveCompute } from './wgsl/offlineAdaptive.compute.js';
|
|
39
52
|
import { normalizeOfflineAdaptiveSamplingOptions } from './OfflineAdaptiveSampling.js';
|
|
@@ -87,118 +100,13 @@ export function isWebGPUPipelineSpecializationFailure(...errors) {
|
|
|
87
100
|
return errors.some((error) => /(?:compute )?library failed creation/i.test(getWebGPUErrorMessage(error)));
|
|
88
101
|
}
|
|
89
102
|
/** CPU-side views over the `RayTraceUniform` WGSL struct. */
|
|
90
|
-
export
|
|
91
|
-
// Created from https://webgpufundamentals.org/webgpu/lessons/resources/wgsl-offset-computer.html
|
|
92
|
-
const RayTraceUniformValues = new ArrayBuffer(256);
|
|
93
|
-
const RayTraceUniformViews = {
|
|
94
|
-
outputSize: new Float32Array(RayTraceUniformValues, 0, 2),
|
|
95
|
-
sampleCount: new Float32Array(RayTraceUniformValues, 8, 1),
|
|
96
|
-
scaleOffset: new Float32Array(RayTraceUniformValues, 16, 4),
|
|
97
|
-
lightsCount: new Int32Array(RayTraceUniformValues, 32, 1),
|
|
98
|
-
transmissiveOutputAlphaMin: new Float32Array(RayTraceUniformValues, 36, 1),
|
|
99
|
-
jitter: new Float32Array(RayTraceUniformValues, 40, 2),
|
|
100
|
-
backgroundColor: new Float32Array(RayTraceUniformValues, 48, 4),
|
|
101
|
-
groundedBackgroundParams: new Float32Array(RayTraceUniformValues, 64, 4),
|
|
102
|
-
groundedBackgroundCenter: new Float32Array(RayTraceUniformValues, 80, 2),
|
|
103
|
-
blasOffset: new Int32Array(RayTraceUniformValues, 88, 1),
|
|
104
|
-
isEmpty: new Int32Array(RayTraceUniformValues, 92, 1),
|
|
105
|
-
bevel: new Int32Array(RayTraceUniformValues, 96, 1),
|
|
106
|
-
dispersionWavelengths: new Int32Array(RayTraceUniformValues, 100, 1),
|
|
107
|
-
envLightPmf: new Float32Array(RayTraceUniformValues, 104, 1),
|
|
108
|
-
lightChoiceCount: new Int32Array(RayTraceUniformValues, 108, 1),
|
|
109
|
-
lightWeightTotal: new Float32Array(RayTraceUniformValues, 112, 1),
|
|
110
|
-
lightSamplingTextureWidth: new Int32Array(RayTraceUniformValues, 116, 1),
|
|
111
|
-
lightChoiceTexelOffset: new Int32Array(RayTraceUniformValues, 120, 1),
|
|
112
|
-
bounces: new Int32Array(RayTraceUniformValues, 124, 1),
|
|
113
|
-
varianceMoments: new Int32Array(RayTraceUniformValues, 128, 1),
|
|
114
|
-
adaptiveSampling: new Int32Array(RayTraceUniformValues, 132, 1),
|
|
115
|
-
clamping: new Float32Array(RayTraceUniformValues, 136, 1),
|
|
116
|
-
directLightCandidates: new Int32Array(RayTraceUniformValues, 140, 1),
|
|
117
|
-
backgroundFlags: new Int32Array(RayTraceUniformValues, 144, 1),
|
|
118
|
-
loopUnrollGuard: new Uint32Array(RayTraceUniformValues, 148, 1),
|
|
119
|
-
sceneFeatureFlags: new Uint32Array(RayTraceUniformValues, 152, 1),
|
|
120
|
-
sequenceSeed: new Uint32Array(RayTraceUniformValues, 156, 1),
|
|
121
|
-
zSobolLogSPP: new Uint32Array(RayTraceUniformValues, 160, 1),
|
|
122
|
-
sampleSequenceOffset: new Uint32Array(RayTraceUniformValues, 164, 1),
|
|
123
|
-
environmentRotation: new Float32Array(RayTraceUniformValues, 176, 16),
|
|
124
|
-
backgroundMapTransform: new Float32Array(RayTraceUniformValues, 240, 4)
|
|
125
|
-
};
|
|
126
|
-
// Fixed runtime trip bounds discourage thin-film loop unrolling. Keep 4 for
|
|
127
|
-
// 2 polarizations/substrates and 3 channels, independent of BSDF budgets.
|
|
128
|
-
RayTraceUniformViews.loopUnrollGuard[0] = 4;
|
|
129
|
-
RayTraceUniformViews.environmentRotation.set(environmentRotation([]));
|
|
130
|
-
RayTraceUniformViews.backgroundMapTransform.set(backgroundMapTransform());
|
|
131
|
-
RayTraceUniformViews.bevel[0] = 1;
|
|
132
|
-
RayTraceUniformViews.dispersionWavelengths[0] = 3;
|
|
133
|
-
return {
|
|
134
|
-
buffer: RayTraceUniformValues,
|
|
135
|
-
views: RayTraceUniformViews
|
|
136
|
-
};
|
|
137
|
-
}
|
|
103
|
+
export { makeRayTraceUniform } from './wgpuSceneUniform.js';
|
|
138
104
|
export function packAnalyticsLightsToBuffer(lights, texturesIndices, selectionPmfs, iesProfileTexelOffsets = []) {
|
|
139
|
-
|
|
140
|
-
const numLights = lights.length;
|
|
141
|
-
if (numLights > FIXED_LIGHT_COUNT) {
|
|
142
|
-
console.warn(`Too many lights, only the first ${FIXED_LIGHT_COUNT} lights will be used.`);
|
|
143
|
-
}
|
|
144
|
-
const data = new Float32Array(numLights * PIXELS_PER_LIGHT * 4);
|
|
145
|
-
function packVec3(idx, v) {
|
|
146
|
-
for (let i = 0; i < 3; i++) {
|
|
147
|
-
data[i + idx * 4] = v[i];
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
const lightTypeConstants = {
|
|
151
|
-
DirectionalLight: CONSTANT_DIRECTIONAL_LIGHT,
|
|
152
|
-
SphereLight: CONSTANT_SPHERE_LIGHT,
|
|
153
|
-
RectLight: CONSTANT_RECT_LIGHT,
|
|
154
|
-
SpotLight: CONSTANT_SPOT_LIGHT
|
|
155
|
-
};
|
|
156
|
-
for (let i = 0; i < numLights; i++) {
|
|
157
|
-
const light = lights[i];
|
|
158
|
-
const color = light.color;
|
|
159
|
-
const intensity = light.intensity;
|
|
160
|
-
const off = i * PIXELS_PER_LIGHT;
|
|
161
|
-
packVec3(off, light.position);
|
|
162
|
-
data[off * 4 + 3] = lightTypeConstants[light.type];
|
|
163
|
-
// emission
|
|
164
|
-
const emissionScale = light.type === 'SpotLight' ? getSpotLightRadiance(light) : intensity;
|
|
165
|
-
packVec3(off + 1, [
|
|
166
|
-
color[0] * emissionScale,
|
|
167
|
-
color[1] * emissionScale,
|
|
168
|
-
color[2] * emissionScale
|
|
169
|
-
]);
|
|
170
|
-
if (light.type === 'RectLight') {
|
|
171
|
-
data[(off + 1) * 4 + 3] = getRectLightArea(light);
|
|
172
|
-
packVec3(off + 2, getRectLightUOrV(light, 0));
|
|
173
|
-
data[(off + 2) * 4 + 3] = light.spread;
|
|
174
|
-
packVec3(off + 3, getRectLightUOrV(light, 1));
|
|
175
|
-
}
|
|
176
|
-
else if (light.type === 'SphereLight') {
|
|
177
|
-
data[(off + 1) * 4 + 3] = getSphereLightArea(light);
|
|
178
|
-
data[(off + 2) * 4 + 3] = light.radius;
|
|
179
|
-
}
|
|
180
|
-
else if (light.type === 'SpotLight') {
|
|
181
|
-
data[(off + 1) * 4 + 3] = getSpotLightArea(light);
|
|
182
|
-
packVec3(off + 2, getLightDirection(light));
|
|
183
|
-
data[(off + 2) * 4 + 3] = light.radius;
|
|
184
|
-
packVec3(off + 3, [
|
|
185
|
-
Math.cos((light.outerAngle * Math.PI) / 180),
|
|
186
|
-
Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180),
|
|
187
|
-
0
|
|
188
|
-
]);
|
|
189
|
-
}
|
|
190
|
-
else if (light.type === 'DirectionalLight') {
|
|
191
|
-
packVec3(off + 2, getLightDirection(light));
|
|
192
|
-
}
|
|
193
|
-
data[(off + 3) * 4 + 3] = light.type === 'SpotLight'
|
|
194
|
-
? iesProfileTexelOffsets[i] ?? -1
|
|
195
|
-
: texturesIndices[i] ?? -1;
|
|
196
|
-
data[(off + 4) * 4] = selectionPmfs[i] ?? 0;
|
|
197
|
-
packVec3(off + 5, getRigidLightFrame(light).x);
|
|
198
|
-
}
|
|
199
|
-
return data;
|
|
105
|
+
return packSceneAnalyticLights(lights, texturesIndices, selectionPmfs, i => iesProfileTexelOffsets[i]);
|
|
200
106
|
}
|
|
201
107
|
class WGPURayTracePass {
|
|
108
|
+
_textureSelection;
|
|
109
|
+
_aovPrimitiveCache = new AovPrimitiveCache();
|
|
202
110
|
_device;
|
|
203
111
|
_rayTracePipeline;
|
|
204
112
|
_targetAspect = 1;
|
|
@@ -212,6 +120,9 @@ class WGPURayTracePass {
|
|
|
212
120
|
_materialChanges = new MaterialChangeTracker();
|
|
213
121
|
_pendingMaterialUpdate;
|
|
214
122
|
_materialData;
|
|
123
|
+
_bindless;
|
|
124
|
+
_retiredBindless = new Set();
|
|
125
|
+
_disposed = false;
|
|
215
126
|
_maxTextureArrayBytes = DEFAULT_MAX_TEXTURE_ARRAY_BYTES;
|
|
216
127
|
_pendingGeometryUpdates = new Set();
|
|
217
128
|
_needsUpdateMeshData = true;
|
|
@@ -251,7 +162,7 @@ class WGPURayTracePass {
|
|
|
251
162
|
const output = this._targetOutputs.get(target);
|
|
252
163
|
[this._outColorBuffer, this._outNormalBuffer, this._outAlbedoBuffer, this._outShadowCatcherBuffer] = output?.buffers ?? [];
|
|
253
164
|
if (output?.bindGroup && output.pipeline === this._rayTracePipeline && this._rayTraceBindGroups) {
|
|
254
|
-
this._rayTraceBindGroups[3] = output.bindGroup;
|
|
165
|
+
this._rayTraceBindGroups[this._bindless ? 2 : 3] = output.bindGroup;
|
|
255
166
|
}
|
|
256
167
|
else {
|
|
257
168
|
this._needsUpdateBindGroups = true;
|
|
@@ -281,6 +192,7 @@ class WGPURayTracePass {
|
|
|
281
192
|
_instancesBuffer;
|
|
282
193
|
_emissiveCache = new EmissiveTriangleCache();
|
|
283
194
|
_lightChoices = new LightChoiceBuffer();
|
|
195
|
+
_shadowCatcherLightChoices = new LightChoiceBuffer();
|
|
284
196
|
_lightSamplingData;
|
|
285
197
|
_lightSamplingScratch;
|
|
286
198
|
_lightSamplingTriangleCount = -1;
|
|
@@ -296,6 +208,8 @@ class WGPURayTracePass {
|
|
|
296
208
|
_envImageSource;
|
|
297
209
|
_envTex;
|
|
298
210
|
_envDistributionTex;
|
|
211
|
+
_envDistribution;
|
|
212
|
+
_skyBaker;
|
|
299
213
|
_backgroundImageSource;
|
|
300
214
|
_backgroundTex;
|
|
301
215
|
_rayTracePipelineLayout;
|
|
@@ -307,15 +221,13 @@ class WGPURayTracePass {
|
|
|
307
221
|
_compiledHasAlpha = true;
|
|
308
222
|
_compiledSceneHasAlpha = true;
|
|
309
223
|
_alphaBlendStrategy = 'stochastic';
|
|
310
|
-
_constants =
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
SAMPLING_PATTERN: 0,
|
|
315
|
-
BEVEL_SAMPLES: DEFAULT_BEVEL_SAMPLES
|
|
316
|
-
};
|
|
224
|
+
_constants = initialSceneConstants();
|
|
225
|
+
_retainedShaderCapabilities;
|
|
226
|
+
_retainedShaderStructure;
|
|
227
|
+
_shaderCapabilities = new WGPUShaderCapabilities();
|
|
317
228
|
_prevPipelineConstants = {};
|
|
318
229
|
_prevDefinesCode = '';
|
|
230
|
+
_prevPipelineInputs;
|
|
319
231
|
_hasTransmission = false;
|
|
320
232
|
_hasShadowCatcher = false;
|
|
321
233
|
_hasDisplacement = false;
|
|
@@ -331,6 +243,7 @@ class WGPURayTracePass {
|
|
|
331
243
|
_focusDistance = 10;
|
|
332
244
|
_needsUpdateBindGroups = true;
|
|
333
245
|
_computeShaderModule;
|
|
246
|
+
_aovPipelines = new WeakMap();
|
|
334
247
|
_depthCompute;
|
|
335
248
|
_depthTracePipeline;
|
|
336
249
|
_depthPipeline;
|
|
@@ -342,9 +255,12 @@ class WGPURayTracePass {
|
|
|
342
255
|
// Fold scene invariants before backend inlining; runtime edits use uniforms.
|
|
343
256
|
_bakePipelineConstants = true;
|
|
344
257
|
_failedPipelineSignature;
|
|
345
|
-
constructor(device) {
|
|
258
|
+
constructor(device, _textureSelection = { requested: 'atlas' }) {
|
|
259
|
+
this._textureSelection = _textureSelection;
|
|
346
260
|
this._device = device;
|
|
347
261
|
this._shaderCache = new WGPUShaderCache(device);
|
|
262
|
+
if (_textureSelection.support)
|
|
263
|
+
this._bindless = new WGPUBindlessTextures(device);
|
|
348
264
|
this._uniforms = {
|
|
349
265
|
cameraUniform: this._uniformBuffer(36 * 4),
|
|
350
266
|
rtUniform: this._uniformBuffer(this._rtUniform.buffer.byteLength),
|
|
@@ -579,129 +495,13 @@ class WGPURayTracePass {
|
|
|
579
495
|
}
|
|
580
496
|
}
|
|
581
497
|
_createPipelineLayout() {
|
|
582
|
-
|
|
583
|
-
const commonBufferLayoutEntries = Array.from({ length: 4 }, (_, i) => ({
|
|
584
|
-
binding: i,
|
|
585
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
586
|
-
buffer: {
|
|
587
|
-
type: 'read-only-storage'
|
|
588
|
-
}
|
|
589
|
-
}));
|
|
590
|
-
const buffersBindGroupLayout = this._shaderCache.createBindGroupLayout({
|
|
591
|
-
label: 'Buffers',
|
|
592
|
-
entries: commonBufferLayoutEntries
|
|
593
|
-
});
|
|
594
|
-
const textureLayoutEntries = [
|
|
595
|
-
{
|
|
596
|
-
binding: 0,
|
|
597
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
598
|
-
sampler: {}
|
|
599
|
-
},
|
|
600
|
-
{
|
|
601
|
-
binding: 1,
|
|
602
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
603
|
-
texture: {
|
|
604
|
-
viewDimension: '2d-array'
|
|
605
|
-
}
|
|
606
|
-
},
|
|
607
|
-
// Map size
|
|
608
|
-
{
|
|
609
|
-
binding: 3,
|
|
610
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
611
|
-
buffer: {
|
|
612
|
-
type: 'uniform'
|
|
613
|
-
}
|
|
614
|
-
},
|
|
615
|
-
// Env map
|
|
616
|
-
{
|
|
617
|
-
binding: 4,
|
|
618
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
619
|
-
texture: {
|
|
620
|
-
viewDimension: '2d',
|
|
621
|
-
sampleType: 'unfilterable-float'
|
|
622
|
-
}
|
|
623
|
-
},
|
|
624
|
-
// Env map distribution
|
|
625
|
-
{
|
|
626
|
-
binding: 5,
|
|
627
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
628
|
-
texture: {
|
|
629
|
-
viewDimension: '2d',
|
|
630
|
-
sampleType: 'unfilterable-float'
|
|
631
|
-
}
|
|
632
|
-
},
|
|
633
|
-
// Background map
|
|
634
|
-
{
|
|
635
|
-
binding: 6,
|
|
636
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
637
|
-
texture: {
|
|
638
|
-
viewDimension: '2d',
|
|
639
|
-
sampleType: 'unfilterable-float'
|
|
640
|
-
}
|
|
641
|
-
},
|
|
642
|
-
{
|
|
643
|
-
binding: 8,
|
|
644
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
645
|
-
texture: {
|
|
646
|
-
viewDimension: '2d',
|
|
647
|
-
sampleType: 'unfilterable-float'
|
|
648
|
-
}
|
|
649
|
-
},
|
|
650
|
-
{
|
|
651
|
-
binding: 9,
|
|
652
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
653
|
-
texture: {
|
|
654
|
-
viewDimension: '2d',
|
|
655
|
-
sampleType: 'unfilterable-float'
|
|
656
|
-
}
|
|
657
|
-
},
|
|
658
|
-
{
|
|
659
|
-
binding: 10,
|
|
660
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
661
|
-
texture: {
|
|
662
|
-
viewDimension: '2d',
|
|
663
|
-
sampleType: 'unfilterable-float'
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
];
|
|
667
|
-
const texturesBindGroupLayout = this._shaderCache.createBindGroupLayout({
|
|
668
|
-
label: 'Textures', entries: textureLayoutEntries
|
|
669
|
-
});
|
|
670
|
-
const uniformsBindGroupLayout = this._shaderCache.createBindGroupLayout({
|
|
671
|
-
label: 'Uniforms',
|
|
672
|
-
entries: [
|
|
673
|
-
...Array.from({ length: Object.keys(this._uniforms).length }, (_, i) => ({
|
|
674
|
-
binding: i,
|
|
675
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
676
|
-
buffer: {
|
|
677
|
-
type: 'uniform'
|
|
678
|
-
}
|
|
679
|
-
})),
|
|
680
|
-
...([])
|
|
681
|
-
]
|
|
682
|
-
});
|
|
683
|
-
const rayTraceOutBuffersBindGroupLayout = this._shaderCache.createBindGroupLayout({
|
|
684
|
-
label: 'Ray Trace Out Buffers',
|
|
685
|
-
entries: [
|
|
686
|
-
...Array.from({ length: 4 }, (_, i) => ({
|
|
687
|
-
binding: i,
|
|
688
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
689
|
-
buffer: { type: 'storage' }
|
|
690
|
-
})),
|
|
691
|
-
...([])
|
|
692
|
-
]
|
|
693
|
-
});
|
|
694
|
-
this._rayTracePipelineLayout = this._shaderCache.createPipelineLayout({
|
|
498
|
+
const descriptor = {
|
|
695
499
|
label: 'Ray Trace Pipeline Layout',
|
|
696
|
-
bindGroupLayouts:
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
uniformsBindGroupLayout,
|
|
700
|
-
rayTraceOutBuffersBindGroupLayout
|
|
701
|
-
]
|
|
702
|
-
});
|
|
500
|
+
bindGroupLayouts: (this._bindless ? bindlessBindGroupLayouts() : rayTraceBindGroupLayouts()).map(layout => this._shaderCache.createBindGroupLayout(layout))
|
|
501
|
+
};
|
|
502
|
+
this._rayTracePipelineLayout = this._shaderCache.createPipelineLayout(this._bindless ? resourceTableLayout(descriptor) : descriptor);
|
|
703
503
|
}
|
|
704
|
-
_updateGPUBuffer(label, gpuBuffer, data, minSize =
|
|
504
|
+
_updateGPUBuffer(label, gpuBuffer, data, minSize = WGPU_SCENE_BUFFER_MIN_BYTES) {
|
|
705
505
|
const device = this._device;
|
|
706
506
|
const size = Math.max(data.byteLength, minSize);
|
|
707
507
|
if (gpuBuffer == null || gpuBuffer.size < size) {
|
|
@@ -739,6 +539,10 @@ class WGPURayTracePass {
|
|
|
739
539
|
let compilationStartedAt;
|
|
740
540
|
let pipelineCompilationStartedAt;
|
|
741
541
|
try {
|
|
542
|
+
if (this._bindless?.retirement)
|
|
543
|
+
await this._bindless.retirement;
|
|
544
|
+
if (this._disposed)
|
|
545
|
+
return;
|
|
742
546
|
if (this._needsUpdateMeshData) {
|
|
743
547
|
this._updateMeshData();
|
|
744
548
|
}
|
|
@@ -757,15 +561,24 @@ class WGPURayTracePass {
|
|
|
757
561
|
this._updateLightSamplingData();
|
|
758
562
|
}
|
|
759
563
|
const device = this._device;
|
|
760
|
-
const
|
|
761
|
-
|
|
564
|
+
const pipelineInputs = JSON.stringify([this._constants, this._hasDisplacement,
|
|
565
|
+
this._alphaBlendStrategy, this._blasLayoutMask, this._bakePipelineConstants]);
|
|
566
|
+
// Steady rendering must not repeat capability selection and cache-key
|
|
567
|
+
// preparation. Dirty resources still take the normal bind-group path.
|
|
568
|
+
if (pipelineInputs === this._prevPipelineInputs && this._rayTracePipeline &&
|
|
569
|
+
this._rayTraceBindGroups && !this._needsUpdateBindGroups)
|
|
570
|
+
return;
|
|
571
|
+
this._rtUniform.views.sceneFeatureFlags[0] = wgpuSceneFeatureFlags(this._constants);
|
|
572
|
+
const requiredCapabilities = retainedShaderCapabilities(this._constants);
|
|
573
|
+
const constants = { ...this._constants, ...requiredCapabilities };
|
|
762
574
|
const hasAlpha = Boolean(constants.HAS_ALPHA_BLEND) &&
|
|
763
575
|
this._alphaBlendStrategy === 'deterministic-source-over';
|
|
764
576
|
const hasSceneAlpha = Boolean(constants.HAS_ALPHA);
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
577
|
+
const pipelineConstantsKeys = wgpuPipelineConstantKeys(constants);
|
|
578
|
+
const defineCode = WGPU_SHADER_DEFINE_KEYS
|
|
579
|
+
.map((key) => `const ${key} = ${constants[key]};`)
|
|
580
|
+
.join('\n');
|
|
581
|
+
const structure = {
|
|
769
582
|
hasDisplacement: this._hasDisplacement,
|
|
770
583
|
hasAlpha,
|
|
771
584
|
hasSceneAlpha,
|
|
@@ -773,45 +586,29 @@ class WGPURayTracePass {
|
|
|
773
586
|
hasCoatNormals: Boolean(constants.USE_COAT_NORMAL_FRAMES),
|
|
774
587
|
blasLayoutMask: this._blasLayoutMask,
|
|
775
588
|
bakePipelineConstants: this._bakePipelineConstants
|
|
589
|
+
};
|
|
590
|
+
const structureKey = JSON.stringify({
|
|
591
|
+
...structure, defineCode,
|
|
592
|
+
constants: pipelineConstantsKeys
|
|
593
|
+
.filter(key => !(key in requiredCapabilities))
|
|
594
|
+
.map(key => [key, constants[key]])
|
|
595
|
+
});
|
|
596
|
+
// Prefer an existing compatible pipeline, including an earlier lean
|
|
597
|
+
// variant. Only grow the current variant when it cannot cover an edit;
|
|
598
|
+
// do not carry unused capabilities across different transport/layouts.
|
|
599
|
+
const capabilities = this._shaderCapabilities.find(structureKey, requiredCapabilities) ??
|
|
600
|
+
retainedShaderCapabilities(this._constants, structureKey === this._retainedShaderStructure ? this._retainedShaderCapabilities : undefined);
|
|
601
|
+
Object.assign(constants, capabilities);
|
|
602
|
+
const pipelineSignature = JSON.stringify({
|
|
603
|
+
...structure,
|
|
604
|
+
constants: Object.keys(constants).sort().map(key => [key, constants[key]])
|
|
776
605
|
});
|
|
777
606
|
attemptedPipelineSignature = pipelineSignature;
|
|
778
607
|
if (pipelineSignature === this._failedPipelineSignature) {
|
|
779
608
|
return;
|
|
780
609
|
}
|
|
781
610
|
this._pipelineError = undefined;
|
|
782
|
-
|
|
783
|
-
const definesKeys = [
|
|
784
|
-
'NUM_MAPS',
|
|
785
|
-
'TLAS_STACK_SIZE',
|
|
786
|
-
'BLAS_STACK_SIZE',
|
|
787
|
-
'NUM_UNIFORM_LIGHTS'
|
|
788
|
-
];
|
|
789
|
-
// Scene feature flags and background selection are runtime uniforms so
|
|
790
|
-
// interactive edits do not recompile the path tracer.
|
|
791
|
-
const constantsNotUsed = [
|
|
792
|
-
...Object.keys(WGPU_SCENE_FEATURE_BITS),
|
|
793
|
-
'USE_BACKGROUND',
|
|
794
|
-
'USE_BACKGROUND_MAP',
|
|
795
|
-
'USE_GROUNDED_BACKGROUND',
|
|
796
|
-
...MATERIAL_TEXTURE_DEFINES,
|
|
797
|
-
'USE_ANISOTROPY_DIRECTIONS',
|
|
798
|
-
'USE_COAT_NORMAL_FRAMES',
|
|
799
|
-
'HAS_ALPHA_BLEND',
|
|
800
|
-
'HAS_ALPHA_MASK'
|
|
801
|
-
];
|
|
802
|
-
const defines = definesKeys.reduce((obj, key) => {
|
|
803
|
-
obj[key] = constants[key];
|
|
804
|
-
return obj;
|
|
805
|
-
}, {});
|
|
806
|
-
const pipelineConstantsKeys = Object.keys(constants)
|
|
807
|
-
.sort()
|
|
808
|
-
.filter((key) => !definesKeys.includes(key) && !constantsNotUsed.includes(key));
|
|
809
|
-
const defineCode = definesKeys
|
|
810
|
-
.map((key) => `const ${key} = ${defines[key]};`)
|
|
811
|
-
.join('\n');
|
|
812
|
-
const previousPipelineConstantsKeys = Object.keys(this._prevPipelineConstants)
|
|
813
|
-
.filter((key) => !definesKeys.includes(key) && !constantsNotUsed.includes(key))
|
|
814
|
-
.sort();
|
|
611
|
+
const previousPipelineConstantsKeys = wgpuPipelineConstantKeys(this._prevPipelineConstants);
|
|
815
612
|
const needsCreateShaderModule = !this._rayTracePipelineLayout ||
|
|
816
613
|
!this._computeShaderModule ||
|
|
817
614
|
pipelineConstantsKeys.join(',') !==
|
|
@@ -836,20 +633,15 @@ class WGPURayTracePass {
|
|
|
836
633
|
let sourceFingerprint = this._shaderCompilationDiagnostics?.modules[0]?.sourceFingerprint ?? '';
|
|
837
634
|
if (needsCreateShaderModule) {
|
|
838
635
|
const sourceGenerationStartedAt = shaderCompilationNow();
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
.join('\n');
|
|
842
|
-
const rayTraceShaderCode = /* wgsl */ `
|
|
843
|
-
${defineCode}
|
|
844
|
-
${constantsCode}
|
|
845
|
-
${rayTraceCompute({
|
|
846
|
-
hasDisplacement: this._hasDisplacement,
|
|
847
|
-
hasAlpha,
|
|
848
|
-
hasSceneAlpha,
|
|
636
|
+
let rayTraceShaderCode = wgpuShaderSource(constants, {
|
|
637
|
+
hasDisplacement: this._hasDisplacement, hasAlpha, hasSceneAlpha,
|
|
849
638
|
hasAnisotropyDirections: Boolean(constants.USE_ANISOTROPY_DIRECTIONS),
|
|
850
639
|
hasCoatNormals: Boolean(constants.USE_COAT_NORMAL_FRAMES),
|
|
851
|
-
blasLayoutMask: this._blasLayoutMask
|
|
852
|
-
|
|
640
|
+
blasLayoutMask: this._blasLayoutMask,
|
|
641
|
+
dynamicEnvironment: true
|
|
642
|
+
}, this._bakePipelineConstants);
|
|
643
|
+
if (this._bindless)
|
|
644
|
+
rayTraceShaderCode = bindlessShaderSource(rayTraceShaderCode, this._textureSelection.support.enable);
|
|
853
645
|
sourceBytes = rayTraceShaderCode.length;
|
|
854
646
|
sourceLines = shaderSourceLineCount(rayTraceShaderCode);
|
|
855
647
|
sourceFingerprint = shaderSourceFingerprint(rayTraceShaderCode);
|
|
@@ -891,7 +683,7 @@ ${rayTraceCompute({
|
|
|
891
683
|
// NOTE must before creating pipeline.
|
|
892
684
|
// Because createComputePipelineAsync is async.
|
|
893
685
|
// The constants may be changed after the pipeline is created(in setMesh).
|
|
894
|
-
this._prevPipelineConstants = { ...
|
|
686
|
+
this._prevPipelineConstants = { ...constants };
|
|
895
687
|
this._prevDefinesCode = defineCode;
|
|
896
688
|
this._needsUpdateBindGroups = true;
|
|
897
689
|
device.pushErrorScope('validation');
|
|
@@ -899,7 +691,7 @@ ${rayTraceCompute({
|
|
|
899
691
|
try {
|
|
900
692
|
const pipelineConstants = !this._bakePipelineConstants
|
|
901
693
|
? pipelineConstantsKeys.reduce((obj, key) => {
|
|
902
|
-
obj[key] = +
|
|
694
|
+
obj[key] = +constants[key];
|
|
903
695
|
return obj;
|
|
904
696
|
}, {})
|
|
905
697
|
: undefined;
|
|
@@ -1020,14 +812,24 @@ ${rayTraceCompute({
|
|
|
1020
812
|
throw new Error(detail);
|
|
1021
813
|
}
|
|
1022
814
|
}
|
|
815
|
+
// Compilation can complete after Engine disposal/device loss has released
|
|
816
|
+
// the material table and its textures. Never bind that retired generation.
|
|
817
|
+
if (this._disposed)
|
|
818
|
+
return;
|
|
1023
819
|
// TODO rebind when lights, materials, bvh changed.
|
|
1024
820
|
if (this._needsUpdateBindGroups) {
|
|
1025
821
|
this._needsUpdateBindGroups = false;
|
|
1026
822
|
this._updateBindGroups();
|
|
1027
823
|
}
|
|
824
|
+
this._retainedShaderCapabilities = capabilities;
|
|
825
|
+
this._retainedShaderStructure = structureKey;
|
|
826
|
+
this._shaderCapabilities.remember(structureKey, capabilities);
|
|
827
|
+
this._prevPipelineInputs = pipelineInputs;
|
|
1028
828
|
this._failedPipelineSignature = undefined;
|
|
1029
829
|
}
|
|
1030
830
|
catch (error) {
|
|
831
|
+
if (this._disposed)
|
|
832
|
+
return;
|
|
1031
833
|
this._pipelineError = error;
|
|
1032
834
|
const failedAt = shaderCompilationNow();
|
|
1033
835
|
if (this._shaderCompilationDiagnostics?.status === 'compiling') {
|
|
@@ -1057,9 +859,106 @@ ${rayTraceCompute({
|
|
|
1057
859
|
this._isCompilingShader = false;
|
|
1058
860
|
}
|
|
1059
861
|
}
|
|
862
|
+
_prepareAovPipelines(kinds) {
|
|
863
|
+
const trace = this._rayTracePipeline;
|
|
864
|
+
if (!trace || !this._depthCompute)
|
|
865
|
+
return;
|
|
866
|
+
const reflectance = (aovMask(kinds) & 24) !== 0;
|
|
867
|
+
let variants = this._aovPipelines.get(trace);
|
|
868
|
+
if (!variants) {
|
|
869
|
+
variants = new Map();
|
|
870
|
+
this._aovPipelines.set(trace, variants);
|
|
871
|
+
}
|
|
872
|
+
let pipelines = variants.get(reflectance);
|
|
873
|
+
if (!pipelines) {
|
|
874
|
+
pipelines = {};
|
|
875
|
+
variants.set(reflectance, pipelines);
|
|
876
|
+
const pending = pipelines;
|
|
877
|
+
const textures = this._bindless, groupIndex = textures ? 2 : 3;
|
|
878
|
+
const output = this._device.createBindGroupLayout({ entries: [
|
|
879
|
+
{ binding: 5, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } },
|
|
880
|
+
{ binding: 6, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } },
|
|
881
|
+
{ binding: 7, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'read-only-storage' } },
|
|
882
|
+
{ binding: 8, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },
|
|
883
|
+
{ binding: 9, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'read-only-storage' } }
|
|
884
|
+
] });
|
|
885
|
+
const descriptor = { bindGroupLayouts: Array.from({ length: groupIndex }, (_, i) => trace.getBindGroupLayout(i)).concat(output) };
|
|
886
|
+
const layout = this._device.createPipelineLayout(textures ? resourceTableLayout(descriptor) : descriptor);
|
|
887
|
+
const compute = { ...this._depthCompute, constants: { ...this._depthCompute.constants, DEPTH_QUERY_MODE: 1, AOV_REFLECTANCE: reflectance ? 1 : 0 } };
|
|
888
|
+
// Keep the UI responsive during first use, and reuse both variants across
|
|
889
|
+
// preview/final target changes rather than recreating synchronous pipelines.
|
|
890
|
+
void Promise.all([
|
|
891
|
+
this._shaderCache.createComputePipelineAsync({ label: 'AOV accumulation', layout, compute: { ...compute, entryPoint: 'aovTrace' } }),
|
|
892
|
+
this._shaderCache.createComputePipelineAsync({ label: 'AOV center', layout, compute: { ...compute, entryPoint: 'aovTraceCenter' } })
|
|
893
|
+
]).then(([accumulation, center]) => { pending.accumulation = accumulation; pending.center = center; }, error => { pending.error = error; });
|
|
894
|
+
}
|
|
895
|
+
if (pipelines.error)
|
|
896
|
+
throw pipelines.error;
|
|
897
|
+
return pipelines;
|
|
898
|
+
}
|
|
899
|
+
prepareAovs(kinds) {
|
|
900
|
+
const pipelines = this._prepareAovPipelines(kinds);
|
|
901
|
+
return !!pipelines?.accumulation && !!pipelines.center;
|
|
902
|
+
}
|
|
903
|
+
renderAovs(state, camera, samples, cap, kinds) {
|
|
904
|
+
const groups = this._rayTraceBindGroups;
|
|
905
|
+
if (!groups || !this._tlas || !this._preparedMeshData || !kinds.length)
|
|
906
|
+
return false;
|
|
907
|
+
const pipelines = this._prepareAovPipelines(kinds);
|
|
908
|
+
if (!pipelines?.accumulation || !pipelines.center)
|
|
909
|
+
return false;
|
|
910
|
+
state.resize(this._width, this._height);
|
|
911
|
+
const textures = this._bindless, groupIndex = textures ? 2 : 3;
|
|
912
|
+
const target = Math.min(samples, cap);
|
|
913
|
+
if (state.centerReady && state.samples >= target)
|
|
914
|
+
return true;
|
|
915
|
+
if (!state.frame) {
|
|
916
|
+
const primitiveIds = this._aovPrimitiveCache.get(this._preparedMeshData, this._tlas);
|
|
917
|
+
const packed = packAovScene(this._preparedMeshData, this._tlas, camera, this._width, this._height, state.history, primitiveIds, false);
|
|
918
|
+
state.frame = packed.frame;
|
|
919
|
+
state.setScene(packed.words, primitiveIds);
|
|
920
|
+
}
|
|
921
|
+
this._device.queue.writeBuffer(this._uniforms.rtUniform, 0, this._rtUniform.buffer);
|
|
922
|
+
this._device.queue.writeBuffer(this._uniforms.cameraUniform, 0, packCameraUniform(this._viewProjInv, this._cameraWorld, this._apertureRadius, this._focusDistance));
|
|
923
|
+
const device = this._device;
|
|
924
|
+
const run = (pipeline, sample) => {
|
|
925
|
+
// A fresh uniform for each queued dispatch keeps batch samples independent.
|
|
926
|
+
const parameters = device.createBuffer({ size: 16, usage: GPUBufferUsage.UNIFORM, mappedAtCreation: true });
|
|
927
|
+
new Uint32Array(parameters.getMappedRange()).set([state.width, state.height, sample, aovMask(kinds)]);
|
|
928
|
+
parameters.unmap();
|
|
929
|
+
const output = device.createBindGroup({ layout: pipeline.getBindGroupLayout(groupIndex), entries: [
|
|
930
|
+
{ binding: 5, resource: { buffer: state.accumulation } }, { binding: 6, resource: { buffer: state.center } },
|
|
931
|
+
{ binding: 7, resource: { buffer: state.scene } }, { binding: 8, resource: { buffer: parameters } }, { binding: 9, resource: { buffer: state.previousCenter } }
|
|
932
|
+
] });
|
|
933
|
+
const encoder = device.createCommandEncoder({ label: 'AOV' }), pass = encoder.beginComputePass();
|
|
934
|
+
if (textures?.table)
|
|
935
|
+
setResourceTable(pass, textures.table);
|
|
936
|
+
pass.setPipeline(pipeline);
|
|
937
|
+
for (let i = 0; i < groupIndex; i++)
|
|
938
|
+
pass.setBindGroup(i, groups[i]);
|
|
939
|
+
pass.setBindGroup(groupIndex, output);
|
|
940
|
+
pass.dispatchWorkgroups(Math.ceil(state.width / 8), Math.ceil(state.height / 8));
|
|
941
|
+
pass.end();
|
|
942
|
+
device.queue.submit([encoder.finish()]);
|
|
943
|
+
parameters.destroy();
|
|
944
|
+
};
|
|
945
|
+
if (!state.centerReady) {
|
|
946
|
+
run(pipelines.center, 0);
|
|
947
|
+
state.centerReady = true;
|
|
948
|
+
state.history.accept(state.frame);
|
|
949
|
+
}
|
|
950
|
+
if ((aovMask(kinds) & 31) === 0)
|
|
951
|
+
state.samples = target;
|
|
952
|
+
while (state.samples < target) {
|
|
953
|
+
run(pipelines.accumulation, state.samples);
|
|
954
|
+
state.samples++;
|
|
955
|
+
}
|
|
956
|
+
return true;
|
|
957
|
+
}
|
|
1060
958
|
async readDepthSamples(area, aspect) {
|
|
1061
959
|
const tracePipeline = this._rayTracePipeline;
|
|
1062
960
|
const groups = this._rayTraceBindGroups;
|
|
961
|
+
const textures = this._bindless, textureRevision = textures?.revision;
|
|
1063
962
|
if (!tracePipeline || !groups || !this._depthCompute || this._isCompilingShader)
|
|
1064
963
|
return;
|
|
1065
964
|
const packed = packDepthSampleArea(area, aspect ?? this._width / this._height);
|
|
@@ -1071,10 +970,11 @@ ${rayTraceCompute({
|
|
|
1071
970
|
{ binding: 4, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } }
|
|
1072
971
|
]
|
|
1073
972
|
});
|
|
1074
|
-
const
|
|
973
|
+
const descriptor = {
|
|
1075
974
|
label: 'Depth query layout',
|
|
1076
|
-
bindGroupLayouts: [0, 1, 2].map(i => tracePipeline.getBindGroupLayout(i)).concat(outputLayout)
|
|
1077
|
-
}
|
|
975
|
+
bindGroupLayouts: (textures ? [0, 1] : [0, 1, 2]).map(i => tracePipeline.getBindGroupLayout(i)).concat(outputLayout)
|
|
976
|
+
};
|
|
977
|
+
const layout = this._shaderCache.createPipelineLayout(textures ? resourceTableLayout(descriptor) : descriptor);
|
|
1078
978
|
this._depthTracePipeline = tracePipeline;
|
|
1079
979
|
this._depthPipeline = this._shaderCache.createComputePipelineAsync({
|
|
1080
980
|
label: 'Depth query', layout,
|
|
@@ -1084,7 +984,7 @@ ${rayTraceCompute({
|
|
|
1084
984
|
}
|
|
1085
985
|
const pipeline = await this._depthPipeline;
|
|
1086
986
|
// Scene uploads can replace the buffers while the small query compiles.
|
|
1087
|
-
if (tracePipeline !== this._rayTracePipeline || groups !== this._rayTraceBindGroups)
|
|
987
|
+
if (tracePipeline !== this._rayTracePipeline || groups !== this._rayTraceBindGroups || textures !== this._bindless || textureRevision !== textures?.revision)
|
|
1088
988
|
return;
|
|
1089
989
|
const device = this._device;
|
|
1090
990
|
const bytes = DEPTH_SAMPLE_COUNT * 16;
|
|
@@ -1096,16 +996,18 @@ ${rayTraceCompute({
|
|
|
1096
996
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
|
|
1097
997
|
try {
|
|
1098
998
|
device.queue.writeBuffer(params, 0, packed);
|
|
1099
|
-
const outputGroup = device.createBindGroup({ layout: pipeline.getBindGroupLayout(3), entries: [
|
|
999
|
+
const outputGroup = device.createBindGroup({ layout: pipeline.getBindGroupLayout(textures ? 2 : 3), entries: [
|
|
1100
1000
|
{ binding: 0, resource: { buffer: output } },
|
|
1101
1001
|
{ binding: 4, resource: { buffer: params } }
|
|
1102
1002
|
] });
|
|
1103
1003
|
const encoder = device.createCommandEncoder({ label: 'Depth query' });
|
|
1104
1004
|
const pass = encoder.beginComputePass();
|
|
1005
|
+
if (textures?.table)
|
|
1006
|
+
setResourceTable(pass, textures.table);
|
|
1105
1007
|
pass.setPipeline(pipeline);
|
|
1106
|
-
for (let i = 0; i < 3; i++)
|
|
1008
|
+
for (let i = 0; i < (textures ? 2 : 3); i++)
|
|
1107
1009
|
pass.setBindGroup(i, groups[i]);
|
|
1108
|
-
pass.setBindGroup(3, outputGroup);
|
|
1010
|
+
pass.setBindGroup(textures ? 2 : 3, outputGroup);
|
|
1109
1011
|
pass.dispatchWorkgroups(1);
|
|
1110
1012
|
pass.end();
|
|
1111
1013
|
encoder.copyBufferToBuffer(output, 0, readback, 0, bytes);
|
|
@@ -1140,50 +1042,49 @@ ${rayTraceCompute({
|
|
|
1140
1042
|
if (!this._bvhBuffer || !this._instancesBuffer) {
|
|
1141
1043
|
throw new Error('WebGPU BVH buffers are not ready.');
|
|
1142
1044
|
}
|
|
1143
|
-
const
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
});
|
|
1157
|
-
const texturesBindGroup = _device.createBindGroup({
|
|
1158
|
-
layout: bindGroupPipeline.getBindGroupLayout(1),
|
|
1159
|
-
entries: [
|
|
1160
|
-
{
|
|
1045
|
+
const bufferEntries = [
|
|
1046
|
+
this._bvhBuffer,
|
|
1047
|
+
this._instancesBuffer,
|
|
1048
|
+
this._attrBuffers,
|
|
1049
|
+
this._materialsBuffer
|
|
1050
|
+
].map((buffer, i) => ({
|
|
1051
|
+
binding: i,
|
|
1052
|
+
resource: {
|
|
1053
|
+
buffer: buffer
|
|
1054
|
+
}
|
|
1055
|
+
}));
|
|
1056
|
+
const textureEntries = [
|
|
1057
|
+
...(this._bindless ? [] : [{
|
|
1161
1058
|
binding: 0,
|
|
1162
1059
|
resource: this._mapsSampler
|
|
1163
1060
|
},
|
|
1164
1061
|
{
|
|
1165
1062
|
binding: 1,
|
|
1166
1063
|
resource: this._maps.createView()
|
|
1167
|
-
},
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1173
|
-
},
|
|
1174
|
-
{ binding: 4, resource: this._envTex.createView() },
|
|
1175
|
-
{ binding: 5, resource: this._envDistributionTex.createView() },
|
|
1176
|
-
{ binding: 6, resource: this._backgroundTex.createView() },
|
|
1177
|
-
{ binding: 8, resource: this._lightSamplingTexture.createView() },
|
|
1178
|
-
{ binding: 9, resource: this._openPbrEnergyLut.createView() },
|
|
1179
|
-
{
|
|
1180
|
-
binding: 10,
|
|
1181
|
-
resource: this._adaptiveSamplingTexture.createView()
|
|
1064
|
+
}]),
|
|
1065
|
+
{
|
|
1066
|
+
binding: 3,
|
|
1067
|
+
resource: {
|
|
1068
|
+
buffer: this._bindless?.metadata ?? this._mapInfoUniform
|
|
1182
1069
|
}
|
|
1183
|
-
|
|
1070
|
+
},
|
|
1071
|
+
{ binding: 4, resource: this._envTex.createView() },
|
|
1072
|
+
{ binding: 5, resource: this._envDistributionTex.createView() },
|
|
1073
|
+
{ binding: 6, resource: this._backgroundTex.createView() },
|
|
1074
|
+
{ binding: 8, resource: this._lightSamplingTexture.createView() },
|
|
1075
|
+
{ binding: 9, resource: this._openPbrEnergyLut.createView() },
|
|
1076
|
+
{
|
|
1077
|
+
binding: 10,
|
|
1078
|
+
resource: this._adaptiveSamplingTexture.createView()
|
|
1079
|
+
}
|
|
1080
|
+
];
|
|
1081
|
+
const bufferBindGroup = _device.createBindGroup({ layout: bindGroupPipeline.getBindGroupLayout(0),
|
|
1082
|
+
entries: this._bindless ? bufferEntries.concat(textureEntries.map(e => ({ ...e, binding: e.binding + 4 }))) : bufferEntries });
|
|
1083
|
+
const texturesBindGroup = this._bindless ? undefined : _device.createBindGroup({
|
|
1084
|
+
layout: bindGroupPipeline.getBindGroupLayout(1), entries: textureEntries
|
|
1184
1085
|
});
|
|
1185
1086
|
const uniformBindGroup = _device.createBindGroup({
|
|
1186
|
-
layout: bindGroupPipeline.getBindGroupLayout(2),
|
|
1087
|
+
layout: bindGroupPipeline.getBindGroupLayout(this._bindless ? 1 : 2),
|
|
1187
1088
|
entries: Object.keys(this._uniforms).map((key, i) => ({
|
|
1188
1089
|
binding: i,
|
|
1189
1090
|
resource: {
|
|
@@ -1193,7 +1094,7 @@ ${rayTraceCompute({
|
|
|
1193
1094
|
});
|
|
1194
1095
|
const target = this._targetOutputs.get(this._activeTarget);
|
|
1195
1096
|
const outputBindGroup = target.pipeline === bindGroupPipeline && target.bindGroup || _device.createBindGroup({
|
|
1196
|
-
layout: bindGroupPipeline.getBindGroupLayout(3),
|
|
1097
|
+
layout: bindGroupPipeline.getBindGroupLayout(this._bindless ? 2 : 3),
|
|
1197
1098
|
entries: [
|
|
1198
1099
|
this._outColorBuffer,
|
|
1199
1100
|
this._outNormalBuffer,
|
|
@@ -1208,7 +1109,7 @@ ${rayTraceCompute({
|
|
|
1208
1109
|
target.pipeline = bindGroupPipeline;
|
|
1209
1110
|
this._rayTraceBindGroups = [
|
|
1210
1111
|
bufferBindGroup,
|
|
1211
|
-
texturesBindGroup,
|
|
1112
|
+
...(texturesBindGroup ? [texturesBindGroup] : []),
|
|
1212
1113
|
uniformBindGroup,
|
|
1213
1114
|
outputBindGroup
|
|
1214
1115
|
];
|
|
@@ -1240,6 +1141,8 @@ ${rayTraceCompute({
|
|
|
1240
1141
|
};
|
|
1241
1142
|
}
|
|
1242
1143
|
const pass = encoder.beginComputePass(descriptor);
|
|
1144
|
+
if (this._bindless?.table)
|
|
1145
|
+
setResourceTable(pass, this._bindless.table);
|
|
1243
1146
|
if (!this._rayTracePipeline || !this._rayTraceBindGroups) {
|
|
1244
1147
|
throw new Error('WebGPU ray tracing pass was submitted before it was ready.');
|
|
1245
1148
|
}
|
|
@@ -1259,8 +1162,18 @@ ${rayTraceCompute({
|
|
|
1259
1162
|
};
|
|
1260
1163
|
}
|
|
1261
1164
|
getDiagnostics() {
|
|
1165
|
+
const atlas = this._materialData instanceof MaterialTable ? this._materialData.textureAtlasStats : undefined;
|
|
1262
1166
|
return {
|
|
1263
|
-
textureAtlas:
|
|
1167
|
+
textureAtlas: atlas,
|
|
1168
|
+
materialTextures: {
|
|
1169
|
+
requested: this._textureSelection.requested,
|
|
1170
|
+
active: this._bindless ? 'bindless' : 'atlas',
|
|
1171
|
+
fallbackReason: this._textureSelection.fallbackReason,
|
|
1172
|
+
...(this._bindless?.diagnostics ?? {
|
|
1173
|
+
textureCount: atlas?.textureCount ?? 0, estimatedBytes: atlas?.estimatedBytes ?? 0,
|
|
1174
|
+
scale: atlas?.scale ?? 1, metadataBytes: 0, resourceTableCapacity: 0, retiredBytes: 0
|
|
1175
|
+
})
|
|
1176
|
+
},
|
|
1264
1177
|
shaderCompilation: this._shaderCompilationDiagnostics,
|
|
1265
1178
|
lightSampling: {
|
|
1266
1179
|
emissiveTriangles: this._emissiveTriangles.length,
|
|
@@ -1325,15 +1238,14 @@ ${rayTraceCompute({
|
|
|
1325
1238
|
return changed;
|
|
1326
1239
|
}
|
|
1327
1240
|
setSamplingPattern(pattern, maxSamples, sequenceSeed = 0) {
|
|
1328
|
-
const
|
|
1329
|
-
const
|
|
1241
|
+
const sampling = traceSampling(pattern, maxSamples, sequenceSeed);
|
|
1242
|
+
const { code, logSPP } = sampling;
|
|
1330
1243
|
const views = this._rtUniform.views;
|
|
1331
1244
|
const changed = this._constants.SAMPLING_PATTERN !== code ||
|
|
1332
1245
|
views.sequenceSeed[0] !== (sequenceSeed >>> 0) ||
|
|
1333
1246
|
(code === 1 && views.zSobolLogSPP[0] !== logSPP);
|
|
1334
1247
|
this._constants.SAMPLING_PATTERN = code;
|
|
1335
|
-
views
|
|
1336
|
-
views.zSobolLogSPP[0] = logSPP;
|
|
1248
|
+
writeTraceSampling(views, sampling);
|
|
1337
1249
|
return changed;
|
|
1338
1250
|
}
|
|
1339
1251
|
setSampleSequenceOffset(offset) {
|
|
@@ -1354,10 +1266,7 @@ ${rayTraceCompute({
|
|
|
1354
1266
|
this._device.queue.writeTexture({ texture: this._adaptiveSamplingTexture }, data, { bytesPerRow: width * Float32Array.BYTES_PER_ELEMENT }, [width, height]);
|
|
1355
1267
|
}
|
|
1356
1268
|
setQuality(options) {
|
|
1357
|
-
this._rtUniform.views
|
|
1358
|
-
this._rtUniform.views.bevel[0] = +options.bevel;
|
|
1359
|
-
this._rtUniform.views.dispersionWavelengths[0] = options.dispersionWavelengths;
|
|
1360
|
-
this._rtUniform.views.directLightCandidates[0] = normalizeDirectLightCandidates(options.directLightCandidates);
|
|
1269
|
+
writeTraceQuality(this._rtUniform.views, options);
|
|
1361
1270
|
}
|
|
1362
1271
|
_setEnvMap(envImage) {
|
|
1363
1272
|
const device = this._device;
|
|
@@ -1365,53 +1274,74 @@ ${rayTraceCompute({
|
|
|
1365
1274
|
if (!environmentMapSourcesMatch(envImage, this._envImageSource) ||
|
|
1366
1275
|
!this._envTex) {
|
|
1367
1276
|
this._envImageSource = envImage;
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
const
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
}, envImage.data.buffer, {
|
|
1398
|
-
bytesPerRow: envImage.width * 4 * 4
|
|
1399
|
-
}, {
|
|
1400
|
-
width: envImage.width,
|
|
1401
|
-
height: envImage.height,
|
|
1402
|
-
depthOrArrayLayers: 1
|
|
1277
|
+
const sky = envImage && 'sky' in envImage ? envImage : undefined;
|
|
1278
|
+
if (sky && (sky.width + 2 > device.limits.maxTextureDimension2D || sky.height + 1 > device.limits.maxTextureDimension2D))
|
|
1279
|
+
throw new RangeError('ProceduralSky resolution exceeds the device texture size limit.');
|
|
1280
|
+
const gpuDistribution = envImage && (sky || envImage.width * envImage.height >= 65536) &&
|
|
1281
|
+
WGPUEnvMapDistribution.supported(device, envImage.width, envImage.height);
|
|
1282
|
+
if (sky && !gpuDistribution)
|
|
1283
|
+
throw new RangeError('ProceduralSky resolution exceeds the GPU sampling storage limit; reduce resolution.');
|
|
1284
|
+
const distribution = envImage && !('sky' in envImage) && !gpuDistribution ? envMapDistribution(envImage) : undefined;
|
|
1285
|
+
const distributionWidth = envImage ? envImage.width + 2 : 1;
|
|
1286
|
+
const distributionHeight = envImage ? envImage.height + 1 : 1;
|
|
1287
|
+
const width = envImage?.width ?? 1;
|
|
1288
|
+
const height = envImage?.height ?? 1;
|
|
1289
|
+
const resized = !this._envTex || this._envTex.width !== width || this._envTex.height !== height ||
|
|
1290
|
+
!this._envDistributionTex || this._envDistributionTex.width !== distributionWidth || this._envDistributionTex.height !== distributionHeight;
|
|
1291
|
+
if (resized) {
|
|
1292
|
+
this._envTex?.destroy();
|
|
1293
|
+
this._envDistributionTex?.destroy();
|
|
1294
|
+
const usage = GPUTextureUsage.TEXTURE_BINDING |
|
|
1295
|
+
GPUTextureUsage.COPY_DST |
|
|
1296
|
+
GPUTextureUsage.RENDER_ATTACHMENT;
|
|
1297
|
+
this._envTex = device.createTexture({
|
|
1298
|
+
format: 'rgba32float',
|
|
1299
|
+
usage: usage | GPUTextureUsage.STORAGE_BINDING,
|
|
1300
|
+
label: 'Env',
|
|
1301
|
+
size: {
|
|
1302
|
+
width,
|
|
1303
|
+
height,
|
|
1304
|
+
depthOrArrayLayers: 1
|
|
1305
|
+
}
|
|
1403
1306
|
});
|
|
1404
|
-
device.
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1307
|
+
this._envDistributionTex = device.createTexture({
|
|
1308
|
+
format: 'rg32float',
|
|
1309
|
+
usage: usage | GPUTextureUsage.STORAGE_BINDING,
|
|
1310
|
+
label: 'Env Distribution',
|
|
1311
|
+
size: {
|
|
1312
|
+
width: distributionWidth,
|
|
1313
|
+
height: distributionHeight,
|
|
1314
|
+
depthOrArrayLayers: 1
|
|
1315
|
+
}
|
|
1412
1316
|
});
|
|
1413
1317
|
}
|
|
1414
|
-
|
|
1318
|
+
if (envImage) {
|
|
1319
|
+
if ('sky' in envImage) {
|
|
1320
|
+
this._skyBaker ??= new WGPUSkyBaker(device);
|
|
1321
|
+
this._skyBaker.bake(envImage, this._envTex);
|
|
1322
|
+
}
|
|
1323
|
+
else
|
|
1324
|
+
device.queue.writeTexture({
|
|
1325
|
+
texture: this._envTex
|
|
1326
|
+
}, envImage.data.buffer, {
|
|
1327
|
+
bytesPerRow: envImage.width * 4 * 4
|
|
1328
|
+
}, {
|
|
1329
|
+
width: envImage.width,
|
|
1330
|
+
height: envImage.height,
|
|
1331
|
+
depthOrArrayLayers: 1
|
|
1332
|
+
});
|
|
1333
|
+
if (gpuDistribution) {
|
|
1334
|
+
this._envDistribution ??= new WGPUEnvMapDistribution(device);
|
|
1335
|
+
this._envDistribution.build(this._envTex, this._envDistributionTex);
|
|
1336
|
+
}
|
|
1337
|
+
else if (distribution) {
|
|
1338
|
+
this._envDistribution?.dispose();
|
|
1339
|
+
device.queue.writeTexture({ texture: this._envDistributionTex }, distribution.data.buffer, { bytesPerRow: distribution.width * 4 * 2 }, { width: distribution.width, height: distribution.height, depthOrArrayLayers: 1 });
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
else
|
|
1343
|
+
this._envDistribution?.dispose();
|
|
1344
|
+
this._needsUpdateBindGroups ||= resized;
|
|
1415
1345
|
}
|
|
1416
1346
|
this._constants.USE_ENVMAP = !!envImage;
|
|
1417
1347
|
}
|
|
@@ -1624,6 +1554,7 @@ ${rayTraceCompute({
|
|
|
1624
1554
|
}
|
|
1625
1555
|
setBackground(background) {
|
|
1626
1556
|
this._rtUniform.views.backgroundMapTransform.set(backgroundMapTransform(background));
|
|
1557
|
+
this._rtUniform.views.backgroundMapRotation.set(backgroundMapRotation(background));
|
|
1627
1558
|
this._constants.USE_BACKGROUND = !!background;
|
|
1628
1559
|
const backgroundImage = background && !Array.isArray(background)
|
|
1629
1560
|
? generateBackgroundMapFromSceneBackground(background)
|
|
@@ -1658,73 +1589,45 @@ ${rayTraceCompute({
|
|
|
1658
1589
|
return;
|
|
1659
1590
|
}
|
|
1660
1591
|
this._backgroundImageSource = backgroundImage;
|
|
1661
|
-
this._backgroundTex?.destroy();
|
|
1662
1592
|
const width = backgroundImage?.width ?? 1;
|
|
1663
1593
|
const height = backgroundImage?.height ?? 1;
|
|
1664
|
-
this.
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1594
|
+
if (backgroundImage && 'sky' in backgroundImage && (width > this._device.limits.maxTextureDimension2D || height > this._device.limits.maxTextureDimension2D))
|
|
1595
|
+
throw new RangeError('ProceduralSky resolution exceeds the device texture size limit.');
|
|
1596
|
+
const resized = !this._backgroundTex || this._backgroundTex.width !== width || this._backgroundTex.height !== height;
|
|
1597
|
+
if (resized) {
|
|
1598
|
+
this._backgroundTex?.destroy();
|
|
1599
|
+
this._backgroundTex = this._device.createTexture({
|
|
1600
|
+
format: 'rgba32float',
|
|
1601
|
+
usage: GPUTextureUsage.TEXTURE_BINDING |
|
|
1602
|
+
GPUTextureUsage.COPY_DST |
|
|
1603
|
+
GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.STORAGE_BINDING,
|
|
1604
|
+
label: 'Background',
|
|
1605
|
+
size: { width, height, depthOrArrayLayers: 1 }
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
if (backgroundImage && 'sky' in backgroundImage) {
|
|
1609
|
+
this._skyBaker ??= new WGPUSkyBaker(this._device);
|
|
1610
|
+
this._skyBaker.bake(backgroundImage, this._backgroundTex);
|
|
1611
|
+
}
|
|
1612
|
+
else if (backgroundImage) {
|
|
1673
1613
|
const source = backgroundImage.data;
|
|
1674
1614
|
const data = source instanceof Float32Array
|
|
1675
1615
|
? source
|
|
1676
|
-
:
|
|
1616
|
+
: source instanceof Uint8Array || source instanceof Uint8ClampedArray
|
|
1617
|
+
? Float32Array.from(source, value => value / 255)
|
|
1618
|
+
: Float32Array.from(source);
|
|
1677
1619
|
this._device.queue.writeTexture({ texture: this._backgroundTex }, data.buffer, { bytesPerRow: width * 4 * 4 }, { width, height, depthOrArrayLayers: 1 });
|
|
1678
1620
|
}
|
|
1679
|
-
this._needsUpdateBindGroups
|
|
1621
|
+
this._needsUpdateBindGroups ||= resized;
|
|
1680
1622
|
}
|
|
1681
1623
|
_updateLightSamplingData() {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
this.
|
|
1686
|
-
this.
|
|
1687
|
-
const
|
|
1688
|
-
|
|
1689
|
-
environment: { count: 0, weight: 0, pmf: 0 },
|
|
1690
|
-
infinite: { count: 0, weight: 0, pmf: 0 },
|
|
1691
|
-
localAndEmissive: { count: 0, weight: 0, pmf: 0 }
|
|
1692
|
-
};
|
|
1693
|
-
this._analyticLightSelectionPmfs = new Array(this._analyticLights.length).fill(0);
|
|
1694
|
-
this._rtUniform.views.envLightPmf[0] = 0;
|
|
1695
|
-
const domains = [domainDiagnostics.environment, domainDiagnostics.infinite, domainDiagnostics.localAndEmissive];
|
|
1696
|
-
for (let i = 0; i < choices.count; i++) {
|
|
1697
|
-
const type = choices.sourceTypes[i], source = choices.sourceIndices[i];
|
|
1698
|
-
const pmf = distribution.pmfs[i];
|
|
1699
|
-
const domainIndex = type === LIGHT_CHOICE_ENVIRONMENT ? LIGHT_DOMAIN_ENVIRONMENT :
|
|
1700
|
-
type === LIGHT_CHOICE_ANALYTIC && this._analyticLights[source]?.type === 'DirectionalLight' ?
|
|
1701
|
-
LIGHT_DOMAIN_INFINITE : LIGHT_DOMAIN_LOCAL_AND_EMISSIVE;
|
|
1702
|
-
const domain = domains[domainIndex];
|
|
1703
|
-
domain.count++;
|
|
1704
|
-
domain.weight += choices.weights[i];
|
|
1705
|
-
domain.pmf += pmf;
|
|
1706
|
-
if (type === LIGHT_CHOICE_ENVIRONMENT)
|
|
1707
|
-
this._rtUniform.views.envLightPmf[0] = pmf;
|
|
1708
|
-
else if (type === LIGHT_CHOICE_ANALYTIC)
|
|
1709
|
-
this._analyticLightSelectionPmfs[source] = pmf;
|
|
1710
|
-
else
|
|
1711
|
-
this._emissiveTriangles[source].selectionPmf = pmf;
|
|
1712
|
-
}
|
|
1713
|
-
this._lightDomainDiagnostics = domainDiagnostics;
|
|
1714
|
-
this._rtUniform.views.lightChoiceCount[0] = choices.count;
|
|
1715
|
-
this._rtUniform.views.lightWeightTotal[0] = distribution.totalWeight;
|
|
1716
|
-
const emissiveTexels = this._emissiveTriangles.length * 6;
|
|
1717
|
-
const choiceTexels = Math.max(choices.count, 1);
|
|
1718
|
-
const profileStartTexel = emissiveTexels + choiceTexels;
|
|
1719
|
-
const packedIES = packIESProfiles(this._analyticLights, profileStartTexel);
|
|
1720
|
-
this._iesProfileTexelOffsets = packedIES.offsets;
|
|
1721
|
-
const totalTexels = Math.max(profileStartTexel + packedIES.texelCount, 1);
|
|
1722
|
-
const maxDimension = this._device.limits.maxTextureDimension2D;
|
|
1723
|
-
const width = Math.min(maxDimension, Math.max(16, Math.ceil(Math.sqrt(totalTexels) / 16) * 16));
|
|
1724
|
-
const height = Math.ceil(totalTexels / width);
|
|
1725
|
-
if (height > maxDimension) {
|
|
1726
|
-
throw new Error('Too many emissive triangles for the light sampling texture.');
|
|
1727
|
-
}
|
|
1624
|
+
this._constants.LIGHT_CAPABILITIES = lightShaderCapabilities(this._analyticLights.map(light => light.type), this._emissiveTriangles.length);
|
|
1625
|
+
const lighting = prepareSceneLightSampling(this._analyticLights, this._emissiveTriangles, this._envImageSource && 'sky' in this._envImageSource ? proceduralEnvironmentPower(this._envImageSource) : estimateEnvironmentPower(this._envImageSource), this._device.limits.maxTextureDimension2D, this._lightChoices, this._lightSamplingScratch, this._shadowCatcherLightChoices);
|
|
1626
|
+
this._analyticLightSelectionPmfs = lighting.analyticPmfs;
|
|
1627
|
+
this._iesProfileTexelOffsets = lighting.profiles.offsets;
|
|
1628
|
+
this._lightDomainDiagnostics = lighting.domains;
|
|
1629
|
+
const { lightWidth: width, lightHeight: height, lightData: textureData } = lighting;
|
|
1630
|
+
writeTraceLighting(this._rtUniform.views, lighting);
|
|
1728
1631
|
const resized = !this._lightSamplingTexture || width !== this._lightSamplingTextureSize[0] || height !== this._lightSamplingTextureSize[1];
|
|
1729
1632
|
if (!this._lightSamplingTexture ||
|
|
1730
1633
|
width !== this._lightSamplingTextureSize[0] ||
|
|
@@ -1739,14 +1642,6 @@ ${rayTraceCompute({
|
|
|
1739
1642
|
this._lightSamplingTextureSize = [width, height];
|
|
1740
1643
|
this._needsUpdateBindGroups = true;
|
|
1741
1644
|
}
|
|
1742
|
-
const textureData = this._lightSamplingScratch?.length === width * height * 4
|
|
1743
|
-
? this._lightSamplingScratch : new Float32Array(width * height * 4);
|
|
1744
|
-
textureData.fill(0);
|
|
1745
|
-
if (this._emissiveTriangles.length) {
|
|
1746
|
-
packEmissiveTriangles(this._emissiveTriangles, textureData);
|
|
1747
|
-
}
|
|
1748
|
-
new Uint32Array(textureData.buffer).set(distribution.choices, emissiveTexels * 4);
|
|
1749
|
-
textureData.set(packedIES.data, profileStartTexel * 4);
|
|
1750
1645
|
const previous = this._lightSamplingData;
|
|
1751
1646
|
const full = resized || !previous || this._lightSamplingTriangleCount !== this._emissiveTriangles.length;
|
|
1752
1647
|
const words = new Uint32Array(textureData.buffer);
|
|
@@ -1772,8 +1667,6 @@ ${rayTraceCompute({
|
|
|
1772
1667
|
this._lightSamplingScratch = previous;
|
|
1773
1668
|
this._lightSamplingData = textureData;
|
|
1774
1669
|
this._lightSamplingTriangleCount = this._emissiveTriangles.length;
|
|
1775
|
-
this._rtUniform.views.lightSamplingTextureWidth[0] = width;
|
|
1776
|
-
this._rtUniform.views.lightChoiceTexelOffset[0] = emissiveTexels;
|
|
1777
1670
|
this._needsUpdateAnalyticLightsBuffer = true;
|
|
1778
1671
|
this._needsUpdateLightSamplingData = false;
|
|
1779
1672
|
}
|
|
@@ -1823,33 +1716,15 @@ ${rayTraceCompute({
|
|
|
1823
1716
|
const tlas = buildTLAS(res.instances, res.blases);
|
|
1824
1717
|
this._tlas = tlas;
|
|
1825
1718
|
this._uploadBVH(tlas, res.blases);
|
|
1826
|
-
const materialData = (this._materialData =
|
|
1719
|
+
const materialData = (this._materialData = this._createMaterialData(materials, this._analyticLights, {
|
|
1827
1720
|
maxTextureArrayBytes: this._maxTextureArrayBytes,
|
|
1828
1721
|
maxTextureArrayLayers: this._device.limits.maxTextureArrayLayers,
|
|
1829
1722
|
maxTextureDimension2D: this._device.limits.maxTextureDimension2D
|
|
1830
1723
|
}));
|
|
1831
1724
|
this._emissiveTriangles = this._emissiveCache.collect(res.emissiveBindings, materials);
|
|
1832
1725
|
this._needsUpdateLightSamplingData = true;
|
|
1833
|
-
const
|
|
1834
|
-
|
|
1835
|
-
'normal',
|
|
1836
|
-
'uv',
|
|
1837
|
-
'uv1',
|
|
1838
|
-
'color',
|
|
1839
|
-
'tangent',
|
|
1840
|
-
'materialIndex'
|
|
1841
|
-
];
|
|
1842
|
-
const attributes = attrNames.map((a) => mergedGeometry[a]);
|
|
1843
|
-
const fixedSize = 4;
|
|
1844
|
-
let stride = 0;
|
|
1845
|
-
const offsets = attrNames.map((attrName, idx) => {
|
|
1846
|
-
const attr = attributes[idx];
|
|
1847
|
-
const offset = stride;
|
|
1848
|
-
if (attr) {
|
|
1849
|
-
stride += fixedSize;
|
|
1850
|
-
}
|
|
1851
|
-
return offset;
|
|
1852
|
-
});
|
|
1726
|
+
const attributeLayout = sceneAttributeLayout(mergedGeometry);
|
|
1727
|
+
const { stride, offsets } = attributeLayout;
|
|
1853
1728
|
const attrBufferData = new F32(mergedGeometry.vertexCount * stride);
|
|
1854
1729
|
packVertexAttributes(mergedGeometry, attrBufferData, stride, offsets, 0, mergedGeometry.vertexCount);
|
|
1855
1730
|
this._attributeData = attrBufferData;
|
|
@@ -1869,17 +1744,7 @@ ${rayTraceCompute({
|
|
|
1869
1744
|
cwbvh: 8
|
|
1870
1745
|
};
|
|
1871
1746
|
this._blasLayoutMask = res.blases.reduce((mask, blas) => mask | blasLayoutBits[blas.bvh.layout ?? 'bvh2'], 0);
|
|
1872
|
-
Object.assign(this._constants,
|
|
1873
|
-
TLAS_STACK_SIZE: retainedShaderCapacity(traversalStackSizes.tlas, Number(this._constants.TLAS_STACK_SIZE ?? 0)),
|
|
1874
|
-
BLAS_STACK_SIZE: retainedShaderCapacity(traversalStackSizes.blas, Number(this._constants.BLAS_STACK_SIZE ?? 0), 32),
|
|
1875
|
-
USE_UV: mergedGeometry.uv != null,
|
|
1876
|
-
USE_VERTEX_COLOR: mergedGeometry.color != null,
|
|
1877
|
-
ATTR_STRIDE: stride / fixedSize,
|
|
1878
|
-
...offsets.reduce((obj, off, idx) => {
|
|
1879
|
-
obj[attrNames[idx].toUpperCase() + '_OFF'] = off / fixedSize;
|
|
1880
|
-
return obj;
|
|
1881
|
-
}, {})
|
|
1882
|
-
});
|
|
1747
|
+
Object.assign(this._constants, sceneTraversalConstants(traversalStackSizes.tlas, traversalStackSizes.blas, this._constants), attributeLayout.constants);
|
|
1883
1748
|
this._updateMaterialConstants(materials, materialData, mergedGeometry);
|
|
1884
1749
|
this._updateTextures(materialData);
|
|
1885
1750
|
this._needsUpdateBindGroups = true;
|
|
@@ -1910,47 +1775,10 @@ ${rayTraceCompute({
|
|
|
1910
1775
|
// Needs to recreate pipeline layout
|
|
1911
1776
|
this._rayTracePipelineLayout = undefined;
|
|
1912
1777
|
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
// Shrinking the array would rebuild every pipeline again on the next edit.
|
|
1918
|
-
const NUM_MAPS = Math.max(Math.ceil(+materialData.defines.NUM_MAPS / 10) * 10, Number(this._constants.NUM_MAPS ?? 0), 20);
|
|
1919
|
-
// Either layer's map requires independent normals, including a smooth
|
|
1920
|
-
// coat over a mapped base. Unmapped materials retain the shared path.
|
|
1921
|
-
const USE_COAT_NORMAL_FRAMES = materials.some(m => m.coatWeight > 0 && (!!m.normalMap || !!m.coatNormalMap));
|
|
1922
|
-
Object.assign(this._constants, {
|
|
1923
|
-
// Match the atlas UV selector. Keep the second set when any texture
|
|
1924
|
-
// needs it; material/texture edits already rebuild these constants.
|
|
1925
|
-
USE_UV1: materialData.bufferData.mapUvChannel.some(channel => channel > 0.5),
|
|
1926
|
-
// Isotropic OpenPBR constructs its own basis. Normal mapping uses
|
|
1927
|
-
// triangle UV differentials rather than this vertex tangent.
|
|
1928
|
-
USE_TANGENT: mergedGeometry.tangent != null &&
|
|
1929
|
-
materials.some(material => material.specularAnisotropy > 0 || material.coatAnisotropy > 0 || (!!material.coatNormalMap && material.coatWeight > 0)),
|
|
1930
|
-
USE_COAT_NORMAL_FRAMES,
|
|
1931
|
-
USE_ANISOTROPY_DIRECTIONS: USE_COAT_NORMAL_FRAMES || materials.some(m => m.specularAnisotropy > 0 && (m.specularAnisotropyModel === 'gltf' || !!m.anisotropyMap || m.specularAnisotropyRotation !== 0) ||
|
|
1932
|
-
m.coatAnisotropy > 0 && m.coatAnisotropyRotation !== 0),
|
|
1933
|
-
HAS_MEDIUM,
|
|
1934
|
-
HAS_SHADOW_CATCHER: this._hasShadowCatcher,
|
|
1935
|
-
HAS_THIN_FILM: materials.some((material) => material.thinFilmWeight > 0),
|
|
1936
|
-
HAS_COAT: materials.some((material) => material.coatWeight > 0),
|
|
1937
|
-
HAS_FUZZ: materials.some((material) => material.fuzzWeight > 0),
|
|
1938
|
-
HAS_SUBSURFACE: materials.some((material) => material.subsurfaceWeight > 0),
|
|
1939
|
-
HAS_BEVEL,
|
|
1940
|
-
HAS_ALPHA_MASK: materials.some((m) => resolveMaterialAlphaMode(m) === 'mask'),
|
|
1941
|
-
HAS_ALPHA_BLEND: materials.some((m) => resolveMaterialAlphaMode(m) === 'blend'),
|
|
1942
|
-
HAS_ALPHA: materials.some((m) => resolveMaterialAlphaMode(m) !== 'opaque'),
|
|
1943
|
-
SPECTRAL,
|
|
1944
|
-
BEVEL_SAMPLES: this._bevelSamples,
|
|
1945
|
-
USE_RR: true,
|
|
1946
|
-
// Match WebGL: defer roulette for multiple-scattering SSS paths.
|
|
1947
|
-
RR_MAX: HAS_MEDIUM ? 12 : 2,
|
|
1948
|
-
NUM_UNIFORM_LIGHTS: FIXED_LIGHT_COUNT,
|
|
1949
|
-
...materialData.defines,
|
|
1950
|
-
NUM_MAPS,
|
|
1951
|
-
...materialTextureFeatures(materialData.defines),
|
|
1952
|
-
USE_NORMAL_MAPS: +materialData.defines.NUM_NORMAL_MAPS > 0
|
|
1953
|
-
});
|
|
1778
|
+
Object.assign(this._constants, wgpuMaterialConstants(materials, materialData, mergedGeometry, this._bevelSamples, Number(this._constants.NUM_MAPS ?? 0)));
|
|
1779
|
+
// Runtime storage metadata has no texture-count specialization.
|
|
1780
|
+
if (this._bindless)
|
|
1781
|
+
this._constants.NUM_MAPS = 20;
|
|
1954
1782
|
}
|
|
1955
1783
|
_updateGeometryData() {
|
|
1956
1784
|
const res = this._preparedMeshData, tlas = this._tlas;
|
|
@@ -1996,7 +1824,7 @@ ${rayTraceCompute({
|
|
|
1996
1824
|
const res = this._preparedMeshData;
|
|
1997
1825
|
let materialData = this._materialData;
|
|
1998
1826
|
if (update.level === 'textures') {
|
|
1999
|
-
materialData = this._materialData =
|
|
1827
|
+
materialData = this._materialData = this._createMaterialData(res.materials, this._analyticLights, {
|
|
2000
1828
|
maxTextureArrayBytes: this._maxTextureArrayBytes,
|
|
2001
1829
|
maxTextureArrayLayers: this._device.limits.maxTextureArrayLayers,
|
|
2002
1830
|
maxTextureDimension2D: this._device.limits.maxTextureDimension2D
|
|
@@ -2106,7 +1934,28 @@ ${rayTraceCompute({
|
|
|
2106
1934
|
this._dirtyTransformMeshes.clear();
|
|
2107
1935
|
this._needsRefitTLAS = false;
|
|
2108
1936
|
}
|
|
1937
|
+
_createMaterialData(...args) {
|
|
1938
|
+
if (this._bindless) {
|
|
1939
|
+
const data = new WGPUBindlessMaterialData(args[0], args[1]);
|
|
1940
|
+
const reason = bindlessLimitReason(this._device, data.textures.length);
|
|
1941
|
+
if (!reason)
|
|
1942
|
+
return data;
|
|
1943
|
+
this._textureSelection.fallbackReason = reason;
|
|
1944
|
+
const retired = this._bindless;
|
|
1945
|
+
this._retiredBindless.add(retired);
|
|
1946
|
+
void this._device.queue.onSubmittedWorkDone().catch(() => { }).then(() => { retired.dispose(); this._retiredBindless.delete(retired); });
|
|
1947
|
+
this._bindless = undefined;
|
|
1948
|
+
this._computeShaderModule = undefined;
|
|
1949
|
+
this._rayTracePipelineLayout = undefined;
|
|
1950
|
+
}
|
|
1951
|
+
return new MaterialTable(...args);
|
|
1952
|
+
}
|
|
2109
1953
|
_updateTextures(materialData) {
|
|
1954
|
+
if (materialData instanceof WGPUBindlessMaterialData) {
|
|
1955
|
+
this._bindless.update(materialData.textures, this._maxTextureArrayBytes);
|
|
1956
|
+
this._needsUpdateBindGroups = true;
|
|
1957
|
+
return;
|
|
1958
|
+
}
|
|
2110
1959
|
// Textures
|
|
2111
1960
|
// TODO Avoid zero length array.
|
|
2112
1961
|
const mapInfo = materialData.bufferData.mapInfo ?? [0, 0, 0, 0];
|
|
@@ -2268,14 +2117,7 @@ ${rayTraceCompute({
|
|
|
2268
2117
|
const arr = this._rtUniform.views.jitter;
|
|
2269
2118
|
arr[0] = x;
|
|
2270
2119
|
arr[1] = y;
|
|
2271
|
-
this._device.queue.writeBuffer(this._uniforms.cameraUniform, 0,
|
|
2272
|
-
...this._viewProjInv,
|
|
2273
|
-
...this._cameraWorld,
|
|
2274
|
-
this._apertureRadius,
|
|
2275
|
-
this._focusDistance,
|
|
2276
|
-
0,
|
|
2277
|
-
0
|
|
2278
|
-
]));
|
|
2120
|
+
this._device.queue.writeBuffer(this._uniforms.cameraUniform, 0, packCameraUniform(this._viewProjInv, this._cameraWorld, this._apertureRadius, this._focusDistance));
|
|
2279
2121
|
}
|
|
2280
2122
|
setSampleTiles(columns, rows, tileX, tileY) {
|
|
2281
2123
|
const arr = this._rtUniform.views.scaleOffset;
|
|
@@ -2301,7 +2143,14 @@ ${rayTraceCompute({
|
|
|
2301
2143
|
return this._hasShadowCatcher;
|
|
2302
2144
|
}
|
|
2303
2145
|
dispose() {
|
|
2146
|
+
this._disposed = true;
|
|
2147
|
+
this._envDistribution?.dispose();
|
|
2148
|
+
this._skyBaker?.dispose();
|
|
2149
|
+
this._bindless?.dispose();
|
|
2150
|
+
this._retiredBindless.forEach(textures => textures.dispose());
|
|
2151
|
+
this._retiredBindless.clear();
|
|
2304
2152
|
this._shaderCache.clear();
|
|
2153
|
+
this._shaderCapabilities.clear();
|
|
2305
2154
|
const buffers = new Set([
|
|
2306
2155
|
...Array.from(this._targetOutputs.values()).flatMap(target => target.buffers),
|
|
2307
2156
|
this._mapInfoUniform,
|