@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebGLFullQuadPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLFullQuadPass.ts"],"names":[],"mappings":"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","sourcesContent":["import {scratchGLSLFunctions} from './scratchSampling.js';\nimport {setTextureRegion, textureRegion} from './textureRegion.js';\nimport { FragmentShader, ShaderDefineValue } from './shader.js';\nimport {\n FrameBuffer,\n WebGLDevice,\n Texture2D,\n TextureOptions,\n WebGLProgramBindings\n} from './webgl.js';\n\nexport interface WebGLFullQuadPassOutput extends TextureOptions {}\n\nexport interface WebGLPassOptions {\n clear?: boolean;\n blend?: boolean;\n viewport?: { x: number; y: number; width: number; height: number };\n scissor?: { x: number; y: number; width: number; height: number };\n}\n\n/**\n * Explicit WebGL 2.0 render pass matching the lifecycle of WGPUFullQuadPass.\n * It owns its output textures and framebuffer; there is no render graph.\n */\nexport class WebGLFullQuadPass<I extends string, O extends string> {\n private readonly _renderer: WebGLDevice;\n private _bindings: WebGLProgramBindings;\n private readonly _sourceShader: FragmentShader;\n private readonly _outputs: O[];\n private readonly _frameBuffer = new FrameBuffer();\n private _outputTextures = {} as Record<O, Texture2D>;\n private readonly _targetOutputs = new Map<object, Record<O, Texture2D>>();\n useTarget(target: object) {\n let outputs = this._targetOutputs.get(target);\n if (!outputs) this._targetOutputs.set(target, outputs = {} as Record<O, Texture2D>);\n this._outputTextures = outputs;\n }\n\n private _outputParams = {} as Record<O, WebGLFullQuadPassOutput>;\n private _reserveCapacity = false;\n private _capacityWidth = 1;\n private _capacityHeight = 1;\n private _width = 1;\n private _height = 1;\n private _renderToScreen = false;\n\n constructor(\n _label: string,\n renderer: WebGLDevice,\n options: {\n shader: FragmentShader;\n outputs?: O[];\n outputParams?: Partial<Record<O, WebGLFullQuadPassOutput>>;\n }\n ) {\n this._renderer = renderer;\n this._sourceShader = options.shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(options.shader));\n this._outputs = options.outputs || (options.shader.outputs as O[]);\n this.setOutputParams(\n Object.fromEntries(\n this._outputs.map((name) => [\n name,\n options.outputParams?.[name] || {}\n ])\n ) as Record<O, WebGLFullQuadPassOutput>\n );\n }\n\n reserveCapacity() {\n if (this._reserveCapacity) return;\n this._reserveCapacity = true;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n this._sourceShader, true, this._bindings.uniforms, this._bindings.defines\n ));\n }\n\n private _samplingShader(\n shader: FragmentShader,\n scratch = false,\n uniforms = shader.uniforms,\n defines = shader.defines\n ) {\n const textures = Object.keys(shader.uniforms).filter(name => shader.uniforms[name].type === 'sampler2D');\n uniforms = {...uniforms};\n if (scratch) for (const name of textures) uniforms[`${name}RegionSize`] = {type: 'ivec2', value: [1, 1]};\n const sampled = new FragmentShader({name: shader.name, outputs: shader.outputs, defines, uniforms,\n includes: [{defines: {}, uniforms: {}, main: '', functions: [() => scratchGLSLFunctions(textures, scratch), ...shader.functions]}],\n main: shader.main});\n sampled.parallelCompile = shader.parallelCompile;\n return sampled;\n }\n\n setSize(width: number, height: number) {\n if (this._width === width && this._height === height) return;\n this._width = Math.max(1, width);\n this._height = Math.max(1, height);\n this._capacityWidth = Math.max(this._capacityWidth, this._width);\n this._capacityHeight = Math.max(this._capacityHeight, this._height);\n this.setUniform('viewportSize', [this._width, this._height]);\n }\n\n setOutputs(outputs: readonly O[]) {\n for (const name of this._outputs) if (!outputs.includes(name)) {\n this._outputTextures[name]?.dispose(this._renderer.gl); delete this._outputTextures[name];\n }\n this._outputs.splice(0, this._outputs.length, ...outputs);\n }\n setOutputParams(params: Record<O, WebGLFullQuadPassOutput>) {\n this._outputParams = params;\n }\n\n setRenderToScreen(renderToScreen = true) {\n this._renderToScreen = renderToScreen;\n }\n\n setUniform(label: string, data: unknown) {\n return this._bindings.set(label, data);\n }\n\n setUniforms(values: Record<string, unknown>) {\n this._bindings.setUniforms(values);\n }\n\n getUniform(label: string) {\n return this._bindings.get(label);\n }\n\n setDefines(\n defines: Record<\n string,\n ShaderDefineValue | undefined\n >\n ) {\n let changed = false;\n for (const [name, value] of Object.entries(defines)) {\n const oldValue = this._bindings.defines[name];\n if (!value) {\n if (name in this._bindings.defines) {\n this._bindings.deleteDefine(name);\n changed = true;\n }\n } else if (oldValue !== value) {\n this._bindings.setDefine(name, value);\n changed = true;\n }\n }\n return changed;\n }\n\n private readonly _retainedOutputs = new Set<Texture2D>();\n retainOutput(texture: Texture2D) { if (Object.values(this._outputTextures).includes(texture)) this._retainedOutputs.add(texture); }\n releaseOutput(texture: Texture2D) {\n if (!this._retainedOutputs.delete(texture)) return;\n if (!Object.values(this._outputTextures).includes(texture)) texture.dispose(this._renderer.gl);\n }\n\n getOutput(name: O) {\n return this._outputTextures[name];\n }\n\n private _prepareOutputs(explicitOutputs?: Partial<Record<O, Texture2D>>) {\n const gl = this._renderer.gl;\n for (const name of this._outputs) {\n const explicit = explicitOutputs?.[name];\n const current = this._outputTextures[name];\n const retainedResize = current && this._retainedOutputs.has(current) &&\n (current.width !== this._width || current.height !== this._height);\n const texture =\n explicit ||\n (retainedResize ? new Texture2D(this._outputParams[name]) : undefined) ||\n this._outputTextures[name] ||\n new Texture2D(this._outputParams[name]);\n texture.ensureStorage(\n gl,\n this._reserveCapacity ? this._capacityWidth : this._width,\n this._reserveCapacity ? this._capacityHeight : this._height,\n this._outputParams[name]\n );\n this._outputTextures[name] = texture;\n setTextureRegion(texture, this._width, this._height);\n }\n }\n\n createPass(\n inputs: Record<I, Texture2D>,\n explicitOutputs?: Partial<Record<O, Texture2D>>,\n options: WebGLPassOptions = {}\n ) {\n const renderer = this._renderer;\n const gl = renderer.gl;\n\n if (this._renderToScreen) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n } else {\n this._prepareOutputs(explicitOutputs);\n this._frameBuffer.bind(\n renderer,\n this._outputs.map((name) => this._outputTextures[name])\n );\n }\n\n const viewport = options.viewport || {\n x: 0,\n y: 0,\n width: this._width,\n height: this._height\n };\n renderer.setViewport(\n viewport.x,\n viewport.y,\n viewport.width,\n viewport.height\n );\n\n // Clear the full accumulation target before enabling the tile scissor.\n // Otherwise every tile outside the first one retains stale camera data.\n if (options.clear) {\n gl.disable(gl.SCISSOR_TEST);\n gl.clearColor(0, 0, 0, 0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n if (options.scissor) {\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(\n options.scissor.x,\n options.scissor.y,\n options.scissor.width,\n options.scissor.height\n );\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n\n if (this._reserveCapacity) for (const [name, texture] of Object.entries(inputs) as [string, Texture2D][]) {\n const region = textureRegion(texture);\n this.setUniform(`${name}RegionSize`, [region.width, region.height]);\n }\n this._bindings.setUniforms(inputs);\n this._bindings.bind(renderer);\n gl.disable(gl.DEPTH_TEST);\n if (options.blend) {\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE);\n } else {\n gl.disable(gl.BLEND);\n }\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n gl.disable(gl.SCISSOR_TEST);\n }\n\n releaseTarget(target: object) {\n const outputs = this._targetOutputs.get(target);\n if (!outputs) return;\n this._targetOutputs.delete(target);\n for (const texture of (Object.values(outputs) as Texture2D[])) texture.dispose(this._renderer.gl);\n if (outputs === this._outputTextures) this._outputTextures = {} as Record<O, Texture2D>;\n }\n\n getMemoryBytes(target?: object): number {\n const outputs = target ? this._targetOutputs.get(target) ?? {} : this._outputTextures;\n return Array.from(new Set([...Object.values(outputs) as Texture2D[], ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + texture.getMemoryBytes(), 0);\n }\n\n dispose() {\n const gl = this._renderer.gl;\n (Array.from(new Set([this._outputTextures, ...this._targetOutputs.values()])).flatMap(outputs => Object.values(outputs)) as Texture2D[]).forEach((texture) =>\n texture.dispose(gl)\n );\n this._retainedOutputs.forEach(texture => texture.dispose(gl));\n this._retainedOutputs.clear();\n this._frameBuffer.dispose(this._renderer);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WebGLFullQuadPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLFullQuadPass.ts"],"names":[],"mappings":"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","sourcesContent":["import {scratchGLSLFunctions} from './scratchSampling.js';\nimport {setTextureRegion, textureRegion} from './textureRegion.js';\nimport { FragmentShader, type ShaderDefineValue } from './shader.js';\nimport {\n FrameBuffer,\n WebGLDevice,\n Texture2D,\n type TextureOptions,\n WebGLProgramBindings\n} from './webgl.js';\n\nexport interface WebGLFullQuadPassOutput extends TextureOptions {}\n\nexport interface WebGLPassOptions {\n clear?: boolean;\n blend?: boolean;\n viewport?: { x: number; y: number; width: number; height: number };\n scissor?: { x: number; y: number; width: number; height: number };\n}\n\n/**\n * Explicit WebGL 2.0 render pass matching the lifecycle of WGPUFullQuadPass.\n * It owns its output textures and framebuffer; there is no render graph.\n */\nexport class WebGLFullQuadPass<I extends string, O extends string> {\n private readonly _renderer: WebGLDevice;\n private _bindings: WebGLProgramBindings;\n private _sourceShader: FragmentShader;\n private readonly _outputs: O[];\n private readonly _frameBuffer = new FrameBuffer();\n private _outputTextures = {} as Record<O, Texture2D>;\n private readonly _targetOutputs = new Map<object, Record<O, Texture2D>>();\n useTarget(target: object) {\n let outputs = this._targetOutputs.get(target);\n if (!outputs) this._targetOutputs.set(target, outputs = {} as Record<O, Texture2D>);\n this._outputTextures = outputs;\n }\n\n private _outputParams = {} as Record<O, WebGLFullQuadPassOutput>;\n private _reserveCapacity = false;\n private _capacityWidth = 1;\n private _capacityHeight = 1;\n private _width = 1;\n private _height = 1;\n private _renderToScreen = false;\n\n constructor(\n _label: string,\n renderer: WebGLDevice,\n options: {\n shader: FragmentShader;\n outputs?: O[];\n outputParams?: Partial<Record<O, WebGLFullQuadPassOutput>>;\n }\n ) {\n this._renderer = renderer;\n this._sourceShader = options.shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(options.shader));\n this._outputs = options.outputs || (options.shader.outputs as O[]);\n this.setOutputParams(\n Object.fromEntries(\n this._outputs.map((name) => [\n name,\n options.outputParams?.[name] || {}\n ])\n ) as Record<O, WebGLFullQuadPassOutput>\n );\n }\n\n setShader(shader: FragmentShader) {\n this._sourceShader = shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n shader, this._reserveCapacity, {...shader.uniforms, ...this._bindings.uniforms}, this._bindings.defines\n ));\n }\n\n reserveCapacity() {\n if (this._reserveCapacity) return;\n this._reserveCapacity = true;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n this._sourceShader, true, this._bindings.uniforms, this._bindings.defines\n ));\n }\n\n private _samplingShader(\n shader: FragmentShader,\n scratch = false,\n uniforms = shader.uniforms,\n defines = shader.defines\n ) {\n const textures = Object.keys(shader.uniforms).filter(name => shader.uniforms[name].type === 'sampler2D');\n uniforms = {...uniforms};\n if (scratch) for (const name of textures) uniforms[`${name}RegionSize`] = {type: 'ivec2', value: [1, 1]};\n const sampled = new FragmentShader({name: shader.name, outputs: shader.outputs, outputTypes: shader.outputTypes, defines, uniforms,\n includes: [{defines: {}, uniforms: {}, main: '', functions: [() => scratchGLSLFunctions(textures, scratch), ...shader.functions]}],\n main: shader.main});\n sampled.parallelCompile = shader.parallelCompile;\n return sampled;\n }\n\n setSize(width: number, height: number) {\n if (this._width === width && this._height === height) return;\n this._width = Math.max(1, width);\n this._height = Math.max(1, height);\n this._capacityWidth = Math.max(this._capacityWidth, this._width);\n this._capacityHeight = Math.max(this._capacityHeight, this._height);\n this.setUniform('viewportSize', [this._width, this._height]);\n }\n\n setOutputs(outputs: readonly O[]) {\n for (const name of this._outputs) if (!outputs.includes(name)) {\n this._outputTextures[name]?.dispose(this._renderer.gl); delete this._outputTextures[name];\n }\n this._outputs.splice(0, this._outputs.length, ...outputs);\n }\n setOutputParams(params: Record<O, WebGLFullQuadPassOutput>) {\n this._outputParams = params;\n }\n\n setRenderToScreen(renderToScreen = true) {\n this._renderToScreen = renderToScreen;\n }\n\n setUniform(label: string, data: unknown) {\n return this._bindings.set(label, data);\n }\n\n setUniforms(values: Record<string, unknown>) {\n this._bindings.setUniforms(values);\n }\n\n getUniform(label: string) {\n return this._bindings.get(label);\n }\n\n setDefines(\n defines: Record<\n string,\n ShaderDefineValue | undefined\n >\n ) {\n let changed = false;\n for (const [name, value] of Object.entries(defines)) {\n const oldValue = this._bindings.defines[name];\n if (!value) {\n if (name in this._bindings.defines) {\n this._bindings.deleteDefine(name);\n changed = true;\n }\n } else if (oldValue !== value) {\n this._bindings.setDefine(name, value);\n changed = true;\n }\n }\n return changed;\n }\n\n private readonly _retainedOutputs = new Set<Texture2D>();\n retainOutput(texture: Texture2D) { if (Object.values(this._outputTextures).includes(texture)) this._retainedOutputs.add(texture); }\n releaseOutput(texture: Texture2D) {\n if (!this._retainedOutputs.delete(texture)) return;\n if (!Object.values(this._outputTextures).includes(texture)) texture.dispose(this._renderer.gl);\n }\n\n // Internal fixed-accumulation loader; transfer ownership to the selected target.\n loadDiagnosticOutputs(outputs: Partial<Record<O, Texture2D>>) {\n for (const name of Object.keys(outputs) as O[]) {\n this._outputTextures[name]?.dispose(this._renderer.gl);\n this._outputTextures[name] = outputs[name]!;\n }\n }\n\n getOutput(name: O) {\n return this._outputTextures[name];\n }\n\n private _prepareOutputs(explicitOutputs?: Partial<Record<O, Texture2D>>) {\n const gl = this._renderer.gl;\n for (const name of this._outputs) {\n const explicit = explicitOutputs?.[name];\n const current = this._outputTextures[name];\n const retainedResize = current && this._retainedOutputs.has(current) &&\n (current.width !== this._width || current.height !== this._height);\n const texture =\n explicit ||\n (retainedResize ? new Texture2D(this._outputParams[name]) : undefined) ||\n this._outputTextures[name] ||\n new Texture2D(this._outputParams[name]);\n texture.ensureStorage(\n gl,\n this._reserveCapacity ? this._capacityWidth : this._width,\n this._reserveCapacity ? this._capacityHeight : this._height,\n this._outputParams[name]\n );\n this._outputTextures[name] = texture;\n setTextureRegion(texture, this._width, this._height);\n }\n }\n\n isProgramReady(inputs?: Record<I, Texture2D>) {\n if (inputs) this._bindings.setUniforms(inputs);\n return this._renderer.isProgramCompiled(this._bindings.getProgram(this._renderer));\n }\n\n createPass(\n inputs: Record<I, Texture2D>,\n explicitOutputs?: Partial<Record<O, Texture2D>>,\n options: WebGLPassOptions = {}\n ) {\n const renderer = this._renderer;\n const gl = renderer.gl;\n\n if (this._renderToScreen) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n } else {\n this._prepareOutputs(explicitOutputs);\n this._frameBuffer.bind(\n renderer,\n this._outputs.map((name) => this._outputTextures[name])\n );\n }\n\n const viewport = options.viewport || {\n x: 0,\n y: 0,\n width: this._width,\n height: this._height\n };\n renderer.setViewport(\n viewport.x,\n viewport.y,\n viewport.width,\n viewport.height\n );\n\n // Clear the full accumulation target before enabling the tile scissor.\n // Otherwise every tile outside the first one retains stale camera data.\n if (options.clear) {\n gl.disable(gl.SCISSOR_TEST);\n gl.clearColor(0, 0, 0, 0);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n if (options.scissor) {\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(\n options.scissor.x,\n options.scissor.y,\n options.scissor.width,\n options.scissor.height\n );\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n\n if (this._reserveCapacity) for (const [name, texture] of Object.entries(inputs) as [string, Texture2D][]) {\n const region = textureRegion(texture);\n this.setUniform(`${name}RegionSize`, [region.width, region.height]);\n }\n this._bindings.setUniforms(inputs);\n if (!this._bindings.bind(renderer)) {\n gl.disable(gl.SCISSOR_TEST);\n return false;\n }\n gl.disable(gl.DEPTH_TEST);\n if (options.blend) {\n gl.enable(gl.BLEND);\n gl.blendEquation(gl.FUNC_ADD);\n gl.blendFunc(gl.ONE, gl.ONE);\n } else {\n gl.disable(gl.BLEND);\n }\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n gl.disable(gl.SCISSOR_TEST);\n return true;\n }\n\n releaseTarget(target: object) {\n const outputs = this._targetOutputs.get(target);\n if (!outputs) return;\n this._targetOutputs.delete(target);\n for (const texture of (Object.values(outputs) as Texture2D[])) texture.dispose(this._renderer.gl);\n if (outputs === this._outputTextures) this._outputTextures = {} as Record<O, Texture2D>;\n }\n\n getMemoryBytes(target?: object): number {\n const outputs = target ? this._targetOutputs.get(target) ?? {} : this._outputTextures;\n return Array.from(new Set([...Object.values(outputs) as Texture2D[], ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + texture.getMemoryBytes(), 0);\n }\n\n dispose() {\n const gl = this._renderer.gl;\n (Array.from(new Set([this._outputTextures, ...this._targetOutputs.values()])).flatMap(outputs => Object.values(outputs)) as Texture2D[]).forEach((texture) =>\n texture.dispose(gl)\n );\n this._retainedOutputs.forEach(texture => texture.dispose(gl));\n this._retainedOutputs.clear();\n this._frameBuffer.dispose(this._renderer);\n }\n}\n"]}
|
|
@@ -23,7 +23,7 @@ export declare class WebGLJNLMDenoisePass {
|
|
|
23
23
|
private _filterPasses;
|
|
24
24
|
constructor(renderer: WebGLDevice);
|
|
25
25
|
/** Runs the denoiser and returns the display-encoded result. */
|
|
26
|
-
render(inputs: WebGLJNLMInputs): Texture2D;
|
|
26
|
+
render(inputs: WebGLJNLMInputs, trace?: string[]): Texture2D;
|
|
27
27
|
reserveCapacity(): void;
|
|
28
28
|
retainOutput(texture: Texture2D): void;
|
|
29
29
|
releaseOutput(texture: Texture2D): void;
|
|
@@ -45,27 +45,27 @@ void main() {
|
|
|
45
45
|
ivec2 p = ivec2(gl_FragCoord.xy);
|
|
46
46
|
ivec2 size = rawGuideTexRegion();
|
|
47
47
|
vec2 center = load_rawGuideTex(p, 0).xy;
|
|
48
|
-
float
|
|
49
|
-
float
|
|
50
|
-
float
|
|
51
|
-
float
|
|
48
|
+
float lM = 0.0;
|
|
49
|
+
float je = 0.0;
|
|
50
|
+
float nM = 0.0;
|
|
51
|
+
float iV = 0.0;
|
|
52
52
|
for (int dy = -1; dy <= 1; dy++) {
|
|
53
53
|
for (int dx = -1; dx <= 1; dx++) {
|
|
54
54
|
vec2 value = load_rawGuideTex(clamp(p + ivec2(dx, dy), ivec2(0), size - 1), 0).xy;
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
nM += value.x;
|
|
56
|
+
iV += value.x * value.x;
|
|
57
57
|
if (value.y >= 0.0) {
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
lM += value.y;
|
|
59
|
+
je += 1.0;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
float variance;
|
|
64
64
|
if (center.y >= 0.0) {
|
|
65
|
-
variance =
|
|
65
|
+
variance = lM / je;
|
|
66
66
|
} else {
|
|
67
|
-
float
|
|
68
|
-
variance = max(
|
|
67
|
+
float lL = nM / 9.0;
|
|
68
|
+
variance = max(iV / 9.0 - lL * lL, 0.0) * 9.0 / 8.0;
|
|
69
69
|
}
|
|
70
70
|
out_guide = vec4(center.x, variance, 0.0, 1.0);
|
|
71
71
|
}`
|
|
@@ -105,68 +105,70 @@ const filterFragment = new FragmentShader({
|
|
|
105
105
|
|
|
106
106
|
ivec2 imageSize;
|
|
107
107
|
|
|
108
|
-
vec2
|
|
108
|
+
vec2 loadGuide(ivec2 p) {
|
|
109
109
|
return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
vec4
|
|
113
|
+
vec4 sI(ivec2 p) {
|
|
114
114
|
vec4 c = load_colorTex(p, 0);
|
|
115
|
-
if (decodeInput) c.rgb = pow(max(c.rgb, 0.0), vec3(2.
|
|
115
|
+
if (decodeInput) c.rgb = mix(pow((max(c.rgb, 0.0) + 0.055) / 1.055, vec3(2.4)),
|
|
116
|
+
c.rgb / 12.92, lessThanEqual(c.rgb, vec3(0.04045)));
|
|
116
117
|
return vec4(c.rgb * c.a, c.a);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
float
|
|
120
|
+
float lP(ivec2 q, vec4 bo, vec3 gO) {
|
|
120
121
|
vec4 albedo = load_albedoTex(q, 0);
|
|
121
122
|
|
|
122
123
|
|
|
123
|
-
vec3
|
|
124
|
-
vec3
|
|
125
|
-
float
|
|
126
|
-
vec3
|
|
124
|
+
vec3 pY = max((albedo.rgb + bo.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));
|
|
125
|
+
vec3 lu = (albedo.rgb - bo.rgb) / pY;
|
|
126
|
+
float iQ = albedo.a - bo.a;
|
|
127
|
+
vec3 lG = load_normalTex(q, 0).rgb - gO;
|
|
127
128
|
return max(
|
|
128
|
-
dot(
|
|
129
|
-
+
|
|
130
|
-
dot(
|
|
129
|
+
dot(lu, lu) * INV_ALBEDO_BANDWIDTH2
|
|
130
|
+
+ iQ * iQ * INV_COVERAGE_BANDWIDTH2,
|
|
131
|
+
dot(lG, lG) * INV_NORMAL_BANDWIDTH2
|
|
131
132
|
);
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
void main() {
|
|
135
136
|
imageSize = guideTexRegion();
|
|
136
137
|
ivec2 p = ivec2(gl_FragCoord.xy);
|
|
137
|
-
vec4
|
|
138
|
-
vec4
|
|
139
|
-
vec3
|
|
138
|
+
vec4 bo = load_albedoTex(p, 0);
|
|
139
|
+
vec4 fC = load_normalTex(p, 0);
|
|
140
|
+
vec3 gO = fC.rgb;
|
|
140
141
|
|
|
141
142
|
|
|
142
|
-
if (
|
|
143
|
-
vec4 c =
|
|
143
|
+
if (fC.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {
|
|
144
|
+
vec4 c = sI(p);
|
|
144
145
|
vec3 rgb = c.rgb / max(c.a, 1e-6);
|
|
145
|
-
if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.
|
|
146
|
+
if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,
|
|
147
|
+
rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));
|
|
146
148
|
out_color = vec4(rgb, c.a);
|
|
147
|
-
out_guide = vec4(
|
|
149
|
+
out_guide = vec4(loadGuide(p), 0.0, 1.0);
|
|
148
150
|
return;
|
|
149
151
|
}
|
|
150
152
|
|
|
151
|
-
vec2
|
|
153
|
+
vec2 lA[PATCH_SIZE];
|
|
152
154
|
int k = 0;
|
|
153
155
|
for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
154
156
|
for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
155
|
-
|
|
157
|
+
lA[k] = loadGuide(p + ivec2(dx, dy) * dilation);
|
|
156
158
|
k++;
|
|
157
159
|
}
|
|
158
160
|
}
|
|
159
161
|
float k2 = colorSensitivity * colorSensitivity;
|
|
160
162
|
|
|
161
163
|
vec4 sum = vec4(0.0);
|
|
162
|
-
vec3
|
|
163
|
-
vec3
|
|
164
|
-
vec3
|
|
165
|
-
vec3
|
|
166
|
-
float
|
|
167
|
-
float
|
|
168
|
-
float
|
|
169
|
-
float
|
|
164
|
+
vec3 gR = max(bo.rgb, vec3(${JNLM_ALBEDO_FLOOR}));
|
|
165
|
+
vec3 mQ = vec3(0.0);
|
|
166
|
+
vec3 gv = vec3(0.0);
|
|
167
|
+
vec3 hm = vec3(0.0);
|
|
168
|
+
float qf = 0.0;
|
|
169
|
+
float gx = 0.0;
|
|
170
|
+
float oE = 0.0;
|
|
171
|
+
float kX = 0.0;
|
|
170
172
|
for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {
|
|
171
173
|
for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {
|
|
172
174
|
ivec2 q = p + ivec2(sx, sy) * dilation;
|
|
@@ -174,68 +176,69 @@ if (
|
|
|
174
176
|
(sx == 0 && sy == 0) ||
|
|
175
177
|
q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y
|
|
176
178
|
) continue;
|
|
177
|
-
float features =
|
|
179
|
+
float features = lP(q, bo, gO);
|
|
178
180
|
if (features > 16.0) continue;
|
|
179
181
|
|
|
180
|
-
float
|
|
182
|
+
float fW = 0.0;
|
|
181
183
|
k = 0;
|
|
182
184
|
for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
183
185
|
for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
184
|
-
vec2 a =
|
|
185
|
-
vec2 b =
|
|
186
|
-
float
|
|
187
|
-
|
|
186
|
+
vec2 a = lA[k];
|
|
187
|
+
vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);
|
|
188
|
+
float rV = a.x - b.x;
|
|
189
|
+
fW += (rV * rV
|
|
188
190
|
- VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))
|
|
189
191
|
/ (1e-10 + k2 * (a.y + b.y));
|
|
190
192
|
k++;
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
|
-
|
|
195
|
+
fW /= float(PATCH_SIZE);
|
|
194
196
|
|
|
195
|
-
float weight = exp(-max(max(
|
|
196
|
-
vec2 g =
|
|
197
|
+
float weight = exp(-max(max(fW, 0.0), features));
|
|
198
|
+
vec2 g = loadGuide(q);
|
|
197
199
|
|
|
198
|
-
vec3 a = (load_albedoTex(q, 0).rgb -
|
|
199
|
-
vec4 value =
|
|
200
|
+
vec3 a = (load_albedoTex(q, 0).rgb - bo.rgb) / gR;
|
|
201
|
+
vec4 value = sI(q);
|
|
200
202
|
sum += value * weight;
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
mQ += a * weight;
|
|
204
|
+
gv += a * a * weight;
|
|
205
|
+
hm += a * value.rgb * weight;
|
|
206
|
+
qf += g.x * weight;
|
|
207
|
+
gx += g.y * weight * weight;
|
|
208
|
+
oE += weight;
|
|
209
|
+
kX = max(kX, weight);
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
|
|
212
214
|
|
|
213
|
-
vec4 center =
|
|
214
|
-
vec2
|
|
215
|
-
float
|
|
216
|
-
float totalWeight =
|
|
217
|
-
vec4 mean = (sum + center *
|
|
215
|
+
vec4 center = sI(p);
|
|
216
|
+
vec2 lw = loadGuide(p);
|
|
217
|
+
float dE = max(kX, CENTER_WEIGHT_MIN);
|
|
218
|
+
float totalWeight = oE + dE;
|
|
219
|
+
vec4 mean = (sum + center * dE) / totalWeight;
|
|
218
220
|
|
|
219
221
|
|
|
220
|
-
vec3
|
|
221
|
-
vec3
|
|
222
|
-
vec3
|
|
222
|
+
vec3 er = mQ / totalWeight;
|
|
223
|
+
vec3 lQ = max(gv / totalWeight - er * er, vec3(0.0));
|
|
224
|
+
vec3 rq = hm / totalWeight - er * mean.rgb;
|
|
223
225
|
|
|
224
226
|
|
|
225
227
|
|
|
226
|
-
vec3
|
|
227
|
-
vec3
|
|
228
|
-
vec3
|
|
229
|
-
vec3
|
|
230
|
-
vec4 filtered = vec4(max(
|
|
228
|
+
vec3 rD = bo.rgb + er * gR;
|
|
229
|
+
vec3 pd = mean.rgb * gR / max(rD, vec3(${JNLM_ALBEDO_FLOOR}));
|
|
230
|
+
vec3 xI = clamp(rq / (lQ + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), pd);
|
|
231
|
+
vec3 sz = mean.rgb - xI * er;
|
|
232
|
+
vec4 filtered = vec4(max(sz, vec3(0.0)), max(mean.a, 0.0));
|
|
231
233
|
vec3 rgb = filtered.a > 1e-6
|
|
232
234
|
? filtered.rgb / max(filtered.a, 1e-6)
|
|
233
235
|
: center.rgb / max(center.a, 1e-6);
|
|
234
|
-
if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.
|
|
236
|
+
if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,
|
|
237
|
+
rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));
|
|
235
238
|
out_color = vec4(rgb, filtered.a);
|
|
236
239
|
out_guide = vec4(
|
|
237
|
-
(
|
|
238
|
-
(
|
|
240
|
+
(qf + lw.x * dE) / totalWeight,
|
|
241
|
+
(gx + lw.y * dE * dE)
|
|
239
242
|
/ (totalWeight * totalWeight),
|
|
240
243
|
0.0,
|
|
241
244
|
1.0
|
|
@@ -272,7 +275,7 @@ export class WebGLJNLMDenoisePass {
|
|
|
272
275
|
}));
|
|
273
276
|
}
|
|
274
277
|
/** Runs the denoiser and returns the display-encoded result. */
|
|
275
|
-
render(inputs) {
|
|
278
|
+
render(inputs, trace) {
|
|
276
279
|
const { width, height, shape } = inputs;
|
|
277
280
|
const passes = [this._guidePass, this._variancePass, ...this._filterPasses];
|
|
278
281
|
passes.forEach((pass) => pass.setSize(width, height));
|
|
@@ -300,6 +303,12 @@ export class WebGLJNLMDenoisePass {
|
|
|
300
303
|
decodeInput: i === 0,
|
|
301
304
|
encodeOutput: i === iterations - 1
|
|
302
305
|
});
|
|
306
|
+
if (trace) {
|
|
307
|
+
if (i === 0)
|
|
308
|
+
trace.push('Decode:DisplayLinear', 'Denoise:DisplayLinear');
|
|
309
|
+
if (i === iterations - 1)
|
|
310
|
+
trace.push('Encode:DisplayEncoded');
|
|
311
|
+
}
|
|
303
312
|
pass.createPass({
|
|
304
313
|
guideTex: guide,
|
|
305
314
|
colorTex: color,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebGLJNLMDenoiser.js","sourceRoot":"","sources":["../../src/renderer/WebGLJNLMDenoiser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,SAAS,EAA0B,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,8BAA8B,EAC9B,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAEjB,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AAEH;;;GAGG;AACH,MAAM,aAAa,GAAG,IAAI,cAAc,CAAC;IACvC,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QACvC,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;KAC/C;IACD,IAAI,EAAE,IAAI,CAAA;;;;;;;;;;;EAWV;CACD,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,gBAAgB,GAAG,IAAI,cAAc,CAAC;IAC1C,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,QAAQ,EAAE;QACR,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;KACzC;IACD,IAAI,EAAE,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BV;CACD,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,cAAc,GAAG,IAAI,cAAc,CAAC;IACxC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE;QACP,aAAa,EAAE,kBAAkB,CAAC,YAAY;QAC9C,YAAY,EAAE,kBAAkB,CAAC,WAAW;QAC5C,qBAAqB,EAAE,CAAC,CAAC,GAAG,kBAAkB,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/E,qBAAqB,EAAE,CAAC,CAAC,GAAG,kBAAkB,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;KAChF;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QACrC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QACtC,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7C,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,8BAA8B,CAAC;QACzE,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAClC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;KACxC;IACD,IAAI,EAAE,IAAI,CAAA;;;;;;;kCAOsB,CAAC,CAAC,GAAG,uBAAuB,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;kDAmBR,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAuCrC,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAiEG,iBAAiB;kCAC5B,0BAA0B;;;;;;;;;;;;;;;EAepF;CACD,CAAC,CAAC;AAmBH,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,SAAS,CAAC,KAAK;IACrB,SAAS,EAAE,SAAS,CAAC,OAAO;IAC5B,SAAS,EAAE,SAAS,CAAC,OAAO;CAC7B,CAAC;AAEF,MAAM,OAAO,oBAAoB;IACvB,SAAS,CAAc;IACvB,UAAU,CAAiE;IAC3E,aAAa,CAA4C;IACjE,uEAAuE;IAC/D,aAAa,CAGjB;IAEJ,YAAY,QAAqB;QAC/B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE;YAC7D,MAAM,EAAE,aAAa;YACrB,YAAY,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;SACrC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,IAAI,iBAAiB,CAAC,cAAc,EAAE,QAAQ,EAAE;YACnE,MAAM,EAAE,gBAAgB;YACxB,YAAY,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;SACrC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CACnC,IAAI,iBAAiB,CAAC,YAAY,EAAE,QAAQ,EAAE;YAC5C,MAAM,EAAE,cAAc;YACtB,YAAY,EAAE;gBACZ,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,UAAU,EAAE;gBACrC,KAAK,EAAE,WAAW;aACnB;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAED,gEAAgE;IAChE,MAAM,CAAC,MAAuB;QAC5B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QACxC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YACzB,UAAU,EAAE,MAAM,CAAC,OAAO;YAC1B,iBAAiB,EAAE,MAAM,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY;SACxE,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAEnF,MAAM,WAAW,GAAG,8BAA8B,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,UAAU,CAAC;gBACd,aAAa,EAAE,KAAK,CAAC,YAAY;gBACjC,6DAA6D;gBAC7D,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;gBACvC,qBAAqB,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClE,qBAAqB,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;aACnE,CAAC,CAAC;YACH,IAAI,CAAC,WAAW,CAAC;gBACf,gBAAgB,EAAE,WAAW;gBAC7B,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;gBAC7B,WAAW,EAAE,CAAC,KAAK,CAAC;gBACpB,YAAY,EAAE,CAAC,KAAK,UAAU,GAAG,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,UAAU,CAAC;gBACd,QAAQ,EAAE,KAAK;gBACf,QAAQ,EAAE,KAAK;gBACf,SAAS,EAAE,MAAM,CAAC,MAAM;gBACxB,SAAS,EAAE,MAAM,CAAC,MAAM;gBACxB,gBAAgB,EAAE,MAAM,CAAC,aAAa;aACvC,CAAC,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,eAAe;QACb,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IACvG,CAAC;IAED,YAAY,CAAC,OAAkB,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACpG,aAAa,CAAC,OAAkB,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtG,cAAc;QACZ,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;aAChE,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO;QACL,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5E,IAAI,CAAC,OAAO,EAAE,CACf,CAAC;IACJ,CAAC;CACF","sourcesContent":["import { FragmentShader, glsl, Shader } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport {\n JNLM_DEFAULT_COLOR_SENSITIVITY,\n JNLM_ALBEDO_FLOOR,\n JNLM_ALBEDO_REGULARIZATION,\n JNLM_DEFAULT_SHAPE,\n JNLM_COVERAGE_BANDWIDTH,\n JNLM_MAX_ITERATIONS,\n jnlmPassDilation,\n type JNLMFilterShape\n} from './jnlm.js';\n\n/**\n * WebGL 2 passes of the JNLM denoiser described in `jnlm.ts`, matching\n * WGPUJNLMDenoiser. Textures replace its storage buffers.\n */\n\n/**\n * The guide mean and the variance of that mean. The main and catcher trace\n * passes each accumulate (sum, sum of squares, count) for their own samples.\n */\nconst guideFragment = new FragmentShader({\n name: 'jnlmGuide',\n outputs: ['guide'],\n uniforms: {\n momentsTex: Shader.uniform('sampler2D'),\n catcherMomentsTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 moments = load_momentsTex(p, 0) + load_catcherMomentsTex(p, 0);\n float n = moments.z;\n float mean = moments.x / max(n, 1.0);\n // Variance of the mean, or -1 when one sample cannot estimate it.\n float variance = n >= 2.0\n ? max(moments.y - n * mean * mean, 0.0) / (n * (n - 1.0))\n : -1.0;\n out_guide = vec4(mean, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * Smooths the noisy per-pixel variance over 3 x 3 pixels. Pixels with a\n * single sample take the spatial variance of their neighborhood instead.\n */\nconst varianceFragment = new FragmentShader({\n name: 'jnlmVariance',\n outputs: ['guide'],\n uniforms: {\n rawGuideTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n ivec2 size = rawGuideTexRegion();\n vec2 center = load_rawGuideTex(p, 0).xy;\n float varianceSum = 0.0;\n float varianceCount = 0.0;\n float meanSum = 0.0;\n float meanSquareSum = 0.0;\n for (int dy = -1; dy <= 1; dy++) {\n for (int dx = -1; dx <= 1; dx++) {\n vec2 value = load_rawGuideTex(clamp(p + ivec2(dx, dy), ivec2(0), size - 1), 0).xy;\n meanSum += value.x;\n meanSquareSum += value.x * value.x;\n if (value.y >= 0.0) {\n varianceSum += value.y;\n varianceCount += 1.0;\n }\n }\n }\n float variance;\n if (center.y >= 0.0) {\n variance = varianceSum / varianceCount;\n } else {\n float spatialMean = meanSum / 9.0;\n variance = max(meanSquareSum / 9.0 - spatialMean * spatialMean, 0.0) * 9.0 / 8.0;\n }\n out_guide = vec4(center.x, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * One joint NL-means pass; see createJNLMFilterWGSL. The first pass decodes\n * the display-encoded composition to linear light, the last encodes it again.\n */\nconst filterFragment = new FragmentShader({\n name: 'jnlmFilter',\n outputs: ['color', 'guide'],\n defines: {\n SEARCH_RADIUS: JNLM_DEFAULT_SHAPE.searchRadius,\n PATCH_RADIUS: JNLM_DEFAULT_SHAPE.patchRadius,\n INV_ALBEDO_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.normalBandwidth ** 2).toFixed(6)\n },\n uniforms: {\n guideTex: Shader.uniform('sampler2D'),\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n colorSensitivity: Shader.uniform('float', JNLM_DEFAULT_COLOR_SENSITIVITY),\n dilation: Shader.uniform('int', 1),\n decodeInput: Shader.uniform('bool', 0),\n encodeOutput: Shader.uniform('bool', 0)\n },\n main: glsl`\n#define PATCH_SIZE ((2 * PATCH_RADIUS + 1) * (2 * PATCH_RADIUS + 1))\n// Variance cancellation strength alpha of the paper.\n#define VARIANCE_CANCELLATION 1.0\n// Lower bound of the center weight, so a pixel unlike all of its neighbors\n// (a thin highlight) is kept rather than replaced by them.\n#define CENTER_WEIGHT_MIN 0.01\n#define INV_COVERAGE_BANDWIDTH2 ${(1 / JNLM_COVERAGE_BANDWIDTH ** 2).toFixed(6)}\n\nivec2 imageSize;\n\nvec2 loadGuide(ivec2 p) {\n return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;\n}\n\n// Premultiplied linear color.\nvec4 loadColor(ivec2 p) {\n vec4 c = load_colorTex(p, 0);\n if (decodeInput) c.rgb = pow(max(c.rgb, 0.0), vec3(2.2));\n return vec4(c.rgb * c.a, c.a);\n}\n\nfloat featureDistance(ivec2 q, vec4 centerAlbedo, vec3 centerNormal) {\n vec4 albedo = load_albedoTex(q, 0);\n // Match WebGPU: protect relative RGB contrast, including dark textures,\n // while keeping coverage differences in absolute units.\n vec3 albedoScale = max((albedo.rgb + centerAlbedo.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 albedoDelta = (albedo.rgb - centerAlbedo.rgb) / albedoScale;\n float coverageDelta = albedo.a - centerAlbedo.a;\n vec3 normalDelta = load_normalTex(q, 0).rgb - centerNormal;\n return max(\n dot(albedoDelta, albedoDelta) * INV_ALBEDO_BANDWIDTH2\n + coverageDelta * coverageDelta * INV_COVERAGE_BANDWIDTH2,\n dot(normalDelta, normalDelta) * INV_NORMAL_BANDWIDTH2\n );\n}\n\nvoid main() {\n imageSize = guideTexRegion();\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 centerAlbedo = load_albedoTex(p, 0);\n vec4 centerNormalTexel = load_normalTex(p, 0);\n vec3 centerNormal = centerNormalTexel.rgb;\n // Primary misses show the background directly. It has no features that\n // protect its detail and no noise beyond antialiasing, so keep it.\n if (centerNormalTexel.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {\n vec4 c = loadColor(p);\n vec3 rgb = c.rgb / max(c.a, 1e-6);\n if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.2));\n out_color = vec4(rgb, c.a);\n out_guide = vec4(loadGuide(p), 0.0, 1.0);\n return;\n }\n\n vec2 centerPatch[PATCH_SIZE];\n int k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n centerPatch[k] = loadGuide(p + ivec2(dx, dy) * dilation);\n k++;\n }\n }\n float k2 = colorSensitivity * colorSensitivity;\n\n vec4 sum = vec4(0.0);\n vec3 featureScale = max(centerAlbedo.rgb, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 featureSum = vec3(0.0);\n vec3 featureSquareSum = vec3(0.0);\n vec3 featureColorSum = vec3(0.0);\n float guideSum = 0.0;\n float guideVarianceSum = 0.0;\n float weightSum = 0.0;\n float maxWeight = 0.0;\n for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {\n for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {\n ivec2 q = p + ivec2(sx, sy) * dilation;\n if (\n (sx == 0 && sy == 0) ||\n q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y\n ) continue;\n float features = featureDistance(q, centerAlbedo, centerNormal);\n if (features > 16.0) continue;\n\n float colorDistance = 0.0;\n k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n vec2 a = centerPatch[k];\n vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);\n float delta = a.x - b.x;\n colorDistance += (delta * delta\n - VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))\n / (1e-10 + k2 * (a.y + b.y));\n k++;\n }\n }\n colorDistance /= float(PATCH_SIZE);\n\n float weight = exp(-max(max(colorDistance, 0.0), features));\n vec2 g = loadGuide(q);\n // Filter premultiplied color so coverage and color stay consistent.\n vec3 a = (load_albedoTex(q, 0).rgb - centerAlbedo.rgb) / featureScale;\n vec4 value = loadColor(q);\n sum += value * weight;\n featureSum += a * weight;\n featureSquareSum += a * a * weight;\n featureColorSum += a * value.rgb * weight;\n guideSum += g.x * weight;\n guideVarianceSum += g.y * weight * weight;\n weightSum += weight;\n maxWeight = max(maxWeight, weight);\n }\n }\n\n // Weight the center like its most similar neighbor (Buades et al. 2005)\n // instead of 1, so isolated outliers are not kept unfiltered.\n vec4 center = loadColor(p);\n vec2 centerGuide = loadGuide(p);\n float centerWeight = max(maxWeight, CENTER_WEIGHT_MIN);\n float totalWeight = weightSum + centerWeight;\n vec4 mean = (sum + center * centerWeight) / totalWeight;\n // Fit each color channel against relative albedo with the same JNLM weights.\n // Centering at this pixel avoids cancellation when the feature is constant.\n vec3 meanFeature = featureSum / totalWeight;\n vec3 featureVariance = max(featureSquareSum / totalWeight - meanFeature * meanFeature, vec3(0.0));\n vec3 covariance = featureColorSum / totalWeight - meanFeature * mean.rgb;\n // A 1% contrast ridge stabilizes flat guides. Bound the response between no\n // texture dependence and multiplicative albedo modulation; specular color\n // with an unrelated albedo falls back to the weighted mean.\n vec3 meanAlbedo = centerAlbedo.rgb + meanFeature * featureScale;\n vec3 maximumSlope = mean.rgb * featureScale / max(meanAlbedo, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 slope = clamp(covariance / (featureVariance + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), maximumSlope);\n vec3 corrected = mean.rgb - slope * meanFeature;\n vec4 filtered = vec4(max(corrected, vec3(0.0)), max(mean.a, 0.0));\n vec3 rgb = filtered.a > 1e-6\n ? filtered.rgb / max(filtered.a, 1e-6)\n : center.rgb / max(center.a, 1e-6);\n if (encodeOutput) rgb = pow(max(rgb, 0.0), vec3(1.0 / 2.2));\n out_color = vec4(rgb, filtered.a);\n out_guide = vec4(\n (guideSum + centerGuide.x * centerWeight) / totalWeight,\n (guideVarianceSum + centerGuide.y * centerWeight * centerWeight)\n / (totalWeight * totalWeight),\n 0.0,\n 1.0\n );\n}`\n});\n\nexport interface WebGLJNLMInputs {\n width: number;\n height: number;\n /** Main trace pass moments: guide sum, sum of squares and count. */\n moments: Texture2D;\n /** Catcher trace pass moments, when the scene has a shadow catcher. */\n catcherMoments?: Texture2D;\n /** Display-encoded composition to filter. */\n color: Texture2D;\n albedo: Texture2D;\n normal: Texture2D;\n /** Normalized shadow-catcher mask; red is the catcher coverage. */\n shadowCatcher: Texture2D;\n strength: number;\n shape: JNLMFilterShape;\n}\n\nconst floatOutput = {\n type: constants.FLOAT,\n minFilter: constants.NEAREST,\n magFilter: constants.NEAREST\n};\n\nexport class WebGLJNLMDenoisePass {\n private _renderer: WebGLDevice;\n private _guidePass: WebGLFullQuadPass<'momentsTex' | 'catcherMomentsTex', 'guide'>;\n private _variancePass: WebGLFullQuadPass<'rawGuideTex', 'guide'>;\n // Two instances so consecutive passes ping-pong between their outputs.\n private _filterPasses: WebGLFullQuadPass<\n 'guideTex' | 'colorTex' | 'albedoTex' | 'normalTex' | 'shadowCatcherTex',\n 'color' | 'guide'\n >[];\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._guidePass = new WebGLFullQuadPass('jnlmGuide', renderer, {\n shader: guideFragment,\n outputParams: { guide: floatOutput }\n });\n this._variancePass = new WebGLFullQuadPass('jnlmVariance', renderer, {\n shader: varianceFragment,\n outputParams: { guide: floatOutput }\n });\n this._filterPasses = [0, 1].map(() =>\n new WebGLFullQuadPass('jnlmFilter', renderer, {\n shader: filterFragment,\n outputParams: {\n color: { type: constants.HALF_FLOAT },\n guide: floatOutput\n }\n })\n );\n }\n\n /** Runs the denoiser and returns the display-encoded result. */\n render(inputs: WebGLJNLMInputs): Texture2D {\n const { width, height, shape } = inputs;\n const passes = [this._guidePass, this._variancePass, ...this._filterPasses];\n passes.forEach((pass) => pass.setSize(width, height));\n this._guidePass.createPass({\n momentsTex: inputs.moments,\n catcherMomentsTex: inputs.catcherMoments ?? this._renderer.emptyTexture\n });\n this._variancePass.createPass({ rawGuideTex: this._guidePass.getOutput('guide') });\n\n const sensitivity = JNLM_DEFAULT_COLOR_SENSITIVITY * Math.max(inputs.strength, 1e-3);\n const iterations = Math.min(JNLM_MAX_ITERATIONS, Math.max(1, Math.round(shape.iterations)));\n let guide = this._variancePass.getOutput('guide');\n let color = inputs.color;\n for (let i = 0; i < iterations; i++) {\n const pass = this._filterPasses[i % 2];\n pass.setDefines({\n SEARCH_RADIUS: shape.searchRadius,\n // Numeric zero removes a define in the WebGL shader builder.\n PATCH_RADIUS: String(shape.patchRadius),\n INV_ALBEDO_BANDWIDTH2: (1 / shape.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / shape.normalBandwidth ** 2).toFixed(6)\n });\n pass.setUniforms({\n colorSensitivity: sensitivity,\n dilation: jnlmPassDilation(i),\n decodeInput: i === 0,\n encodeOutput: i === iterations - 1\n });\n pass.createPass({\n guideTex: guide,\n colorTex: color,\n albedoTex: inputs.albedo,\n normalTex: inputs.normal,\n shadowCatcherTex: inputs.shadowCatcher\n });\n guide = pass.getOutput('guide');\n color = pass.getOutput('color');\n }\n return color;\n }\n\n reserveCapacity() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach(pass => pass.reserveCapacity());\n }\n\n retainOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.retainOutput(texture)); }\n releaseOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.releaseOutput(texture)); }\n\n getMemoryBytes() {\n return [this._guidePass, this._variancePass, ...this._filterPasses]\n .reduce((sum, pass) => sum + pass.getMemoryBytes(), 0);\n }\n\n dispose() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach((pass) =>\n pass.dispose()\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WebGLJNLMDenoiser.js","sourceRoot":"","sources":["../../src/renderer/WebGLJNLMDenoiser.ts"],"names":[],"mappings":"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","sourcesContent":["import { FragmentShader, glsl, Shader } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport {\n JNLM_DEFAULT_COLOR_SENSITIVITY,\n JNLM_ALBEDO_FLOOR,\n JNLM_ALBEDO_REGULARIZATION,\n JNLM_DEFAULT_SHAPE,\n JNLM_COVERAGE_BANDWIDTH,\n JNLM_MAX_ITERATIONS,\n jnlmPassDilation,\n type JNLMFilterShape\n} from './jnlm.js';\n\n/**\n * WebGL 2 passes of the JNLM denoiser described in `jnlm.ts`, matching\n * WGPUJNLMDenoiser. Textures replace its storage buffers.\n */\n\n/**\n * The guide mean and the variance of that mean. The main and catcher trace\n * passes each accumulate (sum, sum of squares, count) for their own samples.\n */\nconst guideFragment = new FragmentShader({\n name: 'jnlmGuide',\n outputs: ['guide'],\n uniforms: {\n momentsTex: Shader.uniform('sampler2D'),\n catcherMomentsTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 moments = load_momentsTex(p, 0) + load_catcherMomentsTex(p, 0);\n float n = moments.z;\n float mean = moments.x / max(n, 1.0);\n // Variance of the mean, or -1 when one sample cannot estimate it.\n float variance = n >= 2.0\n ? max(moments.y - n * mean * mean, 0.0) / (n * (n - 1.0))\n : -1.0;\n out_guide = vec4(mean, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * Smooths the noisy per-pixel variance over 3 x 3 pixels. Pixels with a\n * single sample take the spatial variance of their neighborhood instead.\n */\nconst varianceFragment = new FragmentShader({\n name: 'jnlmVariance',\n outputs: ['guide'],\n uniforms: {\n rawGuideTex: Shader.uniform('sampler2D')\n },\n main: glsl`\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n ivec2 size = rawGuideTexRegion();\n vec2 center = load_rawGuideTex(p, 0).xy;\n float varianceSum = 0.0;\n float varianceCount = 0.0;\n float meanSum = 0.0;\n float meanSquareSum = 0.0;\n for (int dy = -1; dy <= 1; dy++) {\n for (int dx = -1; dx <= 1; dx++) {\n vec2 value = load_rawGuideTex(clamp(p + ivec2(dx, dy), ivec2(0), size - 1), 0).xy;\n meanSum += value.x;\n meanSquareSum += value.x * value.x;\n if (value.y >= 0.0) {\n varianceSum += value.y;\n varianceCount += 1.0;\n }\n }\n }\n float variance;\n if (center.y >= 0.0) {\n variance = varianceSum / varianceCount;\n } else {\n float spatialMean = meanSum / 9.0;\n variance = max(meanSquareSum / 9.0 - spatialMean * spatialMean, 0.0) * 9.0 / 8.0;\n }\n out_guide = vec4(center.x, variance, 0.0, 1.0);\n}`\n});\n\n/**\n * One joint NL-means pass; see createJNLMFilterWGSL. The first pass decodes\n * the display-encoded composition to linear light, the last encodes it again.\n */\nconst filterFragment = new FragmentShader({\n name: 'jnlmFilter',\n outputs: ['color', 'guide'],\n defines: {\n SEARCH_RADIUS: JNLM_DEFAULT_SHAPE.searchRadius,\n PATCH_RADIUS: JNLM_DEFAULT_SHAPE.patchRadius,\n INV_ALBEDO_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / JNLM_DEFAULT_SHAPE.normalBandwidth ** 2).toFixed(6)\n },\n uniforms: {\n guideTex: Shader.uniform('sampler2D'),\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n colorSensitivity: Shader.uniform('float', JNLM_DEFAULT_COLOR_SENSITIVITY),\n dilation: Shader.uniform('int', 1),\n decodeInput: Shader.uniform('bool', 0),\n encodeOutput: Shader.uniform('bool', 0)\n },\n main: glsl`\n#define PATCH_SIZE ((2 * PATCH_RADIUS + 1) * (2 * PATCH_RADIUS + 1))\n// Variance cancellation strength alpha of the paper.\n#define VARIANCE_CANCELLATION 1.0\n// Lower bound of the center weight, so a pixel unlike all of its neighbors\n// (a thin highlight) is kept rather than replaced by them.\n#define CENTER_WEIGHT_MIN 0.01\n#define INV_COVERAGE_BANDWIDTH2 ${(1 / JNLM_COVERAGE_BANDWIDTH ** 2).toFixed(6)}\n\nivec2 imageSize;\n\nvec2 loadGuide(ivec2 p) {\n return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;\n}\n\n// Premultiplied linear color.\nvec4 loadColor(ivec2 p) {\n vec4 c = load_colorTex(p, 0);\n if (decodeInput) c.rgb = mix(pow((max(c.rgb, 0.0) + 0.055) / 1.055, vec3(2.4)),\n c.rgb / 12.92, lessThanEqual(c.rgb, vec3(0.04045)));\n return vec4(c.rgb * c.a, c.a);\n}\n\nfloat featureDistance(ivec2 q, vec4 centerAlbedo, vec3 centerNormal) {\n vec4 albedo = load_albedoTex(q, 0);\n // Match WebGPU: protect relative RGB contrast, including dark textures,\n // while keeping coverage differences in absolute units.\n vec3 albedoScale = max((albedo.rgb + centerAlbedo.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 albedoDelta = (albedo.rgb - centerAlbedo.rgb) / albedoScale;\n float coverageDelta = albedo.a - centerAlbedo.a;\n vec3 normalDelta = load_normalTex(q, 0).rgb - centerNormal;\n return max(\n dot(albedoDelta, albedoDelta) * INV_ALBEDO_BANDWIDTH2\n + coverageDelta * coverageDelta * INV_COVERAGE_BANDWIDTH2,\n dot(normalDelta, normalDelta) * INV_NORMAL_BANDWIDTH2\n );\n}\n\nvoid main() {\n imageSize = guideTexRegion();\n ivec2 p = ivec2(gl_FragCoord.xy);\n vec4 centerAlbedo = load_albedoTex(p, 0);\n vec4 centerNormalTexel = load_normalTex(p, 0);\n vec3 centerNormal = centerNormalTexel.rgb;\n // Primary misses show the background directly. It has no features that\n // protect its detail and no noise beyond antialiasing, so keep it.\n if (centerNormalTexel.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {\n vec4 c = loadColor(p);\n vec3 rgb = c.rgb / max(c.a, 1e-6);\n if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,\n rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));\n out_color = vec4(rgb, c.a);\n out_guide = vec4(loadGuide(p), 0.0, 1.0);\n return;\n }\n\n vec2 centerPatch[PATCH_SIZE];\n int k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n centerPatch[k] = loadGuide(p + ivec2(dx, dy) * dilation);\n k++;\n }\n }\n float k2 = colorSensitivity * colorSensitivity;\n\n vec4 sum = vec4(0.0);\n vec3 featureScale = max(centerAlbedo.rgb, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 featureSum = vec3(0.0);\n vec3 featureSquareSum = vec3(0.0);\n vec3 featureColorSum = vec3(0.0);\n float guideSum = 0.0;\n float guideVarianceSum = 0.0;\n float weightSum = 0.0;\n float maxWeight = 0.0;\n for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {\n for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {\n ivec2 q = p + ivec2(sx, sy) * dilation;\n if (\n (sx == 0 && sy == 0) ||\n q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y\n ) continue;\n float features = featureDistance(q, centerAlbedo, centerNormal);\n if (features > 16.0) continue;\n\n float colorDistance = 0.0;\n k = 0;\n for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n vec2 a = centerPatch[k];\n vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);\n float delta = a.x - b.x;\n colorDistance += (delta * delta\n - VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))\n / (1e-10 + k2 * (a.y + b.y));\n k++;\n }\n }\n colorDistance /= float(PATCH_SIZE);\n\n float weight = exp(-max(max(colorDistance, 0.0), features));\n vec2 g = loadGuide(q);\n // Filter premultiplied color so coverage and color stay consistent.\n vec3 a = (load_albedoTex(q, 0).rgb - centerAlbedo.rgb) / featureScale;\n vec4 value = loadColor(q);\n sum += value * weight;\n featureSum += a * weight;\n featureSquareSum += a * a * weight;\n featureColorSum += a * value.rgb * weight;\n guideSum += g.x * weight;\n guideVarianceSum += g.y * weight * weight;\n weightSum += weight;\n maxWeight = max(maxWeight, weight);\n }\n }\n\n // Weight the center like its most similar neighbor (Buades et al. 2005)\n // instead of 1, so isolated outliers are not kept unfiltered.\n vec4 center = loadColor(p);\n vec2 centerGuide = loadGuide(p);\n float centerWeight = max(maxWeight, CENTER_WEIGHT_MIN);\n float totalWeight = weightSum + centerWeight;\n vec4 mean = (sum + center * centerWeight) / totalWeight;\n // Fit each color channel against relative albedo with the same JNLM weights.\n // Centering at this pixel avoids cancellation when the feature is constant.\n vec3 meanFeature = featureSum / totalWeight;\n vec3 featureVariance = max(featureSquareSum / totalWeight - meanFeature * meanFeature, vec3(0.0));\n vec3 covariance = featureColorSum / totalWeight - meanFeature * mean.rgb;\n // A 1% contrast ridge stabilizes flat guides. Bound the response between no\n // texture dependence and multiplicative albedo modulation; specular color\n // with an unrelated albedo falls back to the weighted mean.\n vec3 meanAlbedo = centerAlbedo.rgb + meanFeature * featureScale;\n vec3 maximumSlope = mean.rgb * featureScale / max(meanAlbedo, vec3(${JNLM_ALBEDO_FLOOR}));\n vec3 slope = clamp(covariance / (featureVariance + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), maximumSlope);\n vec3 corrected = mean.rgb - slope * meanFeature;\n vec4 filtered = vec4(max(corrected, vec3(0.0)), max(mean.a, 0.0));\n vec3 rgb = filtered.a > 1e-6\n ? filtered.rgb / max(filtered.a, 1e-6)\n : center.rgb / max(center.a, 1e-6);\n if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,\n rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));\n out_color = vec4(rgb, filtered.a);\n out_guide = vec4(\n (guideSum + centerGuide.x * centerWeight) / totalWeight,\n (guideVarianceSum + centerGuide.y * centerWeight * centerWeight)\n / (totalWeight * totalWeight),\n 0.0,\n 1.0\n );\n}`\n});\n\nexport interface WebGLJNLMInputs {\n width: number;\n height: number;\n /** Main trace pass moments: guide sum, sum of squares and count. */\n moments: Texture2D;\n /** Catcher trace pass moments, when the scene has a shadow catcher. */\n catcherMoments?: Texture2D;\n /** Display-encoded composition to filter. */\n color: Texture2D;\n albedo: Texture2D;\n normal: Texture2D;\n /** Normalized shadow-catcher mask; red is the catcher coverage. */\n shadowCatcher: Texture2D;\n strength: number;\n shape: JNLMFilterShape;\n}\n\nconst floatOutput = {\n type: constants.FLOAT,\n minFilter: constants.NEAREST,\n magFilter: constants.NEAREST\n};\n\nexport class WebGLJNLMDenoisePass {\n private _renderer: WebGLDevice;\n private _guidePass: WebGLFullQuadPass<'momentsTex' | 'catcherMomentsTex', 'guide'>;\n private _variancePass: WebGLFullQuadPass<'rawGuideTex', 'guide'>;\n // Two instances so consecutive passes ping-pong between their outputs.\n private _filterPasses: WebGLFullQuadPass<\n 'guideTex' | 'colorTex' | 'albedoTex' | 'normalTex' | 'shadowCatcherTex',\n 'color' | 'guide'\n >[];\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._guidePass = new WebGLFullQuadPass('jnlmGuide', renderer, {\n shader: guideFragment,\n outputParams: { guide: floatOutput }\n });\n this._variancePass = new WebGLFullQuadPass('jnlmVariance', renderer, {\n shader: varianceFragment,\n outputParams: { guide: floatOutput }\n });\n this._filterPasses = [0, 1].map(() =>\n new WebGLFullQuadPass('jnlmFilter', renderer, {\n shader: filterFragment,\n outputParams: {\n color: { type: constants.HALF_FLOAT },\n guide: floatOutput\n }\n })\n );\n }\n\n /** Runs the denoiser and returns the display-encoded result. */\n render(inputs: WebGLJNLMInputs, trace?: string[]): Texture2D {\n const { width, height, shape } = inputs;\n const passes = [this._guidePass, this._variancePass, ...this._filterPasses];\n passes.forEach((pass) => pass.setSize(width, height));\n this._guidePass.createPass({\n momentsTex: inputs.moments,\n catcherMomentsTex: inputs.catcherMoments ?? this._renderer.emptyTexture\n });\n this._variancePass.createPass({ rawGuideTex: this._guidePass.getOutput('guide') });\n\n const sensitivity = JNLM_DEFAULT_COLOR_SENSITIVITY * Math.max(inputs.strength, 1e-3);\n const iterations = Math.min(JNLM_MAX_ITERATIONS, Math.max(1, Math.round(shape.iterations)));\n let guide = this._variancePass.getOutput('guide');\n let color = inputs.color;\n for (let i = 0; i < iterations; i++) {\n const pass = this._filterPasses[i % 2];\n pass.setDefines({\n SEARCH_RADIUS: shape.searchRadius,\n // Numeric zero removes a define in the WebGL shader builder.\n PATCH_RADIUS: String(shape.patchRadius),\n INV_ALBEDO_BANDWIDTH2: (1 / shape.albedoBandwidth ** 2).toFixed(6),\n INV_NORMAL_BANDWIDTH2: (1 / shape.normalBandwidth ** 2).toFixed(6)\n });\n pass.setUniforms({\n colorSensitivity: sensitivity,\n dilation: jnlmPassDilation(i),\n decodeInput: i === 0,\n encodeOutput: i === iterations - 1\n });\n if (trace) {\n if (i === 0) trace.push('Decode:DisplayLinear', 'Denoise:DisplayLinear');\n if (i === iterations - 1) trace.push('Encode:DisplayEncoded');\n }\n pass.createPass({\n guideTex: guide,\n colorTex: color,\n albedoTex: inputs.albedo,\n normalTex: inputs.normal,\n shadowCatcherTex: inputs.shadowCatcher\n });\n guide = pass.getOutput('guide');\n color = pass.getOutput('color');\n }\n return color;\n }\n\n reserveCapacity() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach(pass => pass.reserveCapacity());\n }\n\n retainOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.retainOutput(texture)); }\n releaseOutput(texture: Texture2D) { this._filterPasses.forEach(pass => pass.releaseOutput(texture)); }\n\n getMemoryBytes() {\n return [this._guidePass, this._variancePass, ...this._filterPasses]\n .reduce((sum, pass) => sum + pass.getMemoryBytes(), 0);\n }\n\n dispose() {\n [this._guidePass, this._variancePass, ...this._filterPasses].forEach((pass) =>\n pass.dispose()\n );\n }\n}\n"]}
|
|
@@ -42,11 +42,11 @@ vec4 mask = sample_shadowCatcherTex(v_Texcoord);
|
|
|
42
42
|
vec4 background = sample_catcherBackgroundTex(v_Texcoord);
|
|
43
43
|
float hit = sample_albedoTex(v_Texcoord).a;
|
|
44
44
|
|
|
45
|
-
float
|
|
46
|
-
float
|
|
45
|
+
float qZ = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;
|
|
46
|
+
float iT = max(hit - mask.b * qZ, 0.0);
|
|
47
47
|
out_foreground = vec4(
|
|
48
|
-
(light.rgb - background.rgb *
|
|
49
|
-
/ (
|
|
48
|
+
(light.rgb - background.rgb * qZ)
|
|
49
|
+
/ (iT > 0.0 ? iT : sampleCount),
|
|
50
50
|
clamp((light.a - background.a) / sampleCount, 0.0, 1.0)
|
|
51
51
|
);
|
|
52
52
|
out_catcherBackground = background / sampleCount;
|
|
@@ -75,6 +75,9 @@ out_catcherBackground = background / sampleCount;
|
|
|
75
75
|
normalTex: rayTracePass.getOutput('normal'),
|
|
76
76
|
shadowCatcherTex: rayTracePass.hasShadowCatcher()
|
|
77
77
|
? rayTracePass.getOutput('shadowCatcher')
|
|
78
|
+
: this._renderer.emptyTexture,
|
|
79
|
+
catcherMomentsTex: rayTracePass.hasShadowCatcher()
|
|
80
|
+
? rayTracePass.getOutput('catcherMoments')
|
|
78
81
|
: this._renderer.emptyTexture
|
|
79
82
|
}, undefined, { clear: true });
|
|
80
83
|
if (rayTracePass.hasShadowCatcher()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebGLRayTraceOutputPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLRayTraceOutputPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,SAAS,EAA0B,MAAM,YAAY,CAAC;AAC/D,OAAO,uBAAuB,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAW3D,+EAA+E;AAC/E,MAAM,OAAO,uBAAuB;IACjB,SAAS,CAAc;IACvB,KAAK,
|
|
1
|
+
{"version":3,"file":"WebGLRayTraceOutputPass.js","sourceRoot":"","sources":["../../src/renderer/WebGLRayTraceOutputPass.ts"],"names":[],"mappings":"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","sourcesContent":["import { FragmentShader, Shader, glsl } from './shader.js';\nimport { constants, WebGLDevice, Texture2D } from './webgl.js';\nimport normalizeRayTraceOutput from './glsl/normalizeRayTraceOutput.frag.js';\nimport { WebGLFullQuadPass } from './WebGLFullQuadPass.js';\nimport WebGLRayTracePass from './WebGLRayTracePass.js';\n\ntype RayTraceInput =\n | 'colorTex'\n | 'albedoTex'\n | 'normalTex'\n | 'shadowCatcherTex';\ntype LayerOutput = 'foreground' | 'catcherBackground';\ntype RayTraceOutput = 'color' | 'albedo' | 'normal' | 'shadowCatcher';\n\n/** Converts the additive ray tracing buffers into display/denoise textures. */\nexport class WebGLRayTraceOutputPass {\n private readonly _renderer: WebGLDevice;\n private readonly _pass: WebGLFullQuadPass<RayTraceInput | 'catcherMomentsTex', RayTraceOutput>;\n\n private readonly _layersPass: WebGLFullQuadPass<\n RayTraceInput | 'catcherBackgroundTex', LayerOutput\n >;\n\n constructor(renderer: WebGLDevice) {\n this._renderer = renderer;\n this._pass = new WebGLFullQuadPass('rayTraceOutput', renderer, {\n shader: normalizeRayTraceOutput,\n outputs: ['color', 'albedo', 'normal', 'shadowCatcher'],\n outputParams: {\n color: {\n type: constants.HALF_FLOAT,\n minFilter: constants.LINEAR,\n magFilter: constants.LINEAR\n },\n albedo: { type: constants.UNSIGNED_BYTE },\n normal: { type: constants.UNSIGNED_BYTE },\n shadowCatcher: { type: constants.HALF_FLOAT }\n }\n });\n this._layersPass = new WebGLFullQuadPass('rayTraceLayers', renderer, {\n shader: new FragmentShader({\n name: 'normalizeRayTraceLayers',\n outputs: ['foreground', 'catcherBackground'],\n uniforms: {\n colorTex: Shader.uniform('sampler2D'),\n albedoTex: Shader.uniform('sampler2D'),\n normalTex: Shader.uniform('sampler2D'),\n shadowCatcherTex: Shader.uniform('sampler2D'),\n catcherBackgroundTex: Shader.uniform('sampler2D'),\n sampleCount: Shader.uniform('float', 1)\n },\n main: glsl`\nvoid main() {\n vec4 light = sample_colorTex(v_Texcoord);\n vec4 mask = sample_shadowCatcherTex(v_Texcoord);\n vec4 background = sample_catcherBackgroundTex(v_Texcoord);\n float hit = sample_albedoTex(v_Texcoord).a;\n // Full spectral beauty has three wavelength contributions per shadow sample.\n float contributions = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;\n float foregroundHit = max(hit - mask.b * contributions, 0.0);\n out_foreground = vec4(\n (light.rgb - background.rgb * contributions)\n / (foregroundHit > 0.0 ? foregroundHit : sampleCount),\n clamp((light.a - background.a) / sampleCount, 0.0, 1.0)\n );\n out_catcherBackground = background / sampleCount;\n}`\n }),\n outputs: ['foreground', 'catcherBackground'],\n outputParams: {\n foreground: { type: constants.HALF_FLOAT },\n catcherBackground: { type: constants.HALF_FLOAT }\n }\n });\n }\n\n setSize(width: number, height: number) {\n this._pass.setSize(width, height);\n this._layersPass.setSize(width, height);\n }\n\n setSampleCount(sampleCount: number) {\n this._pass.setUniform('sampleCount', Math.max(sampleCount, 1));\n this._layersPass.setUniform('sampleCount', Math.max(sampleCount, 1));\n }\n\n createPass(rayTracePass: WebGLRayTracePass) {\n this._pass.setOutputs(rayTracePass.hasShadowCatcher() ? ['color', 'albedo', 'normal', 'shadowCatcher'] : ['color', 'albedo', 'normal']);\n this._pass.createPass(\n {\n colorTex: rayTracePass.getOutput('color'),\n albedoTex: rayTracePass.getOutput('albedo'),\n normalTex: rayTracePass.getOutput('normal'),\n shadowCatcherTex: rayTracePass.hasShadowCatcher()\n ? rayTracePass.getOutput('shadowCatcher')\n : this._renderer.emptyTexture,\n catcherMomentsTex: rayTracePass.hasShadowCatcher()\n ? rayTracePass.getOutput('catcherMoments')\n : this._renderer.emptyTexture\n },\n undefined,\n { clear: true }\n );\n if (rayTracePass.hasShadowCatcher()) {\n this._layersPass.setOutputs(['foreground', 'catcherBackground']);\n this._layersPass.createPass({\n colorTex: rayTracePass.getOutput('color'),\n albedoTex: rayTracePass.getOutput('albedo'),\n normalTex: rayTracePass.getOutput('normal'),\n shadowCatcherTex: rayTracePass.getOutput('shadowCatcher'),\n catcherBackgroundTex: rayTracePass.getOutput('catcherBackground')\n }, undefined, { clear: true });\n } else {\n this._layersPass.setOutputs([]);\n }\n }\n\n getOutput(label: RayTraceOutput | LayerOutput): Texture2D {\n return label === 'foreground' || label === 'catcherBackground'\n ? this._layersPass.getOutput(label) ?? this._renderer.emptyTexture : this._pass.getOutput(label) ?? this._renderer.emptyTexture;\n }\n\n retainOutput(texture: Texture2D) { this._pass.retainOutput(texture); this._layersPass.retainOutput(texture); }\n releaseOutput(texture: Texture2D) { this._pass.releaseOutput(texture); this._layersPass.releaseOutput(texture); }\n\n getMemoryBytes() { return this._pass.getMemoryBytes() + this._layersPass.getMemoryBytes(); }\n\n dispose() {\n this._pass.dispose();\n this._layersPass.dispose();\n }\n}\n\n"]}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
import { WebGLAov } from './WebGLAov.js';
|
|
2
|
+
import { type AovKind } from './aov.js';
|
|
1
3
|
import { type SamplingPattern } from './sampling.js';
|
|
2
4
|
import { type DepthSampleArea } from './depthQuery.js';
|
|
3
5
|
import { WebGLDevice as WebGLRenderer, Texture2D as WebGLTexture2D } from './webgl.js';
|
|
4
6
|
import Mesh from '../scene/Mesh.js';
|
|
5
7
|
import OpenPBRMaterial from '../scene/OpenPBRMaterial.js';
|
|
6
|
-
import { SceneBackground, SceneLight } from '../scene/Scene.js';
|
|
8
|
+
import type { SceneBackground, SceneLight } from '../scene/Scene.js';
|
|
7
9
|
import Camera from '../scene/Camera.js';
|
|
8
10
|
import Geometry from '../scene/Geometry.js';
|
|
9
11
|
declare class WebGLRayTracePass {
|
|
12
|
+
private _aovPrimitiveCache;
|
|
10
13
|
private readonly _renderer;
|
|
11
14
|
private _meshes;
|
|
15
|
+
private _emissiveActive;
|
|
16
|
+
private _directLightLegacy?;
|
|
17
|
+
private _emissiveCache;
|
|
18
|
+
private _emissiveTex;
|
|
12
19
|
private _sceneEnvironment;
|
|
13
20
|
private _rectLightTextures;
|
|
14
21
|
private _analyticLights;
|
|
@@ -44,12 +51,14 @@ declare class WebGLRayTracePass {
|
|
|
44
51
|
private _envMap;
|
|
45
52
|
private _envMapDistribution;
|
|
46
53
|
private _envImageSource?;
|
|
54
|
+
private readonly _skySource;
|
|
47
55
|
private _backgroundTex;
|
|
48
56
|
private _hasEnvMap;
|
|
49
57
|
private _hasBackground;
|
|
50
58
|
private _groundedBackgroundParams;
|
|
51
59
|
private _groundedBackgroundCenter;
|
|
52
60
|
private _backgroundMapTransform;
|
|
61
|
+
private _backgroundMapRotation;
|
|
53
62
|
private _bounces;
|
|
54
63
|
private _bevelSamples;
|
|
55
64
|
private _clamping?;
|
|
@@ -74,6 +83,8 @@ declare class WebGLRayTracePass {
|
|
|
74
83
|
private _viewProjInv;
|
|
75
84
|
private _apertureRadius;
|
|
76
85
|
private _focusDistance;
|
|
86
|
+
private _aovPass;
|
|
87
|
+
private _aovCenter;
|
|
77
88
|
private _tracePasses;
|
|
78
89
|
private readonly _depthPass;
|
|
79
90
|
private readonly _depthAbort;
|
|
@@ -81,6 +92,7 @@ declare class WebGLRayTracePass {
|
|
|
81
92
|
private _hasShadowCatcher;
|
|
82
93
|
private _spectral;
|
|
83
94
|
constructor(renderer: WebGLRenderer);
|
|
95
|
+
preparePrograms(): boolean;
|
|
84
96
|
createPass(clear: boolean, tile: {
|
|
85
97
|
x: number;
|
|
86
98
|
y: number;
|
|
@@ -105,7 +117,7 @@ declare class WebGLRayTracePass {
|
|
|
105
117
|
buffer: ArrayBuffer;
|
|
106
118
|
};
|
|
107
119
|
getDiagnostics(): {
|
|
108
|
-
textureAtlas: import("./
|
|
120
|
+
textureAtlas: import("./textureAtlas.js").TextureAtlasStats | undefined;
|
|
109
121
|
};
|
|
110
122
|
private _updateMeshData;
|
|
111
123
|
private _updateMaterialConstants;
|
|
@@ -128,8 +140,9 @@ declare class WebGLRayTracePass {
|
|
|
128
140
|
bevel: boolean;
|
|
129
141
|
dispersionWavelengths: 1 | 3;
|
|
130
142
|
directLightCandidates: number;
|
|
143
|
+
caustics?: import('../Render.js').CausticSettings;
|
|
131
144
|
}): void;
|
|
132
|
-
|
|
145
|
+
setSpectralChannel(channel: number): void;
|
|
133
146
|
setSampleCount(sampleCount: number): void;
|
|
134
147
|
isInvalid(): boolean;
|
|
135
148
|
hasShadowCatcher(): boolean;
|
|
@@ -137,6 +150,8 @@ declare class WebGLRayTracePass {
|
|
|
137
150
|
prepare(): void;
|
|
138
151
|
setSamplingPattern(pattern: SamplingPattern, maxSamples: number, sequenceSeed?: number): boolean;
|
|
139
152
|
setSampleSequenceOffset(_offset: number): void;
|
|
153
|
+
prepareAovs(state: WebGLAov, camera: Camera, width: number, height: number, kinds: readonly AovKind[]): boolean;
|
|
154
|
+
renderAovs(state: WebGLAov, camera: Camera, width: number, height: number, samples: number, cap: number, kinds: readonly AovKind[], sequenceOffset?: number): boolean;
|
|
140
155
|
readDepthSamples(area: DepthSampleArea, aspect?: number): Promise<Float32Array | undefined>;
|
|
141
156
|
dispose(): void;
|
|
142
157
|
}
|