@meimu/mutracer 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +222 -0
- package/LICENSES/FidelityFX-FSR.txt +19 -0
- package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +6260 -5580
- package/docs/api.md +45 -18
- package/docs/materials.md +4 -2
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +3 -0
- package/docs/sampling.md +4 -0
- package/docs/technical/acceleration.md +52 -0
- package/docs/technical/aovs.md +79 -0
- package/docs/technical/caustics.md +109 -0
- package/docs/technical/continuous-spectrum.md +29 -0
- package/docs/technical/display-upscale.md +82 -0
- package/docs/technical/openpbr.md +99 -0
- package/docs/technical/pbrt-import.md +168 -0
- package/docs/technical/tiling.md +74 -0
- package/docs/technical/webgl.md +53 -0
- package/docs/viewer.md +11 -1
- package/lib/Display.d.ts +19 -5
- package/lib/Display.js +10 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -1
- package/lib/Engine.js +30 -2
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +20 -11
- package/lib/Render.js +32 -7
- package/lib/Render.js.map +1 -1
- package/lib/main.d.ts +3 -1
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/renderer/AovPrimitiveCache.js +39 -8
- package/lib/renderer/AovPrimitiveCache.js.map +1 -1
- package/lib/renderer/DisplayPostProcess.d.ts +8 -3
- package/lib/renderer/DisplayPostProcess.js +51 -18
- package/lib/renderer/DisplayPostProcess.js.map +1 -1
- package/lib/renderer/MaterialData.js +7 -2
- package/lib/renderer/MaterialData.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +7 -1
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +2 -2
- package/lib/renderer/TileRender.js +128 -7
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +6 -1
- package/lib/renderer/WGPUAov.js +108 -14
- package/lib/renderer/WGPUAov.js.map +1 -1
- package/lib/renderer/WGPUCanvasSurface.js +12 -1
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPURayTraceOutput.js +12 -12
- package/lib/renderer/WGPURayTracePass.d.ts +17 -4
- package/lib/renderer/WGPURayTracePass.js +194 -71
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +46 -40
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLAov.js +3 -3
- package/lib/renderer/WebGLAov.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
- package/lib/renderer/WebGLFullQuadPass.js +8 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
- package/lib/renderer/WebGLRayTracePass.js +115 -111
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -3
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +57 -57
- package/lib/renderer/aov.d.ts +13 -1
- package/lib/renderer/aov.js +21 -2
- package/lib/renderer/aov.js.map +1 -1
- package/lib/renderer/aovDisplay.js +2 -2
- package/lib/renderer/aovDisplay.js.map +1 -1
- package/lib/renderer/binnedSahBvh.d.ts +2 -1
- package/lib/renderer/binnedSahBvh.js +24 -17
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +3 -1
- package/lib/renderer/bvhAccel.js +36 -6
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +1 -1
- package/lib/renderer/cameraUniform.js +6 -2
- package/lib/renderer/cameraUniform.js.map +1 -1
- package/lib/renderer/compactVertices.d.ts +14 -0
- package/lib/renderer/compactVertices.js +124 -0
- package/lib/renderer/compactVertices.js.map +1 -0
- package/lib/renderer/easu.d.ts +11 -0
- package/lib/renderer/easu.js +156 -0
- package/lib/renderer/easu.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +1 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +3 -2
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +44 -36
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
- package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
- package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
- package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
- package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +12 -6
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.js +233 -170
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
- package/lib/renderer/openPbrEnergyLut.js +18 -1
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/pathLimits.d.ts +5 -4
- package/lib/renderer/pathLimits.js +6 -5
- package/lib/renderer/pathLimits.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.d.ts +2 -0
- package/lib/renderer/prepareMeshBVH.js +5 -3
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +1 -1
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +1 -1
- package/lib/renderer/researchTransport.js.map +1 -1
- package/lib/renderer/sceneAssembly.d.ts +1 -1
- package/lib/renderer/sceneAssembly.js +4 -3
- package/lib/renderer/sceneAssembly.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.d.ts +1 -1
- package/lib/renderer/sceneChangeDetector.js +3 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
- package/lib/renderer/sceneLayoutSchema.js +2 -2
- package/lib/renderer/sceneLayoutSchema.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +3 -2
- package/lib/renderer/scenePreparation.js +18 -2
- package/lib/renderer/scenePreparation.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.js +2 -2
- package/lib/renderer/staticBvhPreparation.d.ts +9 -0
- package/lib/renderer/staticBvhPreparation.js +8 -2
- package/lib/renderer/staticBvhPreparation.js.map +1 -1
- package/lib/renderer/surfaceHit.d.ts +10 -0
- package/lib/renderer/surfaceHit.js +22 -0
- package/lib/renderer/surfaceHit.js.map +1 -0
- package/lib/renderer/tangentRequirements.d.ts +2 -0
- package/lib/renderer/tangentRequirements.js +7 -0
- package/lib/renderer/tangentRequirements.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +4 -0
- package/lib/renderer/textureAtlas.js +48 -2
- package/lib/renderer/textureAtlas.js.map +1 -1
- package/lib/renderer/webgl.js +4 -0
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/webglVertexAttributes.d.ts +17 -0
- package/lib/renderer/webglVertexAttributes.js +44 -0
- package/lib/renderer/webglVertexAttributes.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +2 -2
- package/lib/renderer/wgpuMaterialConstants.js +4 -3
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
- package/lib/renderer/wgpuSceneUniform.js +2 -2
- package/lib/renderer/wgpuSceneUniform.js.map +1 -1
- package/lib/renderer/wgpuShaderSource.d.ts +15 -0
- package/lib/renderer/wgpuShaderSource.js +1 -1
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
- package/lib/renderer/wgsl/causticLight.compute.js +121 -119
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
- package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
- 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.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/easu.wgsl.js +80 -0
- package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.js +89 -89
- package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +11 -0
- package/lib/settings/render.js +1 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +21 -14
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +5 -2
- package/lib/oidnBundledWeights.cdn.d.ts +0 -2
- package/lib/oidnBundledWeights.cdn.js +0 -5
- package/lib/oidnBundledWeights.cdn.js.map +0 -1
- package/lib/renderer/bvh.worker.d.ts +0 -1
- package/lib/renderer/bvh.worker.js +0 -16
- package/lib/renderer/bvh.worker.js.map +0 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
- package/lib/renderer/bvhWorkerBuild.js +0 -17
- package/lib/renderer/bvhWorkerBuild.js.map +0 -1
- package/lib/renderer/lightCore.d.ts +0 -12
- package/lib/renderer/lightCore.js +0 -13
- package/lib/renderer/lightCore.js.map +0 -1
- package/lib/renderer/materialCore.d.ts +0 -8
- package/lib/renderer/materialCore.js +0 -9
- package/lib/renderer/materialCore.js.map +0 -1
- package/lib/scene/PixelTexture.d.ts +0 -6
- package/lib/scene/PixelTexture.js +0 -10
- package/lib/scene/PixelTexture.js.map +0 -1
- package/lib/util/studioLighting.d.ts +0 -18
- package/lib/util/studioLighting.js +0 -36
- package/lib/util/studioLighting.js.map +0 -1
package/lib/renderer/WebGLAov.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import displayShader from './glsl/aovDisplay.frag.js';
|
|
2
2
|
import { WebGLFullQuadPass } from './WebGLFullQuadPass.js';
|
|
3
|
-
import {
|
|
3
|
+
import { aovLaneKind } from './aov.js';
|
|
4
4
|
import { AOV_ID_COMPONENTS, validateAovDisplay } from './aovDisplay.js';
|
|
5
5
|
import { AovHistory } from './aov.js';
|
|
6
6
|
import { Texture2D, FrameBuffer } from './webgl.js';
|
|
@@ -54,7 +54,7 @@ export class WebGLAov {
|
|
|
54
54
|
this.displayPass ??= new WebGLFullQuadPass('AOV display', this.renderer, { shader: displayShader, outputs: ['color'] });
|
|
55
55
|
const pass = this.displayPass;
|
|
56
56
|
pass.setSize(this.width, this.height);
|
|
57
|
-
pass.setUniforms({ kind:
|
|
57
|
+
pass.setUniforms({ kind: aovLaneKind(kind), samples: this.samples, mapping: [...options.depthRange, options.positionScale, options.motionScale], idComponent: AOV_ID_COMPONENTS.indexOf(options.idComponent) });
|
|
58
58
|
pass.createPass({ ...this.accumulation[(this.samples - 1) % 2], identity: this.center.id, motion: this.center.motion });
|
|
59
59
|
return pass.getOutput('color');
|
|
60
60
|
}
|
|
@@ -62,7 +62,7 @@ export class WebGLAov {
|
|
|
62
62
|
const gl = this.renderer.gl, framebuffer = new FrameBuffer(), width = this.width, height = this.height;
|
|
63
63
|
try {
|
|
64
64
|
const accumulated = this.accumulation[(this.samples - 1) % 2];
|
|
65
|
-
const name = kind === 'depth' || kind === 'roughness' ? 'geometry' : kind ===
|
|
65
|
+
const name = kind === 'depth' || kind === 'roughness' ? 'geometry' : aovLaneKind(kind) === 3 ? 'diffuse' : aovLaneKind(kind) === 4 ? 'specular' : 'position';
|
|
66
66
|
framebuffer.bind(this.renderer, [kind === 'id' ? this.center.id : kind === 'motion' ? this.center.motion : accumulated[name]]);
|
|
67
67
|
if (kind === 'id') {
|
|
68
68
|
const source = new Uint32Array(width * height * 4), data = new Uint32Array(source.length);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebGLAov.js","sourceRoot":"","sources":["../../src/renderer/WebGLAov.ts"],"names":[],"mappings":"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","sourcesContent":["import displayShader from './glsl/aovDisplay.frag.js';\nimport {WebGLFullQuadPass} from './WebGLFullQuadPass.js';\nimport {AOV_KINDS} from './aov.js';\nimport {AOV_ID_COMPONENTS, validateAovDisplay, type AovDisplayOptions} from './aovDisplay.js';\nimport {AovHistory, type AovKind, type AovFrameSnapshot} from './aov.js';\nimport {Texture2D, FrameBuffer, type WebGLDevice} from './webgl.js';\nimport {readRgbaPixels} from './WebGLReadback.js';\nconst names = ['geometry','position','diffuse','specular'] as const;\nexport class WebGLAov {\n private displayPass?: WebGLFullQuadPass<string,'color'>;\n readonly history=new AovHistory();\n width=0; height=0; samples=0; centerReady=false; frame?: AovFrameSnapshot;\n readonly accumulation: Record<typeof names[number],Texture2D>[]=[];\n previousCenter: {id:Texture2D; motion:Texture2D} | undefined;\n center: {id:Texture2D; motion:Texture2D} | undefined;\n scene = new Texture2D({type: 5125, minFilter:9728,magFilter:9728});\n constructor(readonly renderer: WebGLDevice) {}\n reset(){if(this.centerReady){const swap=this.previousCenter;this.previousCenter=this.center;this.center=swap;}this.samples=0;this.centerReady=false;this.frame=undefined;}\n resize(width:number,height:number){\n if(width===this.width && height===this.height)return;\n this.dispose();this.history.clear();this.reset();this.width=width;this.height=height;\n const options={width,height,type:5126,minFilter:9728,magFilter:9728};\n for(let i=0;i<2;i++)this.accumulation.push(Object.fromEntries(names.map(n=>[n,new Texture2D(options)])) as Record<typeof names[number],Texture2D>);\n this.previousCenter={id:new Texture2D({...options,type:5125}),motion:new Texture2D(options)};\n this.center={id:new Texture2D({...options,type:5125}),motion:new Texture2D(options)};\n }\n setScene(words:Uint32Array){\n const width=Math.min(1024,Math.max(1,Math.ceil(words.length/4))),height=Math.ceil(words.length/(width*4));\n const data=new Uint32Array(width*height*4);data.set(words);\n this.scene.source={data,width,height};\n }\n visualize(kind:AovKind,options:AovDisplayOptions):Texture2D {\n if(!this.samples || !this.center)throw new Error('AOV output is not ready');\n validateAovDisplay(options);\n this.displayPass??=new WebGLFullQuadPass('AOV display',this.renderer,{shader:displayShader,outputs:['color']});\n const pass=this.displayPass;pass.setSize(this.width,this.height);pass.setUniforms({kind:AOV_KINDS.indexOf(kind),samples:this.samples,mapping:[...options.depthRange,options.positionScale,options.motionScale],idComponent:AOV_ID_COMPONENTS.indexOf(options.idComponent)});\n pass.createPass({...this.accumulation[(this.samples-1)%2],identity:this.center.id,motion:this.center.motion});return pass.getOutput('color');\n }\n async read(kind:AovKind){\n const gl=this.renderer.gl, framebuffer=new FrameBuffer(), width=this.width,height=this.height;\n try{\n const accumulated=this.accumulation[(this.samples-1)%2];\n const name=kind==='depth'||kind==='roughness'?'geometry':kind==='diffuseAlbedo'?'diffuse':kind==='specularAlbedo'?'specular':'position';\n framebuffer.bind(this.renderer,[kind==='id'?this.center!.id:kind==='motion'?this.center!.motion:accumulated[name]]);\n if(kind==='id'){\n const source=new Uint32Array(width*height*4),data=new Uint32Array(source.length);\n gl.readPixels(0,0,width,height,gl.RGBA_INTEGER,gl.UNSIGNED_INT,source);\n for(let y=0;y<height;y++)data.set(source.subarray((height-1-y)*width*4,(height-y)*width*4),y*width*4);\n return {width,height,data};\n }\n const data=readRgbaPixels(gl,width,height,false);\n if(kind==='motion'){for(let o=2;o<data.length;o+=4)data[o]=0;return {width,height,data};}\n framebuffer.bind(this.renderer,[accumulated.position]);const coverage=readRgbaPixels(gl,width,height,false);\n for(let p=0;p<width*height;p++){\n const o=p*4,hits=coverage[o+3],inv=hits>0?1/hits:0,alpha=hits/Math.max(1,this.samples);\n if(kind==='depth')data.set([data[o]*inv,0,0,alpha],o);\n else if(kind==='roughness')data.set([data[o+1]*inv,data[o+2]*inv,data[o+3]*inv,alpha],o);\n else if(kind==='position')data.set([data[o]*inv,data[o+1]*inv,data[o+2]*inv,alpha],o);\n else{const count=data[o+3],scale=count>0?1/count:0;data.set([data[o]*scale,data[o+1]*scale,data[o+2]*scale,count/Math.max(1,this.samples)],o);}\n }\n return {width,height,data};\n }finally{framebuffer.dispose(this.renderer);}\n }\n get bytes(){return this.width*this.height*(2*64+64+(this.displayPass?4:0))+this.scene.width*this.scene.height*16;}\n dispose(){this.displayPass?.dispose();this.displayPass=undefined;const gl=this.renderer.gl;for(const set of this.accumulation)for(const texture of Object.values(set))texture.dispose(gl);this.accumulation.length=0;this.center?.id.dispose(gl);this.center?.motion.dispose(gl);this.center=undefined;this.previousCenter?.id.dispose(gl);this.previousCenter?.motion.dispose(gl);this.previousCenter=undefined;this.scene.dispose(gl);}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WebGLAov.js","sourceRoot":"","sources":["../../src/renderer/WebGLAov.ts"],"names":[],"mappings":"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","sourcesContent":["import displayShader from './glsl/aovDisplay.frag.js';\nimport {WebGLFullQuadPass} from './WebGLFullQuadPass.js';\nimport {aovLaneKind} from './aov.js';\nimport {AOV_ID_COMPONENTS, validateAovDisplay, type AovDisplayOptions} from './aovDisplay.js';\nimport {AovHistory, type AovKind, type AovFrameSnapshot} from './aov.js';\nimport {Texture2D, FrameBuffer, type WebGLDevice} from './webgl.js';\nimport {readRgbaPixels} from './WebGLReadback.js';\nconst names = ['geometry','position','diffuse','specular'] as const;\nexport class WebGLAov {\n private displayPass?: WebGLFullQuadPass<string,'color'>;\n readonly history=new AovHistory();\n width=0; height=0; samples=0; centerReady=false; frame?: AovFrameSnapshot;\n readonly accumulation: Record<typeof names[number],Texture2D>[]=[];\n previousCenter: {id:Texture2D; motion:Texture2D} | undefined;\n center: {id:Texture2D; motion:Texture2D} | undefined;\n scene = new Texture2D({type: 5125, minFilter:9728,magFilter:9728});\n constructor(readonly renderer: WebGLDevice) {}\n reset(){if(this.centerReady){const swap=this.previousCenter;this.previousCenter=this.center;this.center=swap;}this.samples=0;this.centerReady=false;this.frame=undefined;}\n resize(width:number,height:number){\n if(width===this.width && height===this.height)return;\n this.dispose();this.history.clear();this.reset();this.width=width;this.height=height;\n const options={width,height,type:5126,minFilter:9728,magFilter:9728};\n for(let i=0;i<2;i++)this.accumulation.push(Object.fromEntries(names.map(n=>[n,new Texture2D(options)])) as Record<typeof names[number],Texture2D>);\n this.previousCenter={id:new Texture2D({...options,type:5125}),motion:new Texture2D(options)};\n this.center={id:new Texture2D({...options,type:5125}),motion:new Texture2D(options)};\n }\n setScene(words:Uint32Array){\n const width=Math.min(1024,Math.max(1,Math.ceil(words.length/4))),height=Math.ceil(words.length/(width*4));\n const data=new Uint32Array(width*height*4);data.set(words);\n this.scene.source={data,width,height};\n }\n visualize(kind:AovKind,options:AovDisplayOptions):Texture2D {\n if(!this.samples || !this.center)throw new Error('AOV output is not ready');\n validateAovDisplay(options);\n this.displayPass??=new WebGLFullQuadPass('AOV display',this.renderer,{shader:displayShader,outputs:['color']});\n const pass=this.displayPass;pass.setSize(this.width,this.height);pass.setUniforms({kind:aovLaneKind(kind),samples:this.samples,mapping:[...options.depthRange,options.positionScale,options.motionScale],idComponent:AOV_ID_COMPONENTS.indexOf(options.idComponent)});\n pass.createPass({...this.accumulation[(this.samples-1)%2],identity:this.center.id,motion:this.center.motion});return pass.getOutput('color');\n }\n async read(kind:AovKind){\n const gl=this.renderer.gl, framebuffer=new FrameBuffer(), width=this.width,height=this.height;\n try{\n const accumulated=this.accumulation[(this.samples-1)%2];\n const name=kind==='depth'||kind==='roughness'?'geometry':aovLaneKind(kind)===3?'diffuse':aovLaneKind(kind)===4?'specular':'position';\n framebuffer.bind(this.renderer,[kind==='id'?this.center!.id:kind==='motion'?this.center!.motion:accumulated[name]]);\n if(kind==='id'){\n const source=new Uint32Array(width*height*4),data=new Uint32Array(source.length);\n gl.readPixels(0,0,width,height,gl.RGBA_INTEGER,gl.UNSIGNED_INT,source);\n for(let y=0;y<height;y++)data.set(source.subarray((height-1-y)*width*4,(height-y)*width*4),y*width*4);\n return {width,height,data};\n }\n const data=readRgbaPixels(gl,width,height,false);\n if(kind==='motion'){for(let o=2;o<data.length;o+=4)data[o]=0;return {width,height,data};}\n framebuffer.bind(this.renderer,[accumulated.position]);const coverage=readRgbaPixels(gl,width,height,false);\n for(let p=0;p<width*height;p++){\n const o=p*4,hits=coverage[o+3],inv=hits>0?1/hits:0,alpha=hits/Math.max(1,this.samples);\n if(kind==='depth')data.set([data[o]*inv,0,0,alpha],o);\n else if(kind==='roughness')data.set([data[o+1]*inv,data[o+2]*inv,data[o+3]*inv,alpha],o);\n else if(kind==='position')data.set([data[o]*inv,data[o+1]*inv,data[o+2]*inv,alpha],o);\n else{const count=data[o+3],scale=count>0?1/count:0;data.set([data[o]*scale,data[o+1]*scale,data[o+2]*scale,count/Math.max(1,this.samples)],o);}\n }\n return {width,height,data};\n }finally{framebuffer.dispose(this.renderer);}\n }\n get bytes(){return this.width*this.height*(2*64+64+(this.displayPass?4:0))+this.scene.width*this.scene.height*16;}\n dispose(){this.displayPass?.dispose();this.displayPass=undefined;const gl=this.renderer.gl;for(const set of this.accumulation)for(const texture of Object.values(set))texture.dispose(gl);this.accumulation.length=0;this.center?.id.dispose(gl);this.center?.motion.dispose(gl);this.center=undefined;this.previousCenter?.id.dispose(gl);this.previousCenter?.motion.dispose(gl);this.previousCenter=undefined;this.scene.dispose(gl);}\n}\n"]}
|
|
@@ -43,7 +43,7 @@ export declare class WebGLFullQuadPass<I extends string, O extends string> {
|
|
|
43
43
|
outputs?: O[];
|
|
44
44
|
outputParams?: Partial<Record<O, WebGLFullQuadPassOutput>>;
|
|
45
45
|
});
|
|
46
|
-
setShader(shader: FragmentShader): void;
|
|
46
|
+
setShader(shader: FragmentShader, discardUniforms?: readonly string[], discardDefines?: readonly string[]): void;
|
|
47
47
|
reserveCapacity(): void;
|
|
48
48
|
private _samplingShader;
|
|
49
49
|
setSize(width: number, height: number): void;
|
|
@@ -37,9 +37,15 @@ export class WebGLFullQuadPass {
|
|
|
37
37
|
options.outputParams?.[name] || {}
|
|
38
38
|
])));
|
|
39
39
|
}
|
|
40
|
-
setShader(shader) {
|
|
40
|
+
setShader(shader, discardUniforms = [], discardDefines = []) {
|
|
41
|
+
const uniforms = { ...shader.uniforms, ...this._bindings.uniforms };
|
|
42
|
+
const defines = { ...shader.defines, ...this._bindings.defines };
|
|
43
|
+
for (const name of discardUniforms)
|
|
44
|
+
delete uniforms[name];
|
|
45
|
+
for (const name of discardDefines)
|
|
46
|
+
delete defines[name];
|
|
41
47
|
this._sourceShader = shader;
|
|
42
|
-
this._bindings = new WebGLProgramBindings(this._samplingShader(shader, this._reserveCapacity,
|
|
48
|
+
this._bindings = new WebGLProgramBindings(this._samplingShader(shader, this._reserveCapacity, uniforms, defines));
|
|
43
49
|
}
|
|
44
50
|
reserveCapacity() {
|
|
45
51
|
if (this._reserveCapacity)
|
|
@@ -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, 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"]}
|
|
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, discardUniforms: readonly string[] = [], discardDefines: readonly string[] = []) {\n const uniforms = {...shader.uniforms, ...this._bindings.uniforms};\n const defines = {...shader.defines, ...this._bindings.defines};\n for (const name of discardUniforms) delete uniforms[name];\n for (const name of discardDefines) delete defines[name];\n this._sourceShader = shader;\n this._bindings = new WebGLProgramBindings(this._samplingShader(\n shader, this._reserveCapacity, uniforms, 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"]}
|
|
@@ -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 mF = 0.0;
|
|
49
|
+
float jI = 0.0;
|
|
50
|
+
float oL = 0.0;
|
|
51
|
+
float jB = 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
|
+
oL += value.x;
|
|
56
|
+
jB += value.x * value.x;
|
|
57
57
|
if (value.y >= 0.0) {
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
mF += value.y;
|
|
59
|
+
jI += 1.0;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
float variance;
|
|
64
64
|
if (center.y >= 0.0) {
|
|
65
|
-
variance =
|
|
65
|
+
variance = mF / jI;
|
|
66
66
|
} else {
|
|
67
|
-
float
|
|
68
|
-
variance = max(
|
|
67
|
+
float mE = oL / 9.0;
|
|
68
|
+
variance = max(jB / 9.0 - mE * mE, 0.0) * 9.0 / 8.0;
|
|
69
69
|
}
|
|
70
70
|
out_guide = vec4(center.x, variance, 0.0, 1.0);
|
|
71
71
|
}`
|
|
@@ -110,38 +110,38 @@ return load_guideTex(clamp(p, ivec2(0), imageSize - 1), 0).xy;
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
vec4
|
|
113
|
+
vec4 ns(ivec2 p) {
|
|
114
114
|
vec4 c = load_colorTex(p, 0);
|
|
115
115
|
if (decodeInput) c.rgb = mix(pow((max(c.rgb, 0.0) + 0.055) / 1.055, vec3(2.4)),
|
|
116
116
|
c.rgb / 12.92, lessThanEqual(c.rgb, vec3(0.04045)));
|
|
117
117
|
return vec4(c.rgb * c.a, c.a);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
float
|
|
120
|
+
float mJ(ivec2 q, vec4 bp, vec3 hk) {
|
|
121
121
|
vec4 albedo = load_albedoTex(q, 0);
|
|
122
122
|
|
|
123
123
|
|
|
124
|
-
vec3
|
|
125
|
-
vec3
|
|
126
|
-
float
|
|
127
|
-
vec3
|
|
124
|
+
vec3 rc = max((albedo.rgb + bp.rgb) * 0.5, vec3(${JNLM_ALBEDO_FLOOR}));
|
|
125
|
+
vec3 mn = (albedo.rgb - bp.rgb) / rc;
|
|
126
|
+
float jv = albedo.a - bp.a;
|
|
127
|
+
vec3 my = load_normalTex(q, 0).rgb - hk;
|
|
128
128
|
return max(
|
|
129
|
-
dot(
|
|
130
|
-
+
|
|
131
|
-
dot(
|
|
129
|
+
dot(mn, mn) * INV_ALBEDO_BANDWIDTH2
|
|
130
|
+
+ jv * jv * INV_COVERAGE_BANDWIDTH2,
|
|
131
|
+
dot(my, my) * INV_NORMAL_BANDWIDTH2
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
void main() {
|
|
136
136
|
imageSize = guideTexRegion();
|
|
137
137
|
ivec2 p = ivec2(gl_FragCoord.xy);
|
|
138
|
-
vec4
|
|
139
|
-
vec4
|
|
140
|
-
vec3
|
|
138
|
+
vec4 bp = load_albedoTex(p, 0);
|
|
139
|
+
vec4 fO = load_normalTex(p, 0);
|
|
140
|
+
vec3 hk = fO.rgb;
|
|
141
141
|
|
|
142
142
|
|
|
143
|
-
if (
|
|
144
|
-
vec4 c =
|
|
143
|
+
if (fO.a <= 0.0 && load_shadowCatcherTex(p, 0).r <= 0.0) {
|
|
144
|
+
vec4 c = ns(p);
|
|
145
145
|
vec3 rgb = c.rgb / max(c.a, 1e-6);
|
|
146
146
|
if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,
|
|
147
147
|
rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));
|
|
@@ -150,25 +150,25 @@ out_guide = vec4(loadGuide(p), 0.0, 1.0);
|
|
|
150
150
|
return;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
vec2
|
|
153
|
+
vec2 mq[PATCH_SIZE];
|
|
154
154
|
int k = 0;
|
|
155
155
|
for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
156
156
|
for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
157
|
-
|
|
157
|
+
mq[k] = loadGuide(p + ivec2(dx, dy) * dilation);
|
|
158
158
|
k++;
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
float k2 = colorSensitivity * colorSensitivity;
|
|
162
162
|
|
|
163
163
|
vec4 sum = vec4(0.0);
|
|
164
|
-
vec3
|
|
165
|
-
vec3
|
|
166
|
-
vec3
|
|
167
|
-
vec3
|
|
168
|
-
float
|
|
169
|
-
float
|
|
170
|
-
float
|
|
171
|
-
float
|
|
164
|
+
vec3 hn = max(bp.rgb, vec3(${JNLM_ALBEDO_FLOOR}));
|
|
165
|
+
vec3 nS = vec3(0.0);
|
|
166
|
+
vec3 gP = vec3(0.0);
|
|
167
|
+
vec3 hH = vec3(0.0);
|
|
168
|
+
float rn = 0.0;
|
|
169
|
+
float gR = 0.0;
|
|
170
|
+
float pK = 0.0;
|
|
171
|
+
float lR = 0.0;
|
|
172
172
|
for (int sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {
|
|
173
173
|
for (int sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {
|
|
174
174
|
ivec2 q = p + ivec2(sx, sy) * dilation;
|
|
@@ -176,60 +176,60 @@ if (
|
|
|
176
176
|
(sx == 0 && sy == 0) ||
|
|
177
177
|
q.x < 0 || q.y < 0 || q.x >= imageSize.x || q.y >= imageSize.y
|
|
178
178
|
) continue;
|
|
179
|
-
float features =
|
|
179
|
+
float features = mJ(q, bp, hk);
|
|
180
180
|
if (features > 16.0) continue;
|
|
181
181
|
|
|
182
|
-
float
|
|
182
|
+
float gn = 0.0;
|
|
183
183
|
k = 0;
|
|
184
184
|
for (int dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
185
185
|
for (int dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
186
|
-
vec2 a =
|
|
186
|
+
vec2 a = mq[k];
|
|
187
187
|
vec2 b = loadGuide(q + ivec2(dx, dy) * dilation);
|
|
188
|
-
float
|
|
189
|
-
|
|
188
|
+
float tn = a.x - b.x;
|
|
189
|
+
gn += (tn * tn
|
|
190
190
|
- VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))
|
|
191
191
|
/ (1e-10 + k2 * (a.y + b.y));
|
|
192
192
|
k++;
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
|
|
195
|
+
gn /= float(PATCH_SIZE);
|
|
196
196
|
|
|
197
|
-
float weight = exp(-max(max(
|
|
197
|
+
float weight = exp(-max(max(gn, 0.0), features));
|
|
198
198
|
vec2 g = loadGuide(q);
|
|
199
199
|
|
|
200
|
-
vec3 a = (load_albedoTex(q, 0).rgb -
|
|
201
|
-
vec4 value =
|
|
200
|
+
vec3 a = (load_albedoTex(q, 0).rgb - bp.rgb) / hn;
|
|
201
|
+
vec4 value = ns(q);
|
|
202
202
|
sum += value * weight;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
203
|
+
nS += a * weight;
|
|
204
|
+
gP += a * a * weight;
|
|
205
|
+
hH += a * value.rgb * weight;
|
|
206
|
+
rn += g.x * weight;
|
|
207
|
+
gR += g.y * weight * weight;
|
|
208
|
+
pK += weight;
|
|
209
|
+
lR = max(lR, weight);
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
vec4 center =
|
|
216
|
-
vec2
|
|
217
|
-
float
|
|
218
|
-
float totalWeight =
|
|
219
|
-
vec4 mean = (sum + center *
|
|
215
|
+
vec4 center = ns(p);
|
|
216
|
+
vec2 mp = loadGuide(p);
|
|
217
|
+
float dG = max(lR, CENTER_WEIGHT_MIN);
|
|
218
|
+
float totalWeight = pK + dG;
|
|
219
|
+
vec4 mean = (sum + center * dG) / totalWeight;
|
|
220
220
|
|
|
221
221
|
|
|
222
|
-
vec3
|
|
223
|
-
vec3
|
|
224
|
-
vec3
|
|
222
|
+
vec3 eA = nS / totalWeight;
|
|
223
|
+
vec3 mK = max(gP / totalWeight - eA * eA, vec3(0.0));
|
|
224
|
+
vec3 sH = hH / totalWeight - eA * mean.rgb;
|
|
225
225
|
|
|
226
226
|
|
|
227
227
|
|
|
228
|
-
vec3
|
|
229
|
-
vec3
|
|
230
|
-
vec3
|
|
231
|
-
vec3
|
|
232
|
-
vec4 filtered = vec4(max(
|
|
228
|
+
vec3 gt = bp.rgb + eA * hn;
|
|
229
|
+
vec3 qm = mean.rgb * hn / max(gt, vec3(${JNLM_ALBEDO_FLOOR}));
|
|
230
|
+
vec3 slope = clamp(sH / (mK + vec3(${JNLM_ALBEDO_REGULARIZATION})), vec3(0.0), qm);
|
|
231
|
+
vec3 tY = mean.rgb - slope * eA;
|
|
232
|
+
vec4 filtered = vec4(max(tY, vec3(0.0)), max(mean.a, 0.0));
|
|
233
233
|
vec3 rgb = filtered.a > 1e-6
|
|
234
234
|
? filtered.rgb / max(filtered.a, 1e-6)
|
|
235
235
|
: center.rgb / max(center.a, 1e-6);
|
|
@@ -237,8 +237,8 @@ if (encodeOutput) rgb = mix(1.055 * pow(max(rgb, 0.0), vec3(1.0 / 2.4)) - 0.055,
|
|
|
237
237
|
rgb * 12.92, lessThanEqual(rgb, vec3(0.0031308)));
|
|
238
238
|
out_color = vec4(rgb, filtered.a);
|
|
239
239
|
out_guide = vec4(
|
|
240
|
-
(
|
|
241
|
-
(
|
|
240
|
+
(rn + mp.x * dG) / totalWeight,
|
|
241
|
+
(gR + mp.y * dG * dG)
|
|
242
242
|
/ (totalWeight * totalWeight),
|
|
243
243
|
0.0,
|
|
244
244
|
1.0
|
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
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 sq = max(sample_normalTex(v_Texcoord).a, 1.0) / sampleCount;
|
|
46
|
+
float jz = max(hit - mask.b * sq, 0.0);
|
|
47
47
|
out_foreground = vec4(
|
|
48
|
-
(light.rgb - background.rgb *
|
|
49
|
-
/ (
|
|
48
|
+
(light.rgb - background.rgb * sq)
|
|
49
|
+
/ (jz > 0.0 ? jz : sampleCount),
|
|
50
50
|
clamp((light.a - background.a) / sampleCount, 0.0, 1.0)
|
|
51
51
|
);
|
|
52
52
|
out_catcherBackground = background / sampleCount;
|