@meimu/mutracer 0.1.5 → 0.3.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 +10 -7
- package/THIRD_PARTY_NOTICES.md +13 -8
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +12316 -9228
- package/docs/api.md +232 -21
- package/docs/caustics.md +80 -0
- package/docs/denoising.md +30 -15
- package/docs/materials.md +6 -5
- package/docs/performance.md +5 -2
- package/docs/progressive-rendering.md +73 -1
- package/docs/technical/continuous-spectrum.md +93 -0
- package/docs/threejs.md +14 -5
- package/docs/updates.md +46 -2
- package/docs/viewer-checklist.md +65 -0
- package/docs/viewer.md +15 -8
- package/lib/Display.d.ts +13 -2
- package/lib/Display.js +28 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +4 -0
- package/lib/Engine.js +99 -37
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +98 -15
- package/lib/Render.js +275 -27
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +11 -1
- package/lib/RenderLoop.js +120 -15
- 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 +11 -0
- package/lib/renderer/GPUTraceQueue.js +33 -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 +36 -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/WGPUCausticLightPass.d.ts +48 -0
- package/lib/renderer/WGPUCausticLightPass.js +217 -0
- package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
- 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/WGPUPhotonMap.d.ts +37 -0
- package/lib/renderer/WGPUPhotonMap.js +191 -0
- package/lib/renderer/WGPUPhotonMap.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
- package/lib/renderer/WGPURayTraceOutput.js +132 -29
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +83 -56
- package/lib/renderer/WGPURayTracePass.js +884 -837
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
- package/lib/renderer/WGPURenderingPipeline.js +297 -82
- 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 +7 -4
- package/lib/renderer/WebGLFullQuadPass.js +22 -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 +18 -3
- package/lib/renderer/WebGLRayTracePass.js +121 -9
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +126 -22
- 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 +6 -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/causticDiagnostics.d.ts +31 -0
- package/lib/renderer/causticDiagnostics.js +5 -0
- package/lib/renderer/causticDiagnostics.js.map +1 -0
- package/lib/renderer/causticEmission.d.ts +10 -0
- package/lib/renderer/causticEmission.js +40 -0
- package/lib/renderer/causticEmission.js.map +1 -0
- package/lib/renderer/causticUniform.d.ts +12 -0
- package/lib/renderer/causticUniform.js +22 -0
- package/lib/renderer/causticUniform.js.map +1 -0
- package/lib/renderer/caustics.d.ts +16 -0
- package/lib/renderer/caustics.js +93 -0
- package/lib/renderer/caustics.js.map +1 -0
- package/lib/renderer/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/emissiveLight.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -67
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +432 -434
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +160 -157
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +802 -802
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +72 -67
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +143 -120
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +21 -18
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampling.glsl.js +91 -94
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
- package/lib/renderer/glsl/chunks/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.d.ts +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +271 -248
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +37 -32
- 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 +22 -18
- package/lib/renderer/lightSampling.js +135 -62
- 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 +7 -3
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -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/researchTransport.d.ts +31 -0
- package/lib/renderer/researchTransport.js +5 -0
- package/lib/renderer/researchTransport.js.map +1 -0
- package/lib/renderer/sceneAssembly.d.ts +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 +119 -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/spectrum.d.ts +21 -0
- package/lib/renderer/spectrum.js +154 -0
- package/lib/renderer/spectrum.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/webglLightSampling.d.ts +39 -0
- package/lib/renderer/webglLightSampling.js +15 -0
- package/lib/renderer/webglLightSampling.js.map +1 -0
- 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 +22 -0
- package/lib/renderer/wgpuShaderSource.js +33 -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/causticLight.compute.d.ts +6 -0
- package/lib/renderer/wgsl/causticLight.compute.js +537 -0
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +41 -35
- 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 +747 -704
- 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 +4 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +83 -79
- 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 +137 -137
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +3 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +52 -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 -144
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +269 -245
- 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 +27 -14
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -95
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
- 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/photonMap.compute.d.ts +29 -0
- package/lib/renderer/wgsl/photonMap.compute.js +352 -0
- package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.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 +25 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +645 -500
- 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 +36 -3
- package/lib/settings/render.js +4 -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 +20 -7
- 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 +5 -0
- package/package.json +33 -7
- package/lib/renderer/texturesFromMaterials.d.ts +0 -6
- package/lib/renderer/texturesFromMaterials.js.map +0 -1
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { hdrResolveWGSL } from './wgsl/compose.frag.wgsl.js';
|
|
2
|
+
import { oidnAuxiliaryDefine } from './wgsl/oidnAuxiliary.wgsl.js';
|
|
3
|
+
import { displayAovKind, DEFAULT_AOV_DISPLAY } from './aovDisplay.js';
|
|
4
|
+
import { WGPUAov } from './WGPUAov.js';
|
|
5
|
+
import { aovMask } from './aov.js';
|
|
1
6
|
import { DisplayPostProcess } from './DisplayPostProcess.js';
|
|
2
7
|
import { customDenoiseLayersMain, customDenoiseCoverageMain } from './wgsl/customDenoise.wgsl.js';
|
|
3
8
|
import { WGPUCanvasSurface } from './WGPUCanvasSurface.js';
|
|
4
9
|
import { WGPUScratchBuffer } from './WGPUScratchBuffer.js';
|
|
5
10
|
import { WGPUScratchTexture } from './WGPUScratchTexture.js';
|
|
6
11
|
import { ScratchPool } from './ScratchPool.js';
|
|
12
|
+
import { GPUTraceQueue } from './GPUTraceQueue.js';
|
|
7
13
|
import { makeRenderPipeline } from './renderPipeline.js';
|
|
8
14
|
import { textureBytes } from './gpuMemory.js';
|
|
9
15
|
import { WGPUFullQuadPass } from './WGPUFullQuadPass.js';
|
|
@@ -21,60 +27,50 @@ export const oidnAlbedoSrgbEncodeMain = /* wgsl */ `
|
|
|
21
27
|
if (globalId.x >= u32(imageSize.x) || globalId.y >= u32(imageSize.y)) { return; }
|
|
22
28
|
let index = globalId.x + globalId.y * u32(imageSize.x);
|
|
23
29
|
let raw = textureLoad(in_albedo, vec2u(globalId.xy), 0);
|
|
24
|
-
let
|
|
25
|
-
let encoded = select(
|
|
26
|
-
1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055,
|
|
27
|
-
12.92 * linear,
|
|
28
|
-
linear <= vec3f(0.0031308)
|
|
29
|
-
);
|
|
30
|
+
let encoded = sQ(raw.rgb);
|
|
30
31
|
out_albedo[index] = vec4f(encoded, raw.a);
|
|
31
32
|
`;
|
|
32
33
|
export const oidnAlbedoSrgbDecodeMain = /* wgsl */ `
|
|
33
34
|
if (globalId.x >= u32(imageSize.x) || globalId.y >= u32(imageSize.y)) { return; }
|
|
34
35
|
let index = globalId.x + globalId.y * u32(imageSize.x);
|
|
35
36
|
let filtered = in_albedo[index];
|
|
36
|
-
let
|
|
37
|
-
let linear = select(
|
|
38
|
-
pow((encoded + 0.055) / 1.055, vec3f(2.4)),
|
|
39
|
-
encoded / 12.92,
|
|
40
|
-
encoded <= vec3f(0.04045)
|
|
41
|
-
);
|
|
37
|
+
let linear = sP(filtered.rgb);
|
|
42
38
|
var result = linear;
|
|
43
|
-
let
|
|
39
|
+
let jj = textureLoad(in_rawAlbedo, vec2i(globalId.xy), 0).a;
|
|
44
40
|
if (preserveSurfaceTexture != 0u) {
|
|
45
41
|
|
|
46
42
|
|
|
47
43
|
|
|
48
|
-
let
|
|
49
|
-
let center = textureLoad(in_rawNormal,
|
|
44
|
+
let pixel = vec2i(globalId.xy);
|
|
45
|
+
let center = textureLoad(in_rawNormal, pixel, 0);
|
|
50
46
|
let n = normalize(center.rgb * 2.0 - 1.0 + vec3f(1e-8));
|
|
51
|
-
var
|
|
47
|
+
var nS = 0.0;
|
|
52
48
|
for (var y = -1; y <= 1; y++) {
|
|
53
49
|
for (var x = -1; x <= 1; x++) {
|
|
54
|
-
let
|
|
55
|
-
clamp(
|
|
56
|
-
let nn = normalize(
|
|
57
|
-
|
|
58
|
-
max(1.0 - dot(n, nn), abs(center.a -
|
|
50
|
+
let vI = textureLoad(in_rawNormal,
|
|
51
|
+
clamp(pixel + vec2i(x, y), vec2i(0), imageSize - 1), 0);
|
|
52
|
+
let nn = normalize(vI.rgb * 2.0 - 1.0 + vec3f(1e-8));
|
|
53
|
+
nS = max(nS,
|
|
54
|
+
max(1.0 - dot(n, nn), abs(center.a - vI.a)));
|
|
59
55
|
}
|
|
60
56
|
}
|
|
61
|
-
let
|
|
62
|
-
let raw = clamp(textureLoad(in_rawAlbedo,
|
|
57
|
+
let wc = smoothstep(0.02, 0.1, nS);
|
|
58
|
+
let raw = clamp(textureLoad(in_rawAlbedo, pixel, 0).rgb,
|
|
63
59
|
vec3f(0.0), vec3f(1.0));
|
|
64
|
-
result = mix(raw, linear,
|
|
60
|
+
result = mix(raw, linear, wc);
|
|
65
61
|
}
|
|
66
|
-
out_albedo[index] = vec4f(result,
|
|
62
|
+
out_albedo[index] = vec4f(result, jj);
|
|
67
63
|
`;
|
|
68
64
|
export const oidnNormalSanitizeMain = /* wgsl */ `
|
|
69
65
|
if (globalId.x >= u32(imageSize.x) || globalId.y >= u32(imageSize.y)) { return; }
|
|
70
66
|
let index = globalId.x + globalId.y * u32(imageSize.x);
|
|
71
|
-
out_normal[index] = vec4f(
|
|
67
|
+
out_normal[index] = vec4f(rG(in_normal[index].rgb), 1.0);
|
|
72
68
|
`;
|
|
73
69
|
function createTimeQuery(device) {
|
|
74
70
|
try {
|
|
75
71
|
const querySet = device.createQuerySet({
|
|
76
72
|
type: 'timestamp',
|
|
77
|
-
count:
|
|
73
|
+
count: 16
|
|
78
74
|
});
|
|
79
75
|
const resolveBuffer = device.createBuffer({
|
|
80
76
|
size: querySet.count * 8,
|
|
@@ -95,17 +91,29 @@ function createTimeQuery(device) {
|
|
|
95
91
|
return undefined;
|
|
96
92
|
}
|
|
97
93
|
}
|
|
98
|
-
function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs) {
|
|
94
|
+
function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs, traceQueue) {
|
|
99
95
|
let sampleRenderedCallback = () => { };
|
|
100
|
-
let
|
|
96
|
+
let batchSamples = false;
|
|
97
|
+
let realtimeBatchBudgetMs = Infinity;
|
|
98
|
+
// Samples traced between display frames skip the resolve and composition;
|
|
99
|
+
// the next presentation or read resolves them once.
|
|
100
|
+
let realtimeDeferPostProcess = false;
|
|
101
|
+
let postProcessPending = false;
|
|
102
|
+
// Resolve uses the configuration that produced these buffers, even if another
|
|
103
|
+
// target has since changed the shared trace pass's caustic settings.
|
|
104
|
+
let sampledOutput;
|
|
101
105
|
let offlineSamplesPerBatch = 0;
|
|
102
106
|
let deferPostProcess = false;
|
|
103
107
|
let sampleSequenceOffset = 0;
|
|
108
|
+
const aov = new WGPUAov(device);
|
|
109
|
+
let aovCamera;
|
|
104
110
|
let sampleCount = 0;
|
|
105
111
|
let elapsedFrameTime = 32;
|
|
106
112
|
let elapsedTileTime;
|
|
107
113
|
let tileTimingGeneration = 0;
|
|
114
|
+
let causticBatchTimeMs = 0, photonBatchTimeMs = 0;
|
|
108
115
|
let lastGpuTraceTiming;
|
|
116
|
+
let displayTrace;
|
|
109
117
|
let diagnosticsReadbackPromise = Promise.resolve();
|
|
110
118
|
let isFirstFrame = true;
|
|
111
119
|
let disposed = false;
|
|
@@ -127,6 +135,8 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
|
|
|
127
135
|
let denoiseValid = false;
|
|
128
136
|
let maxTimePerTile = 21;
|
|
129
137
|
let bloomIntensity = 0;
|
|
138
|
+
// Sample count of this accumulation's last bloom refresh.
|
|
139
|
+
let bloomSamples = 0;
|
|
130
140
|
let bloomThreshold = 1;
|
|
131
141
|
let bloomRadius = 0.6;
|
|
132
142
|
let exposure = 1;
|
|
@@ -139,6 +149,7 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
|
|
|
139
149
|
let hdrOutputRequested = false;
|
|
140
150
|
let hdrOutputActive = false;
|
|
141
151
|
let output = 'final';
|
|
152
|
+
let aovDisplayOptions = DEFAULT_AOV_DISPLAY;
|
|
142
153
|
let shadowCatcherColor = vec3.create();
|
|
143
154
|
let shadowCatcherAlpha = 1;
|
|
144
155
|
let pageLeaveTime = performance.now();
|
|
@@ -227,6 +238,8 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
|
|
|
227
238
|
tileTimingGeneration++;
|
|
228
239
|
tileRenderWithPredict?.needsUpdatePredicting();
|
|
229
240
|
lastGpuTraceTiming = undefined;
|
|
241
|
+
causticBatchTimeMs = 0;
|
|
242
|
+
photonBatchTimeMs = 0;
|
|
230
243
|
// A changed render configuration needs fresh timing. Refresh
|
|
231
244
|
// its estimator without submitting a hidden probe in that mode.
|
|
232
245
|
needsUpdatePredicting = offlineSamplesPerBatch === 0;
|
|
@@ -248,12 +261,14 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
|
|
|
248
261
|
inputs: ['colorTex', 'coverageTex'],
|
|
249
262
|
outputs: ['color'],
|
|
250
263
|
uniforms: [{ label: 'flatBackgroundColor', type: 'vec4f', data: [0, 0, 0, 0] }],
|
|
264
|
+
fsDefine: hdrResolveWGSL,
|
|
251
265
|
fsMain: /* wgsl */ `
|
|
252
266
|
var color = load_colorTex(uv, 0);
|
|
253
267
|
let coverage = clamp(load_coverageTex(uv, 0).a, 0.0, 1.0);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
268
|
+
color = vec4f(
|
|
269
|
+
jx(color.r, coverage, flatBackgroundColor.a > 0.5, true),
|
|
270
|
+
jx(color.g, coverage, flatBackgroundColor.a > 0.5, true),
|
|
271
|
+
jx(color.b, coverage, flatBackgroundColor.a > 0.5, true), color.a);
|
|
257
272
|
output.color = color;
|
|
258
273
|
`
|
|
259
274
|
}));
|
|
@@ -337,7 +352,6 @@ output.color = color;
|
|
|
337
352
|
fsMain: compositeDenoiseDisplayMain,
|
|
338
353
|
fsDefine: linearToSrgbDefine,
|
|
339
354
|
uniforms: [
|
|
340
|
-
{ label: 'hdrOutputEnabled', type: 'f32', data: 0 },
|
|
341
355
|
{ label: 'denoisedAlpha', type: 'f32', data: 0 }
|
|
342
356
|
],
|
|
343
357
|
outputs: ['color'], inputs: ['colorTex', 'composedTex']
|
|
@@ -354,6 +368,7 @@ output.color = color;
|
|
|
354
368
|
inputs: ['albedo'],
|
|
355
369
|
outputs: ['albedo'],
|
|
356
370
|
uniforms: auxiliaryPassUniforms,
|
|
371
|
+
csDefine: oidnAuxiliaryDefine,
|
|
357
372
|
csMain: oidnAlbedoSrgbEncodeMain
|
|
358
373
|
}));
|
|
359
374
|
const oidnAlbedoDecodePass = scratch.get('oidnAlbedoDecodePass', () => new WGPUComputePass('OIDN albedo sRGB decode', device, {
|
|
@@ -362,12 +377,14 @@ output.color = color;
|
|
|
362
377
|
uniforms: [...auxiliaryPassUniforms, {
|
|
363
378
|
label: 'preserveSurfaceTexture', type: 'u32', data: 0
|
|
364
379
|
}],
|
|
380
|
+
csDefine: oidnAuxiliaryDefine,
|
|
365
381
|
csMain: oidnAlbedoSrgbDecodeMain
|
|
366
382
|
}));
|
|
367
383
|
const oidnNormalSanitizePass = scratch.get('oidnNormalSanitizePass', () => new WGPUComputePass('OIDN normal sanitize', device, {
|
|
368
384
|
inputs: ['normal'],
|
|
369
385
|
outputs: ['normal'],
|
|
370
386
|
uniforms: auxiliaryPassUniforms,
|
|
387
|
+
csDefine: oidnAuxiliaryDefine,
|
|
371
388
|
csMain: oidnNormalSanitizeMain
|
|
372
389
|
}));
|
|
373
390
|
oidnAlbedoEncodePass.setOutputParams({ albedo: { channels: 4 } });
|
|
@@ -375,11 +392,11 @@ output.color = color;
|
|
|
375
392
|
oidnNormalSanitizePass.setOutputParams({ normal: { channels: 4 } });
|
|
376
393
|
const outputPass = scratch.get('outputPass', () => new WGPUFullQuadPass('output', device, {
|
|
377
394
|
fsMain: /* wgsl */ `
|
|
378
|
-
let
|
|
395
|
+
let xW = min(
|
|
379
396
|
vec2i(uv2 * vec2f(colorTexRegion())),
|
|
380
397
|
vec2i(colorTexRegion()) - vec2i(1)
|
|
381
398
|
);
|
|
382
|
-
var color = load_colorTex(
|
|
399
|
+
var color = load_colorTex(xW, 0);
|
|
383
400
|
color = vec4(color.rgb * color.a, color.a);
|
|
384
401
|
output.color = color;
|
|
385
402
|
`,
|
|
@@ -412,7 +429,8 @@ output.color = color;
|
|
|
412
429
|
_updateSeed(renderWidth, renderHeight);
|
|
413
430
|
const activeTimeQuery = timeQuery;
|
|
414
431
|
const isUnmapped = activeTimeQuery?.resultBuffer.mapState === 'unmapped';
|
|
415
|
-
rayTracePass.createPass(encoder, clear, tiles, activeTimeQuery ? { querySet: activeTimeQuery.querySet } : undefined);
|
|
432
|
+
const measuredCausticBatch = rayTracePass.createPass(encoder, clear, tiles, activeTimeQuery ? { querySet: activeTimeQuery.querySet } : undefined);
|
|
433
|
+
sampledOutput = rayTracePass.getOutputBuffer();
|
|
416
434
|
if (activeTimeQuery) {
|
|
417
435
|
encoder.resolveQuerySet(activeTimeQuery.querySet, 0, activeTimeQuery.querySet.count, activeTimeQuery.resolveBuffer, 0);
|
|
418
436
|
if (isUnmapped) {
|
|
@@ -428,14 +446,25 @@ output.color = color;
|
|
|
428
446
|
diagnosticsReadbackPromise = activeTimeQuery.resultBuffer
|
|
429
447
|
.mapAsync(GPUMapMode.READ).then(() => {
|
|
430
448
|
const mappedRange = activeTimeQuery.resultBuffer.getMappedRange();
|
|
431
|
-
const times = new BigInt64Array(mappedRange, 0,
|
|
432
|
-
const
|
|
449
|
+
const times = new BigInt64Array(mappedRange, 0, 16);
|
|
450
|
+
const causticTime = (measuredCausticBatch & 1) ? Math.max(Number(times[3] - times[2] + times[5] - times[4]) / 1_000_000, 0) : 0;
|
|
451
|
+
// Independent timestamp pairs avoid Metal's cross-pass counter bug.
|
|
452
|
+
const photonTime = (measuredCausticBatch & 2) ? Math.max(Number(times[7] - times[6] + times[9] - times[8] + times[11] - times[10] + times[13] - times[12] + times[15] - times[14]) / 1_000_000, 0) : 0;
|
|
453
|
+
const ptTime = Math.max(Number(times[1] - times[0]) / 1_000_000, 0);
|
|
433
454
|
// A readback may finish after scene preparation or a mode switch.
|
|
434
455
|
// It must not overwrite throughput learned for the current scene.
|
|
435
456
|
const timingIsCurrent = !disposed && submittedTimingGeneration === tileTimingGeneration &&
|
|
436
457
|
!isFirstFrame;
|
|
437
458
|
if (timingIsCurrent) {
|
|
459
|
+
if (measuredCausticBatch & 1)
|
|
460
|
+
causticBatchTimeMs = causticTime;
|
|
461
|
+
if (measuredCausticBatch & 2)
|
|
462
|
+
photonBatchTimeMs = photonTime;
|
|
463
|
+
const traceTime = Math.max(ptTime + (causticBatchTimeMs + photonBatchTimeMs) / submittedTileCount, .1);
|
|
438
464
|
lastGpuTraceTiming = {
|
|
465
|
+
causticTimeMs: causticBatchTimeMs, photonMappingTimeMs: photonBatchTimeMs,
|
|
466
|
+
photonStagesMs: (measuredCausticBatch & 2) ? [6, 8, 10, 12, 14].map(i => Math.max(Number(times[i + 1] - times[i]) / 1_000_000, 0)) : undefined,
|
|
467
|
+
pathTracingTimeMs: ptTime,
|
|
439
468
|
tileTimeMs: traceTime,
|
|
440
469
|
tileTimePerSampleMs: traceTime,
|
|
441
470
|
estimatedFullFrameTimeMs: traceTime * submittedTileCount,
|
|
@@ -498,7 +527,6 @@ output.color = color;
|
|
|
498
527
|
composePass.setUniform('shadowCatcherAlpha', shadowCatcherAlpha);
|
|
499
528
|
compositeDenoiseDisplayPass.setSize(renderWidth, renderHeight);
|
|
500
529
|
compositeDenoiseDisplayPass.setOutputParams({ color: { format: composeColorFormat } });
|
|
501
|
-
compositeDenoiseDisplayPass.setUniform('hdrOutputEnabled', +hdrOutputActive);
|
|
502
530
|
compositeDenoiseDisplayPass.setUniform('denoisedAlpha', denoiseValid && denoisedDisplayLinear ? +rayTracePass.needsDenoiseAlpha() : 0);
|
|
503
531
|
}
|
|
504
532
|
function snapshotInput(encoder, key, texture, exact = false) {
|
|
@@ -529,6 +557,15 @@ output.color = color;
|
|
|
529
557
|
}
|
|
530
558
|
composePass.setUniform('flatBackgroundColor', resolvedFlatBackground);
|
|
531
559
|
rawOutputPass.setUniform('flatBackgroundColor', resolvedFlatBackground);
|
|
560
|
+
const aovKind = displayAovKind(output);
|
|
561
|
+
if (aovKind && sampleCount === 0) {
|
|
562
|
+
if (!execution?.aovs?.includes(aovKind))
|
|
563
|
+
throw new Error(`AOV ${aovKind} is not enabled`);
|
|
564
|
+
if (!aov.samples)
|
|
565
|
+
return;
|
|
566
|
+
finishPresentation(encoder, aov.visualize(aovKind, aovDisplayOptions, hdrOutputActive));
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
532
569
|
if (resolvedSamples < 1)
|
|
533
570
|
return;
|
|
534
571
|
prepareComposition();
|
|
@@ -536,7 +573,7 @@ output.color = color;
|
|
|
536
573
|
denoisedTexture = prepareDenoisedTexture(encoder, denoisedBuffer, denoisedTexture);
|
|
537
574
|
if (resolve) {
|
|
538
575
|
rayTraceOutputPass.setSampleCount(sampleCount);
|
|
539
|
-
rayTraceOutputPass.createPass(encoder, rayTracePass.getOutputBuffer(), resolvedHasShadowCatcher);
|
|
576
|
+
rayTraceOutputPass.createPass(encoder, sampledOutput ?? rayTracePass.getOutputBuffer(), resolvedHasShadowCatcher);
|
|
540
577
|
}
|
|
541
578
|
composePass.setUniform('shadowCatcherEnabled', +resolvedHasShadowCatcher);
|
|
542
579
|
let foregroundTexture = getFrameInput(resolvedHasShadowCatcher ? 'foreground' : 'color');
|
|
@@ -550,17 +587,18 @@ output.color = color;
|
|
|
550
587
|
}));
|
|
551
588
|
layers.setOutputParams({ foreground: { format: 'rgba32float' }, background: { format: 'rgba32float' } });
|
|
552
589
|
layers.setSize(renderWidth, renderHeight);
|
|
590
|
+
displayTrace?.push('CorrectLayers:SceneLinear');
|
|
553
591
|
layers.createPass(encoder, { originalTex: getFrameInput('color'), filteredTex: denoisedTexture,
|
|
554
592
|
foregroundTex: foregroundTexture, backgroundTex: catcherBackgroundTexture });
|
|
555
593
|
foregroundTexture = layers.getOutput('foreground');
|
|
556
594
|
catcherBackgroundTexture = layers.getOutput('background');
|
|
557
595
|
}
|
|
558
596
|
const bloomEnabled = bloomIntensity > 0.0;
|
|
559
|
-
// Progressive accumulation refreshes bloom every ten samples
|
|
560
|
-
|
|
597
|
+
// Progressive accumulation refreshes bloom after every ten new samples,
|
|
598
|
+
// including when several samples are resolved at once.
|
|
561
599
|
const bloomState = scratch.get('bloom state', () => ({ owner: undefined, settings: '', dispose() { } }));
|
|
562
600
|
const bloomSettings = `${bloomThreshold}/${bloomRadius}/${+(denoiseValid && denoisedHDR)}`;
|
|
563
|
-
const needsUpdateBloom = bloomEnabled && sampleCount >= 10 && (
|
|
601
|
+
const needsUpdateBloom = bloomEnabled && sampleCount >= 10 && (sampleCount - bloomSamples >= 10 || bloomState.owner !== targetKey || bloomState.settings !== bloomSettings);
|
|
564
602
|
let bloomIntensityToUpdate = bloomIntensity;
|
|
565
603
|
if (needsUpdateBloom) {
|
|
566
604
|
if (!bloomPass) {
|
|
@@ -570,14 +608,17 @@ output.color = color;
|
|
|
570
608
|
bloomPass.setSize(renderWidth, renderHeight);
|
|
571
609
|
bloomState.owner = targetKey;
|
|
572
610
|
bloomState.settings = bloomSettings;
|
|
611
|
+
bloomSamples = sampleCount;
|
|
573
612
|
bloomPass.setBrightThreshold(bloomThreshold);
|
|
574
613
|
bloomPass.setRadius(bloomRadius);
|
|
614
|
+
displayTrace?.push('Bloom:SceneLinear');
|
|
575
615
|
bloomPass.createPass(encoder, colorTexture);
|
|
576
616
|
}
|
|
577
617
|
else if (bloomEnabled && sampleCount < 10) {
|
|
578
618
|
bloomIntensityToUpdate = 0;
|
|
579
619
|
}
|
|
580
620
|
composePass.setUniform('bloomIntensity', bloomIntensityToUpdate);
|
|
621
|
+
displayTrace?.push('Compose:DisplayLinear+DisplayEncoded');
|
|
581
622
|
composePass.createPass(encoder, {
|
|
582
623
|
colorTex: colorTexture,
|
|
583
624
|
foregroundTex: foregroundTexture,
|
|
@@ -588,6 +629,7 @@ output.color = color;
|
|
|
588
629
|
bloomTex: bloomEnabled && bloomPass ? bloomPass.getOutput() : colorTexture
|
|
589
630
|
});
|
|
590
631
|
if (denoiseValid && !denoisedHDR && denoisedDisplayLinear && denoisedTexture) {
|
|
632
|
+
displayTrace?.push('Encode:DisplayEncoded');
|
|
591
633
|
compositeDenoiseDisplayPass.createPass(encoder, {
|
|
592
634
|
colorTex: denoisedTexture,
|
|
593
635
|
composedTex: composePass.getOutput('denoiseColor')
|
|
@@ -596,14 +638,24 @@ output.color = color;
|
|
|
596
638
|
let displayTexture = (denoiseValid && denoisedBuffer ? (denoisedHDR ? composePass.getOutput('color') : denoisedDisplayLinear
|
|
597
639
|
? compositeDenoiseDisplayPass.getOutput('color') : denoisedTexture) : undefined) ||
|
|
598
640
|
composePass.getOutput('color');
|
|
641
|
+
if (aovKind) {
|
|
642
|
+
if (!execution?.aovs?.includes(aovKind))
|
|
643
|
+
throw new Error(`AOV ${aovKind} is not enabled`);
|
|
644
|
+
displayTexture = aov.visualize(aovKind, aovDisplayOptions, hdrOutputActive);
|
|
645
|
+
}
|
|
646
|
+
finishPresentation(encoder, displayTexture);
|
|
647
|
+
}
|
|
648
|
+
function finishPresentation(encoder, displayTexture) {
|
|
599
649
|
const activeHDRPeakMeter = hdrOutputActive
|
|
600
650
|
? (hdrPeakMeter ??= scratch.get('hdrPeak', () => new WGPUHDRPeakMeter(device)))
|
|
601
651
|
: undefined;
|
|
602
652
|
const hdrPeakReadbackSubmitted = activeHDRPeakMeter?.encode(encoder, displayTexture, renderWidth, renderHeight) ?? false;
|
|
603
653
|
if (output === 'normal' || output === 'albedo') {
|
|
654
|
+
displayTrace?.push('AOV:Raw');
|
|
604
655
|
displayTexture = getFrameInput(output);
|
|
605
656
|
}
|
|
606
657
|
else if (output === 'shadowCatcher') {
|
|
658
|
+
displayTrace?.push('AOV:Raw');
|
|
607
659
|
displayTexture = getFrameInput('shadowCatcher');
|
|
608
660
|
}
|
|
609
661
|
if (displayTexture.width < renderWidth || displayTexture.height < renderHeight) {
|
|
@@ -632,36 +684,46 @@ output.color = color;
|
|
|
632
684
|
void activeHDRPeakMeter?.resolve();
|
|
633
685
|
}
|
|
634
686
|
}
|
|
687
|
+
function flushPostProcess() {
|
|
688
|
+
if (!postProcessPending)
|
|
689
|
+
return;
|
|
690
|
+
postProcessPending = false;
|
|
691
|
+
drawPostProcess(device.createCommandEncoder(), false, true);
|
|
692
|
+
}
|
|
635
693
|
function trace(camera, maxSamples) {
|
|
694
|
+
applyTraceQuality();
|
|
636
695
|
// A call to draw means accumulation has been invalidated. Cancel OIDN
|
|
637
696
|
// before checking shader compilation: pipeline-affecting parameter changes
|
|
638
697
|
// otherwise leave the previous asynchronous denoise alive while resources
|
|
639
698
|
// and bind groups are being replaced.
|
|
640
699
|
cancelDenoise();
|
|
641
|
-
if (rayTracePass.isCompilingShader()) {
|
|
642
|
-
isFirstFrame = true;
|
|
643
|
-
sampleCount = 0;
|
|
644
|
-
return true;
|
|
645
|
-
}
|
|
646
700
|
// Update the camera before compiling and sampling.
|
|
647
701
|
rayTracePass.setCamera(camera);
|
|
702
|
+
aovCamera = camera;
|
|
703
|
+
rayTracePass.updatePipeline();
|
|
704
|
+
const pipelineError = rayTracePass.getPipelineError();
|
|
705
|
+
if (pipelineError)
|
|
706
|
+
throw pipelineError;
|
|
707
|
+
// Waiting for a shader is not an input change: this render's samples and
|
|
708
|
+
// complete image stay valid, and only Render's restart discards them.
|
|
709
|
+
if (rayTracePass.isCompilingShader() || !rayTracePass.isPipelineReady())
|
|
710
|
+
return true;
|
|
711
|
+
if (execution?.aovs?.length && !rayTracePass.prepareAovs(execution.aovs))
|
|
712
|
+
return true;
|
|
648
713
|
const resetAccumulation = isFirstFrame;
|
|
714
|
+
if (resetAccumulation)
|
|
715
|
+
aov.reset();
|
|
649
716
|
if (resetAccumulation) {
|
|
717
|
+
postProcessPending = false;
|
|
718
|
+
bloomSamples = 0;
|
|
650
719
|
denoiseValid = false;
|
|
651
720
|
tileTimingGeneration++;
|
|
652
721
|
elapsedTileTime = undefined;
|
|
653
|
-
rayTracePass.setCamera(camera);
|
|
654
722
|
(tileRenderWithPredict || tileRender).reset();
|
|
655
723
|
// Reset
|
|
656
724
|
isFirstFrame = false;
|
|
657
725
|
sampleCount = 0;
|
|
658
726
|
}
|
|
659
|
-
rayTracePass.updatePipeline();
|
|
660
|
-
if (rayTracePass.isCompilingShader() || !rayTracePass.isPipelineReady()) {
|
|
661
|
-
isFirstFrame = true;
|
|
662
|
-
sampleCount = 0;
|
|
663
|
-
return true;
|
|
664
|
-
}
|
|
665
727
|
// Keep the last completed denoise visible while a static while-converging batch
|
|
666
728
|
// accumulates, including the incomplete first sample after a scene edit.
|
|
667
729
|
if (!preserveDenoisedOutput || isFirstFrame) {
|
|
@@ -687,16 +749,32 @@ output.color = color;
|
|
|
687
749
|
needsUpdatePredicting = false;
|
|
688
750
|
}
|
|
689
751
|
const frameSampleCount = sampleCount;
|
|
752
|
+
const sampleTimeMs = lastGpuTraceTiming?.estimatedFullFrameTimeMs;
|
|
753
|
+
const realtime = offlineSamplesPerBatch === 0 && batchSamples;
|
|
754
|
+
const realtimeBudget = Math.min(maxTimePerTile, realtimeBatchBudgetMs);
|
|
755
|
+
if (realtime && !resetAccumulation && !isPredictingFrame && sampleTimeMs !== undefined &&
|
|
756
|
+
traceQueue.available(realtimeBudget) < Math.min(sampleTimeMs, realtimeBudget))
|
|
757
|
+
return false;
|
|
758
|
+
// Only batch a measured, unchanged full-frame workload. New cameras get
|
|
759
|
+
// their first sample immediately; expensive samples retain tiled execution.
|
|
760
|
+
const realtimeBatch = realtime && sampleCount > 0 &&
|
|
761
|
+
!resetAccumulation && !isPredictingFrame && lastGpuTraceTiming?.tileCount === 1 && sampleTimeMs !== undefined &&
|
|
762
|
+
sampleTimeMs <= realtimeBudget / 2;
|
|
763
|
+
const realtimeSamples = realtimeBatch
|
|
764
|
+
? Math.min(64, Math.floor(traceQueue.available(realtimeBudget) / sampleTimeMs)) : 1;
|
|
765
|
+
if (realtimeBatch && realtimeSamples === 0)
|
|
766
|
+
return false;
|
|
767
|
+
const batchStarted = performance.now();
|
|
690
768
|
_startRecordFrameTime(!resetAccumulation);
|
|
691
769
|
const renderSampleTarget = maxSamples;
|
|
692
|
-
const batchTarget = Math.min(renderSampleTarget, sampleCount +
|
|
770
|
+
const batchTarget = Math.min(renderSampleTarget, sampleCount + (offlineSamplesPerBatch > 0 ? offlineSamplesPerBatch : realtimeSamples));
|
|
693
771
|
do {
|
|
694
772
|
let { xIndex, yIndex, columns, rows, isFirstTile, isLastTile, samplesPerFrame } = (tileRenderWithPredict || tileRender).nextTile(elapsedTileTime);
|
|
695
773
|
rayTraceOutputPass.setSampleTileGrid(columns, rows);
|
|
696
|
-
if (offlineSamplesPerBatch > 0 && columns * rows === 1) {
|
|
774
|
+
if ((offlineSamplesPerBatch > 0 || realtimeBatch) && columns * rows === 1) {
|
|
697
775
|
samplesPerFrame = batchTarget - sampleCount;
|
|
698
776
|
}
|
|
699
|
-
else if (!
|
|
777
|
+
else if (!batchSamples) {
|
|
700
778
|
samplesPerFrame = 1;
|
|
701
779
|
}
|
|
702
780
|
if (columns * rows === 1) {
|
|
@@ -708,11 +786,21 @@ output.color = color;
|
|
|
708
786
|
sample(sampleCount === 0, [1, 1]);
|
|
709
787
|
sampleCount++;
|
|
710
788
|
samplesSubmitted++;
|
|
789
|
+
if (realtime && !isPredictingFrame && sampleTimeMs !== undefined)
|
|
790
|
+
traceQueue.track(sampleTimeMs);
|
|
791
|
+
if (realtimeBatch) {
|
|
792
|
+
// Encoding many tiny samples must also leave the main thread free
|
|
793
|
+
// to receive camera input. Yield before encoding another batch.
|
|
794
|
+
if (performance.now() - batchStarted >= 4)
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
711
797
|
}
|
|
712
798
|
}
|
|
713
799
|
else {
|
|
714
800
|
rayTracePass.setSampleTiles(columns, rows, xIndex, yIndex);
|
|
715
801
|
sample(sampleCount === 0 && isFirstTile, [columns, rows]);
|
|
802
|
+
if (realtime && !isPredictingFrame && sampleTimeMs !== undefined)
|
|
803
|
+
traceQueue.track(sampleTimeMs / (columns * rows));
|
|
716
804
|
if (isLastTile)
|
|
717
805
|
sampleCount++;
|
|
718
806
|
}
|
|
@@ -727,7 +815,14 @@ output.color = color;
|
|
|
727
815
|
sampleCount = 0;
|
|
728
816
|
return false;
|
|
729
817
|
}
|
|
730
|
-
if (sampleCount !== frameSampleCount &&
|
|
818
|
+
if (sampleCount !== frameSampleCount && execution?.aovs?.length) {
|
|
819
|
+
rayTracePass.renderAovs(aov, camera, sampleCount, execution.aovSamples ?? 16, execution.aovs);
|
|
820
|
+
}
|
|
821
|
+
if (sampleCount !== frameSampleCount && realtime && realtimeDeferPostProcess && sampleCount < renderSampleTarget) {
|
|
822
|
+
postProcessPending = true;
|
|
823
|
+
}
|
|
824
|
+
else if (sampleCount !== frameSampleCount && (!deferPostProcess || sampleCount >= renderSampleTarget)) {
|
|
825
|
+
postProcessPending = false;
|
|
731
826
|
const encoder = device.createCommandEncoder();
|
|
732
827
|
drawPostProcess(encoder, sampleCount >= renderSampleTarget, true);
|
|
733
828
|
}
|
|
@@ -759,6 +854,7 @@ output.color = color;
|
|
|
759
854
|
// The target retains its complete presentation texture through the resize.
|
|
760
855
|
clearDenoisedOutput();
|
|
761
856
|
tileTimingGeneration++;
|
|
857
|
+
sampledOutput = undefined;
|
|
762
858
|
renderWidth = nextRenderWidth;
|
|
763
859
|
renderHeight = nextRenderHeight;
|
|
764
860
|
(tileRenderWithPredict || tileRender).setSize(renderWidth, renderHeight);
|
|
@@ -856,7 +952,6 @@ output.color = color;
|
|
|
856
952
|
hdrPeakMeter?.reset();
|
|
857
953
|
}
|
|
858
954
|
compositeDenoiseDisplayPass.setOutputParams({ color: { format: composeColorFormat } });
|
|
859
|
-
compositeDenoiseDisplayPass.setUniform('hdrOutputEnabled', hdrOutputActive ? 1 : 0);
|
|
860
955
|
composePass.setUniform('hdrOutputEnabled', hdrOutputActive ? 1 : 0);
|
|
861
956
|
return wasActive !== hdrOutputActive;
|
|
862
957
|
}
|
|
@@ -893,6 +988,7 @@ output.color = color;
|
|
|
893
988
|
jnlmPass ??= scratch.get('jnlm', () => new WGPUJNLMDenoisePass(device));
|
|
894
989
|
const rayBuffers = rayTracePass.getOutputBuffer();
|
|
895
990
|
const encoder = device.createCommandEncoder({ label: 'JNLM denoise' });
|
|
991
|
+
displayTrace?.push('Denoise:DisplayLinear');
|
|
896
992
|
const output = jnlmPass.encode(encoder, {
|
|
897
993
|
width: renderWidth,
|
|
898
994
|
height: renderHeight,
|
|
@@ -917,7 +1013,7 @@ output.color = color;
|
|
|
917
1013
|
return completed;
|
|
918
1014
|
});
|
|
919
1015
|
}
|
|
920
|
-
function performCustomDenoise(denoiser, schedule, signal) {
|
|
1016
|
+
function performCustomDenoise(denoiser, schedule, signal, requestedAovs = []) {
|
|
921
1017
|
const generation = denoiseGeneration;
|
|
922
1018
|
const controller = activeCustomController = new AbortController();
|
|
923
1019
|
const abort = () => controller.abort();
|
|
@@ -932,7 +1028,15 @@ output.color = color;
|
|
|
932
1028
|
const albedo = copyGuide('Custom albedo', getFrameInput('albedo'), true);
|
|
933
1029
|
const normal = copyGuide('Custom normal', getFrameInput('normal'), true);
|
|
934
1030
|
const output = scratch.get('Custom output', () => new WGPUScratchBuffer(device)).get(width * height * 16, true);
|
|
935
|
-
|
|
1031
|
+
const aovs = requestedAovs.length ? aov.snapshot(requestedAovs) : undefined;
|
|
1032
|
+
displayTrace?.push('Denoise:SceneLinear');
|
|
1033
|
+
try {
|
|
1034
|
+
await denoiser.denoise({ device, width, height, color, albedo, normal, output, aovs }, { signal: controller.signal, schedule });
|
|
1035
|
+
}
|
|
1036
|
+
finally {
|
|
1037
|
+
if (aovs)
|
|
1038
|
+
void device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => aov.releaseSnapshot(aovs));
|
|
1039
|
+
}
|
|
936
1040
|
if (controller.signal.aborted || disposed || generation !== denoiseGeneration)
|
|
937
1041
|
return false;
|
|
938
1042
|
const coverage = scratch.get('custom coverage', () => new WGPUComputePass('Custom coverage', device, {
|
|
@@ -965,8 +1069,11 @@ output.color = color;
|
|
|
965
1069
|
cancelDenoise();
|
|
966
1070
|
if (isFirstFrame || sampleCount < 1)
|
|
967
1071
|
return Promise.resolve(false);
|
|
1072
|
+
if (output !== 'final' && output !== 'shadow')
|
|
1073
|
+
return Promise.resolve(true);
|
|
1074
|
+
flushPostProcess();
|
|
968
1075
|
if (attachedDenoiser.kind === 'custom')
|
|
969
|
-
return performCustomDenoise(attachedDenoiser.denoiser, denoiseSchedule, signal);
|
|
1076
|
+
return performCustomDenoise(attachedDenoiser.denoiser, denoiseSchedule, signal, attachedDenoiser.aovs);
|
|
970
1077
|
denoisedHDR = false;
|
|
971
1078
|
if (attachedDenoiser.kind === 'jnlm')
|
|
972
1079
|
return performJNLMDenoise(attachedDenoiser.denoiser);
|
|
@@ -991,7 +1098,7 @@ output.color = color;
|
|
|
991
1098
|
wholeImage: denoiseSchedule === 'every-sample'
|
|
992
1099
|
} : {}),
|
|
993
1100
|
// A preview frame is one whole-image pass. Settled images can take many
|
|
994
|
-
// tiles; oidn-
|
|
1101
|
+
// tiles; oidn-webgpu runs those back to back by default, which starves
|
|
995
1102
|
// the page at 4K, so pace them to display frames instead.
|
|
996
1103
|
scheduling: denoiseSchedule === 'every-sample' ? 'event-loop' : 'animation-frame'
|
|
997
1104
|
};
|
|
@@ -1081,6 +1188,7 @@ output.color = color;
|
|
|
1081
1188
|
return Promise.resolve();
|
|
1082
1189
|
// Snapshot the complete raw composition; never feed a previous denoise
|
|
1083
1190
|
// back into the network during progressive updates.
|
|
1191
|
+
displayTrace?.push('Denoise:DisplayLinear');
|
|
1084
1192
|
return runOIDNPhase(generation, (finish, fail) => denoiser.tileExecute({
|
|
1085
1193
|
...convergingTileOptions,
|
|
1086
1194
|
color: { data: colorInput, ...size },
|
|
@@ -1189,35 +1297,59 @@ output.color = color;
|
|
|
1189
1297
|
diagnosticsReadbackPromise
|
|
1190
1298
|
]).then(() => {
|
|
1191
1299
|
rayTracePass.releaseTarget(targetKey);
|
|
1300
|
+
aov.dispose();
|
|
1192
1301
|
denoisedBuffer?.destroy();
|
|
1193
1302
|
presentationTexture?.destroy();
|
|
1194
1303
|
displayPostProcess.dispose();
|
|
1195
1304
|
rayTraceOutputPass.dispose();
|
|
1196
1305
|
});
|
|
1197
1306
|
}
|
|
1307
|
+
// Keep tracing quality out of presentation: an old fallback must not
|
|
1308
|
+
// invalidate a new caustic pipeline while it is compiling.
|
|
1309
|
+
function applyTraceQuality() {
|
|
1310
|
+
if (execution) {
|
|
1311
|
+
rayTracePass.setQuality(execution);
|
|
1312
|
+
rayTracePass.setBevelSamples(execution.bevelSamples);
|
|
1313
|
+
rayTracePass.setAlphaBlendStrategy(execution.alphaBlendStrategy);
|
|
1314
|
+
rayTracePass.setSamplingPattern(execution.samplingPattern, execution.maxSamples);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1198
1317
|
function activate() {
|
|
1199
1318
|
rayTracePass.useTarget(targetKey);
|
|
1200
1319
|
if (renderWidth && renderHeight)
|
|
1201
1320
|
rayTracePass.setSize(renderWidth, renderHeight, screenWidth / screenHeight);
|
|
1202
1321
|
if (execution) {
|
|
1203
|
-
rayTracePass.setQuality(execution);
|
|
1204
1322
|
rayTracePass.setClamping(execution.clamping);
|
|
1205
1323
|
rayTracePass.setTransmissiveOutputAlphaMin(execution.transmissiveOutputAlphaMin);
|
|
1206
|
-
rayTracePass.setBevelSamples(execution.bevelSamples);
|
|
1207
|
-
rayTracePass.setAlphaBlendStrategy(execution.alphaBlendStrategy);
|
|
1208
|
-
rayTracePass.setSamplingPattern(execution.samplingPattern, execution.maxSamples);
|
|
1209
1324
|
}
|
|
1210
1325
|
}
|
|
1211
1326
|
return {
|
|
1212
1327
|
invalidateTiming: invalidateTilePrediction,
|
|
1213
1328
|
invalidateDenoisedOutput() { cancelDenoise(); denoiseValid = false; preserveDenoisedOutput = false; },
|
|
1214
1329
|
configure(settings) {
|
|
1215
|
-
const timingKeys = ['bounces', 'bevel', 'bevelSamples', 'directLightCandidates', 'dispersionWavelengths', 'alphaBlendStrategy', 'samplingPattern', 'clamping', 'transmissiveOutputAlphaMin'];
|
|
1330
|
+
const timingKeys = ['bounces', 'bevel', 'bevelSamples', 'directLightCandidates', 'dispersionWavelengths', 'alphaBlendStrategy', 'samplingPattern', 'clamping', 'transmissiveOutputAlphaMin', 'caustics'];
|
|
1216
1331
|
if (!execution || timingKeys.some(key => execution[key] !== settings[key]))
|
|
1217
1332
|
invalidateTilePrediction();
|
|
1218
|
-
|
|
1333
|
+
if (settings.aovs?.length && (!Number.isInteger(settings.aovSamples ?? 16) || (settings.aovSamples ?? 16) < 1))
|
|
1334
|
+
throw new RangeError('aovSamples must be a positive integer');
|
|
1335
|
+
const previousMask = aovMask(execution?.aovs ?? []), nextMask = aovMask(settings.aovs ?? []);
|
|
1336
|
+
if (previousMask !== nextMask || execution?.aovSamples !== settings.aovSamples)
|
|
1337
|
+
aov.samples = 0;
|
|
1338
|
+
execution = { ...settings, aovs: [...(settings.aovs ?? [])] };
|
|
1339
|
+
// Presentation may still name the previous preview's AOV. Drop that
|
|
1340
|
+
// selection before tracing with a smaller set; Display validates and
|
|
1341
|
+
// reapplies the current channel when the new image is presented.
|
|
1342
|
+
const displayedAov = displayAovKind(output);
|
|
1343
|
+
if (displayedAov && !settings.aovs?.includes(displayedAov))
|
|
1344
|
+
output = 'final';
|
|
1345
|
+
if (previousMask && !nextMask) {
|
|
1346
|
+
aov.dispose();
|
|
1347
|
+
aov.history.clear();
|
|
1348
|
+
aov.width = aov.height = 0;
|
|
1349
|
+
aov.reset();
|
|
1350
|
+
}
|
|
1219
1351
|
maxTimePerTile = Math.max(1, settings.timeBudgetMs);
|
|
1220
|
-
|
|
1352
|
+
batchSamples = settings.batchSamples;
|
|
1221
1353
|
tileRender.setDesiredMsPerTile(maxTimePerTile);
|
|
1222
1354
|
tileRender.setMaxTiles(settings.maxTiles);
|
|
1223
1355
|
tileRenderWithPredict?.setDesiredMsPerTile(maxTimePerTile);
|
|
@@ -1228,6 +1360,11 @@ output.color = color;
|
|
|
1228
1360
|
canCompleteSampleWithin(timeBudgetMs) {
|
|
1229
1361
|
return (lastGpuTraceTiming?.estimatedFullFrameTimeMs ?? elapsedFrameTime) <= timeBudgetMs;
|
|
1230
1362
|
},
|
|
1363
|
+
setRealtimeBatchBudget(milliseconds) { realtimeBatchBudgetMs = milliseconds; },
|
|
1364
|
+
setRealtimeDeferPostProcess(defer) { realtimeDeferPostProcess = defer; },
|
|
1365
|
+
getRealtimeSampleTime() { return lastGpuTraceTiming?.estimatedFullFrameTimeMs; },
|
|
1366
|
+
getRealtimeTileTime() { return lastGpuTraceTiming?.tileTimePerSampleMs; },
|
|
1367
|
+
whenTraceAvailable() { return traceQueue.whenAvailable(); },
|
|
1231
1368
|
get presentationComplete() { return !!presentationTexture; },
|
|
1232
1369
|
get presentationDenoised() { return presentationDenoised; },
|
|
1233
1370
|
present() {
|
|
@@ -1242,13 +1379,14 @@ output.color = color;
|
|
|
1242
1379
|
getMemory() {
|
|
1243
1380
|
return {
|
|
1244
1381
|
width: renderWidth, height: renderHeight,
|
|
1245
|
-
bytes: rayTracePass.getTargetMemoryBytes(targetKey) + rayTraceOutputPass.getMemoryBytes() + textureBytes(presentationTexture) + displayPostProcess.getMemoryBytes() + (denoisedBuffer?.size ?? 0)
|
|
1382
|
+
bytes: aov.bytes + rayTracePass.getTargetMemoryBytes(targetKey) + rayTraceOutputPass.getMemoryBytes() + textureBytes(presentationTexture) + displayPostProcess.getMemoryBytes() + (denoisedBuffer?.size ?? 0)
|
|
1246
1383
|
};
|
|
1247
1384
|
},
|
|
1248
1385
|
isFirstFrame() {
|
|
1249
1386
|
return isFirstFrame;
|
|
1250
1387
|
},
|
|
1251
1388
|
restartSamples() {
|
|
1389
|
+
aov.reset();
|
|
1252
1390
|
// Input edits reset accumulation, not learned throughput. Re-arming a
|
|
1253
1391
|
// hidden probe here starves continuously changing scenes of visible samples.
|
|
1254
1392
|
tileTimingGeneration++;
|
|
@@ -1257,16 +1395,17 @@ output.color = color;
|
|
|
1257
1395
|
denoiseValid = false;
|
|
1258
1396
|
presentationDenoised = false;
|
|
1259
1397
|
resolvedSamples = 0;
|
|
1398
|
+
postProcessPending = false;
|
|
1399
|
+
bloomSamples = 0;
|
|
1260
1400
|
(tileRenderWithPredict || tileRender).reset();
|
|
1261
1401
|
isPredictingFrame = false;
|
|
1262
1402
|
isFirstFrame = true;
|
|
1263
1403
|
sampleCount = 0;
|
|
1264
1404
|
},
|
|
1265
1405
|
getOutputTexture(kind) {
|
|
1266
|
-
|
|
1267
|
-
return;
|
|
1406
|
+
flushPostProcess();
|
|
1268
1407
|
if (kind === 'hdr')
|
|
1269
|
-
return getFrameInput('color');
|
|
1408
|
+
return resolvedSamples > 0 ? getFrameInput('color') : undefined;
|
|
1270
1409
|
return displayPostProcess.output ?? presentationTexture;
|
|
1271
1410
|
},
|
|
1272
1411
|
applyPostProcesses(passes, render) {
|
|
@@ -1275,8 +1414,9 @@ output.color = color;
|
|
|
1275
1414
|
},
|
|
1276
1415
|
trace,
|
|
1277
1416
|
drawPostProcess() {
|
|
1278
|
-
const
|
|
1279
|
-
|
|
1417
|
+
const resolve = postProcessPending;
|
|
1418
|
+
postProcessPending = false;
|
|
1419
|
+
drawPostProcess(device.createCommandEncoder(), true, resolve);
|
|
1280
1420
|
},
|
|
1281
1421
|
performDenoise,
|
|
1282
1422
|
cancelDenoise,
|
|
@@ -1291,9 +1431,11 @@ output.color = color;
|
|
|
1291
1431
|
const bytesPerRow = Math.ceil(width * 16 / 256) * 256;
|
|
1292
1432
|
const buffer = device.createBuffer({ size: bytesPerRow * height, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ });
|
|
1293
1433
|
const encoder = device.createCommandEncoder();
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1434
|
+
const presentationReadback = hdrOutputActive && displayAovKind(output) ? scratch.get('AOV encoded readback', () => new WGPUFullQuadPass('AOV encoded readback', device, { textureWillBeRead: true, inputs: ['inputTex'], outputs: ['color'], fsMain: `let c=load_inputTex(uv,0);let rgb=select(1.055*pow(max(c.rgb,vec3f(0.0)),vec3f(1.0/2.4))-0.055,12.92*c.rgb,c.rgb<=vec3f(0.0031308));output.color=vec4f(rgb,c.a);` })) : readbackPass;
|
|
1435
|
+
presentationReadback.setOutputParams({ color: { format: 'rgba32float' } });
|
|
1436
|
+
presentationReadback.setSize(width, height);
|
|
1437
|
+
presentationReadback.createPass(encoder, { inputTex: image });
|
|
1438
|
+
encoder.copyTextureToBuffer({ texture: presentationReadback.getOutput('color') }, { buffer, bytesPerRow }, { width, height });
|
|
1297
1439
|
device.queue.submit([encoder.finish()]);
|
|
1298
1440
|
try {
|
|
1299
1441
|
await buffer.mapAsync(GPUMapMode.READ);
|
|
@@ -1308,7 +1450,46 @@ output.color = color;
|
|
|
1308
1450
|
buffer.destroy();
|
|
1309
1451
|
}
|
|
1310
1452
|
},
|
|
1453
|
+
aovReady(kind) { return !!execution?.aovs?.includes(kind) && aov.samples > 0; },
|
|
1454
|
+
getAovSamples() { return aov.samples; },
|
|
1455
|
+
restartAovs() { aov.reset(); },
|
|
1456
|
+
refineAovs(camera, samples = sampleCount) {
|
|
1457
|
+
if (samples < 1 || !execution?.aovs?.length)
|
|
1458
|
+
return true;
|
|
1459
|
+
applyTraceQuality();
|
|
1460
|
+
rayTracePass.setCamera(camera);
|
|
1461
|
+
aovCamera = camera;
|
|
1462
|
+
rayTracePass.updatePipeline();
|
|
1463
|
+
const pipelineError = rayTracePass.getPipelineError();
|
|
1464
|
+
if (pipelineError)
|
|
1465
|
+
throw pipelineError;
|
|
1466
|
+
if (rayTracePass.isCompilingShader() || !rayTracePass.isPipelineReady())
|
|
1467
|
+
return false;
|
|
1468
|
+
return rayTracePass.renderAovs(aov, camera, samples, execution.aovSamples ?? 16, execution.aovs);
|
|
1469
|
+
},
|
|
1470
|
+
async readAov(kind) {
|
|
1471
|
+
if (!execution?.aovs?.includes(kind) || !aovCamera || (sampleCount < 1 && aov.samples < 1))
|
|
1472
|
+
throw new Error('AOV output is not ready');
|
|
1473
|
+
for (;;) {
|
|
1474
|
+
if (disposed)
|
|
1475
|
+
throw new Error('AOV compilation was interrupted');
|
|
1476
|
+
activate();
|
|
1477
|
+
applyTraceQuality();
|
|
1478
|
+
rayTracePass.setCamera(aovCamera);
|
|
1479
|
+
rayTracePass.updatePipeline();
|
|
1480
|
+
const pipelineError = rayTracePass.getPipelineError();
|
|
1481
|
+
if (pipelineError)
|
|
1482
|
+
throw pipelineError;
|
|
1483
|
+
if (!rayTracePass.isCompilingShader() && rayTracePass.isPipelineReady() &&
|
|
1484
|
+
rayTracePass.renderAovs(aov, aovCamera, Math.max(sampleCount, aov.samples), execution.aovSamples ?? 16, execution.aovs))
|
|
1485
|
+
break;
|
|
1486
|
+
// Display frames stop on a hidden page, but compilation still completes.
|
|
1487
|
+
await new Promise(resolve => setTimeout(resolve, 16));
|
|
1488
|
+
}
|
|
1489
|
+
return aov.read(kind);
|
|
1490
|
+
},
|
|
1311
1491
|
async readOutput(kind) {
|
|
1492
|
+
flushPostProcess();
|
|
1312
1493
|
rawOutputPass.setUniform('flatBackgroundColor', resolvedFlatBackground);
|
|
1313
1494
|
const width = renderWidth, height = renderHeight;
|
|
1314
1495
|
const bytesPerRow = Math.ceil(width * 16 / 256) * 256;
|
|
@@ -1377,6 +1558,38 @@ output.color = color;
|
|
|
1377
1558
|
getTotalSamplesRendered() {
|
|
1378
1559
|
return sampleCount;
|
|
1379
1560
|
},
|
|
1561
|
+
/** @internal */
|
|
1562
|
+
_displayParity() {
|
|
1563
|
+
return {
|
|
1564
|
+
record(trace) { displayTrace = trace; },
|
|
1565
|
+
load(input) {
|
|
1566
|
+
cancelDenoise();
|
|
1567
|
+
clearDenoisedOutput();
|
|
1568
|
+
setSize(input.width, input.height);
|
|
1569
|
+
rayTracePass.useTarget(targetKey);
|
|
1570
|
+
rayTracePass.setSize(renderWidth, renderHeight, screenWidth / screenHeight);
|
|
1571
|
+
const buffers = sampledOutput = rayTracePass.getOutputBuffer();
|
|
1572
|
+
const shadow = new Float32Array(input.width * input.height * 12);
|
|
1573
|
+
for (let i = 0; i < input.width * input.height; i++) {
|
|
1574
|
+
shadow.set(input.shadow.subarray(i * 8, i * 8 + 8), i * 12);
|
|
1575
|
+
shadow.set(input.moments.subarray(i * 4, i * 4 + 4), i * 12 + 8);
|
|
1576
|
+
}
|
|
1577
|
+
for (const [buffer, data] of [[buffers.color, input.color], [buffers.albedo, input.albedo],
|
|
1578
|
+
[buffers.normal, input.normal], [buffers.shadowCatcher, shadow]])
|
|
1579
|
+
device.queue.writeBuffer(buffer, 0, data);
|
|
1580
|
+
sampleCount = resolvedSamples = input.samples;
|
|
1581
|
+
resolvedHasShadowCatcher = input.catcher;
|
|
1582
|
+
isFirstFrame = false;
|
|
1583
|
+
postProcessPending = false;
|
|
1584
|
+
bloomSamples = 0;
|
|
1585
|
+
rayTraceOutputPass.setSampleCount(sampleCount);
|
|
1586
|
+
rayTraceOutputPass.setSampleTileGrid(1, 1);
|
|
1587
|
+
const encoder = device.createCommandEncoder();
|
|
1588
|
+
rayTraceOutputPass.createPass(encoder, buffers, resolvedHasShadowCatcher);
|
|
1589
|
+
device.queue.submit([encoder.finish()]);
|
|
1590
|
+
}
|
|
1591
|
+
};
|
|
1592
|
+
},
|
|
1380
1593
|
getDiagnostics() {
|
|
1381
1594
|
return {
|
|
1382
1595
|
...rayTracePass.getDiagnostics(),
|
|
@@ -1421,6 +1634,7 @@ output.color = color;
|
|
|
1421
1634
|
setOnSampleRendered(cb) {
|
|
1422
1635
|
sampleRenderedCallback = cb;
|
|
1423
1636
|
},
|
|
1637
|
+
setAovDisplayOptions(options) { aovDisplayOptions = { ...options, depthRange: [...options.depthRange] }; },
|
|
1424
1638
|
setOutput(nextOutput) {
|
|
1425
1639
|
if (output === nextOutput)
|
|
1426
1640
|
return false;
|
|
@@ -1432,7 +1646,8 @@ output.color = color;
|
|
|
1432
1646
|
}
|
|
1433
1647
|
/** Independent render targets, without preview or presentation policy. */
|
|
1434
1648
|
export function makeWGPURenderTargets(canvas, device, options = {}) {
|
|
1435
|
-
const rayTracePass = new WGPURayTracePass(device);
|
|
1649
|
+
const rayTracePass = new WGPURayTracePass(device, options.materialTextures);
|
|
1650
|
+
const traceQueue = new GPUTraceQueue(device.queue);
|
|
1436
1651
|
const customJobs = new Set();
|
|
1437
1652
|
const scratch = new ScratchPool(work => {
|
|
1438
1653
|
// A cancelled custom filter can keep submitting GPU work until its promise settles.
|
|
@@ -1443,7 +1658,7 @@ export function makeWGPURenderTargets(canvas, device, options = {}) {
|
|
|
1443
1658
|
});
|
|
1444
1659
|
const surface = scratch.get('canvas', () => new WGPUCanvasSurface(canvas, device, options.presentationFormat ?? navigator.gpu.getPreferredCanvasFormat()));
|
|
1445
1660
|
return makeRenderPipeline(rayTracePass, () => {
|
|
1446
|
-
const target = makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs);
|
|
1661
|
+
const target = makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs, traceQueue);
|
|
1447
1662
|
return target;
|
|
1448
1663
|
}, false, scratch);
|
|
1449
1664
|
}
|