@meimu/mutracer 0.2.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/README.md +3 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +9328 -7614
- package/docs/api.md +83 -35
- package/docs/caustics.md +80 -0
- package/docs/materials.md +9 -6
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +53 -9
- 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 +122 -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/updates.md +3 -1
- package/docs/viewer-checklist.md +65 -0
- package/docs/viewer.md +18 -6
- 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 +4 -1
- package/lib/Engine.js +77 -14
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +81 -24
- package/lib/Render.js +201 -26
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +7 -3
- package/lib/RenderLoop.js +68 -44
- package/lib/RenderLoop.js.map +1 -1
- package/lib/main.d.ts +4 -2
- 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/GPUTraceQueue.d.ts +2 -1
- package/lib/renderer/GPUTraceQueue.js +3 -1
- package/lib/renderer/GPUTraceQueue.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 +11 -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/WGPUCausticLightPass.d.ts +48 -0
- package/lib/renderer/WGPUCausticLightPass.js +217 -0
- package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- 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 +122 -28
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +65 -21
- package/lib/renderer/WGPURayTracePass.js +730 -409
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +110 -68
- 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 +2 -1
- package/lib/renderer/WebGLFullQuadPass.js +10 -0
- 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 +20 -11
- package/lib/renderer/WebGLRayTracePass.js +157 -116
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +17 -14
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +60 -60
- package/lib/renderer/accumulationTarget.d.ts +2 -1
- package/lib/renderer/accumulationTarget.js.map +1 -1
- 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/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/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 +53 -53
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +45 -37
- 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.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 -73
- package/lib/renderer/glsl/chunks/intersect.glsl.js +478 -465
- 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 +156 -153
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
- 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 +70 -63
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +89 -75
- 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 +160 -118
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
- package/lib/renderer/glsl/chunks/sampling.glsl.js +88 -91
- 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/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 +13 -7
- 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.d.ts +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +338 -252
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +27 -26
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/lightSampling.d.ts +3 -2
- package/lib/renderer/lightSampling.js +14 -8
- package/lib/renderer/lightSampling.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 +5 -4
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +5 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- 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 +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 +2 -0
- package/lib/renderer/sceneLayoutSchema.js +3 -3
- 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.d.ts +21 -0
- package/lib/renderer/spectrum.js +154 -0
- package/lib/renderer/spectrum.js.map +1 -0
- 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/webglLightSampling.d.ts +39 -0
- package/lib/renderer/webglLightSampling.js +15 -0
- package/lib/renderer/webglLightSampling.js.map +1 -0
- 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 +3 -3
- 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 +22 -0
- package/lib/renderer/wgpuShaderSource.js +3 -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 +55 -55
- 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 +33 -33
- 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 +6 -0
- package/lib/renderer/wgsl/causticLight.compute.js +539 -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.js +37 -37
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +634 -620
- 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 +23 -21
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +3 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +77 -74
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +795 -795
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +45 -29
- 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 +142 -138
- 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 +228 -189
- 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 +11 -11
- 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 +88 -92
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
- 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 +100 -98
- 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 +12 -3
- 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.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.js +64 -64
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +23 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +531 -543
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/MaterialState.d.ts +2 -2
- package/lib/scene/MaterialState.js +2 -2
- package/lib/scene/MaterialState.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +22 -0
- package/lib/settings/render.js +2 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +23 -16
- 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/llms.txt +2 -1
- package/package.json +7 -4
- 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
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Mode indices understood by applyToneMapping. */
|
|
2
|
+
export const TONE_MAPPING_MODES = { agx: 0, aces: 1, cineon: 2, reinhard: 3, linear: 4 };
|
|
1
3
|
export const linearToSrgbDefine = /* wgsl */ `
|
|
2
4
|
fn linearToSrgb(color: vec3f) -> vec3f {
|
|
3
5
|
let linear = max(color, vec3f(0.0));
|
|
@@ -8,24 +10,24 @@ return select(high, low, linear <= vec3f(0.0031308));
|
|
|
8
10
|
`;
|
|
9
11
|
export const composeDefine = /* wgsl */ `
|
|
10
12
|
|
|
11
|
-
fn
|
|
13
|
+
fn kH(color: vec3f) -> vec3f {
|
|
12
14
|
return clamp(color, vec3f(0.0), vec3f(1.0));
|
|
13
15
|
}
|
|
14
|
-
fn
|
|
16
|
+
fn jp(color: vec3f) -> vec3f {
|
|
15
17
|
return clamp(color / (vec3f(1.0) + color), vec3f(0.0), vec3f(1.0));
|
|
16
18
|
}
|
|
17
|
-
fn
|
|
18
|
-
let color = max(vec3f(0.0),
|
|
19
|
+
fn kw(kb: vec3f) -> vec3f {
|
|
20
|
+
let color = max(vec3f(0.0), kb - 0.004);
|
|
19
21
|
return pow((color * (6.2 * color + 0.5)) /
|
|
20
22
|
(color * (6.2 * color + 1.7) + 0.06), vec3f(2.2));
|
|
21
23
|
}
|
|
22
|
-
fn
|
|
23
|
-
let
|
|
24
|
-
let
|
|
25
|
-
return
|
|
24
|
+
fn qw(value: vec3f) -> vec3f {
|
|
25
|
+
let je = value * (value + 0.0245786) - 0.000090537;
|
|
26
|
+
let ah = value * (0.983729 * value + 0.4329510) + 0.238081;
|
|
27
|
+
return je / ah;
|
|
26
28
|
}
|
|
27
|
-
fn
|
|
28
|
-
let
|
|
29
|
+
fn mH(kb: vec3f) -> vec3f {
|
|
30
|
+
let rt = mat3x3f(
|
|
29
31
|
vec3f(0.59719, 0.07600, 0.02840),
|
|
30
32
|
vec3f(0.35458, 0.90834, 0.13383),
|
|
31
33
|
vec3f(0.04823, 0.01566, 0.83777)
|
|
@@ -35,63 +37,63 @@ vec3f(1.60475, -0.10208, -0.00327),
|
|
|
35
37
|
vec3f(-0.53108, 1.10813, -0.07276),
|
|
36
38
|
vec3f(-0.07367, -0.00605, 1.07602)
|
|
37
39
|
);
|
|
38
|
-
let color =
|
|
39
|
-
return clamp(outputMatrix *
|
|
40
|
+
let color = rt * (kb / 0.6);
|
|
41
|
+
return clamp(outputMatrix * qw(color), vec3f(0.0), vec3f(1.0));
|
|
40
42
|
}
|
|
41
|
-
fn
|
|
42
|
-
let
|
|
43
|
-
let
|
|
44
|
-
return 15.5 *
|
|
45
|
-
+ 31.96 *
|
|
46
|
-
+ 0.4298 *
|
|
43
|
+
fn gj(value: vec3f) -> vec3f {
|
|
44
|
+
let ox = value * value;
|
|
45
|
+
let tf = ox * ox;
|
|
46
|
+
return 15.5 * tf * ox - 40.14 * tf * value
|
|
47
|
+
+ 31.96 * tf - 6.868 * ox * value
|
|
48
|
+
+ 0.4298 * ox + 0.1191 * value - 0.00232;
|
|
47
49
|
}
|
|
48
|
-
fn
|
|
49
|
-
let
|
|
50
|
+
fn nC(kb: vec3f) -> vec3f {
|
|
51
|
+
let oB = mat3x3f(
|
|
50
52
|
vec3f(1.6605, -0.1246, -0.0182),
|
|
51
53
|
vec3f(-0.5876, 1.1329, -0.1006),
|
|
52
54
|
vec3f(-0.0728, -0.0083, 1.1187)
|
|
53
55
|
);
|
|
54
|
-
let
|
|
56
|
+
let oC = mat3x3f(
|
|
55
57
|
vec3f(0.6274, 0.0691, 0.0164),
|
|
56
58
|
vec3f(0.3293, 0.9195, 0.0880),
|
|
57
59
|
vec3f(0.0433, 0.0113, 0.8956)
|
|
58
60
|
);
|
|
59
|
-
let
|
|
61
|
+
let rv = mat3x3f(
|
|
60
62
|
vec3f(0.856627153315983, 0.137318972929847, 0.11189821299995),
|
|
61
63
|
vec3f(0.0951212405381588, 0.761241990602591, 0.0767994186031903),
|
|
62
64
|
vec3f(0.0482516061458583, 0.101439036467562, 0.811302368396859)
|
|
63
65
|
);
|
|
64
|
-
let
|
|
66
|
+
let qr = mat3x3f(
|
|
65
67
|
vec3f(1.1271005818144368, -0.1413297634984383, -0.14132976349843826),
|
|
66
68
|
vec3f(-0.11060664309660323, 1.157823702216272, -0.11060664309660294),
|
|
67
69
|
vec3f(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)
|
|
68
70
|
);
|
|
69
|
-
var color =
|
|
71
|
+
var color = rv * (oC * kb);
|
|
70
72
|
color = clamp((log2(max(color, vec3f(1e-10))) + 12.47393) / 16.5, vec3f(0.0), vec3f(1.0));
|
|
71
|
-
color =
|
|
73
|
+
color = qr * gj(color);
|
|
72
74
|
color = pow(max(color, vec3f(0.0)), vec3f(2.2));
|
|
73
|
-
return clamp(
|
|
75
|
+
return clamp(oB * color, vec3f(0.0), vec3f(1.0));
|
|
74
76
|
}
|
|
75
|
-
fn
|
|
77
|
+
fn bH(color: vec3f) -> vec3f {
|
|
76
78
|
let toneMappingMode = i32(toneMappingParams.x);
|
|
77
|
-
if (toneMappingMode == 1) { return
|
|
78
|
-
if (toneMappingMode == 2) { return
|
|
79
|
-
if (toneMappingMode == 3) { return
|
|
80
|
-
if (toneMappingMode == 4) { return
|
|
81
|
-
return
|
|
79
|
+
if (toneMappingMode == 1) { return mH(color); }
|
|
80
|
+
if (toneMappingMode == 2) { return kw(color); }
|
|
81
|
+
if (toneMappingMode == 3) { return jp(color); }
|
|
82
|
+
if (toneMappingMode == 4) { return kH(color); }
|
|
83
|
+
return nC(color);
|
|
82
84
|
}
|
|
83
85
|
${linearToSrgbDefine}
|
|
84
|
-
fn
|
|
86
|
+
fn fm(kb: vec3f) -> vec3f {
|
|
85
87
|
let contrast = colorGradingParams.x;
|
|
86
88
|
let saturation = colorGradingParams.y;
|
|
87
89
|
let temperature = colorGradingParams.z;
|
|
88
90
|
let tint = colorGradingParams.w;
|
|
89
|
-
let
|
|
91
|
+
let wu = vec3f(
|
|
90
92
|
1.0 + temperature * 0.16 + tint * 0.04,
|
|
91
93
|
1.0 - tint * 0.12,
|
|
92
94
|
1.0 - temperature * 0.16 + tint * 0.04
|
|
93
95
|
);
|
|
94
|
-
var color = max(
|
|
96
|
+
var color = max(kb * wu, vec3f(0.0));
|
|
95
97
|
color = max((color - 0.18) * contrast + 0.18, vec3f(0.0));
|
|
96
98
|
let luminance = dot(color, vec3f(0.2126, 0.7152, 0.0722));
|
|
97
99
|
return max(mix(vec3f(luminance), color, saturation), vec3f(0.0));
|
|
@@ -101,54 +103,54 @@ export function createComposeMain(sdrEncoding = 'srgb') {
|
|
|
101
103
|
return /* wgsl */ `
|
|
102
104
|
|
|
103
105
|
var finalColor = load_colorTex(uv, 0);
|
|
104
|
-
var
|
|
106
|
+
var jU = vec4(0.0);
|
|
105
107
|
if (bloomIntensity > 0.0) {
|
|
106
|
-
|
|
107
|
-
finalColor = vec4f(finalColor.rgb +
|
|
108
|
+
jU = load_bloomTex(uv, 0) * bloomIntensity;
|
|
109
|
+
finalColor = vec4f(finalColor.rgb + jU.rgb, finalColor.a);
|
|
108
110
|
}
|
|
109
111
|
|
|
110
|
-
var gradedColor =
|
|
111
|
-
let
|
|
112
|
-
gradedColor *= 1.0 - toneMappingParams.y *
|
|
113
|
-
let
|
|
114
|
-
if (!
|
|
115
|
-
gradedColor =
|
|
112
|
+
var gradedColor = fm(finalColor.rgb * exposure);
|
|
113
|
+
let ji = smoothstep(0.2, 0.72, distance(vec2f(uv) / vec2f(colorTexRegion()), vec2f(0.5)));
|
|
114
|
+
gradedColor *= 1.0 - toneMappingParams.y * ji;
|
|
115
|
+
let gS = hdrOutputEnabled > 0.5;
|
|
116
|
+
if (!gS) {
|
|
117
|
+
gradedColor = bH(gradedColor);
|
|
116
118
|
}
|
|
117
|
-
let
|
|
119
|
+
let nP = select(
|
|
118
120
|
${sdrEncoding === 'srgb' ? 'linearToSrgb(gradedColor)' : 'pow(max(gradedColor, vec3f(0.0)), vec3f(1.0 / 2.2))'},
|
|
119
121
|
linearToSrgb(gradedColor),
|
|
120
|
-
|
|
122
|
+
gS
|
|
121
123
|
);
|
|
122
|
-
var
|
|
124
|
+
var pT = nP;
|
|
123
125
|
if (flatBackgroundColor.a > 0.5) {
|
|
124
|
-
let
|
|
126
|
+
let jN = clamp(
|
|
125
127
|
load_flatBackgroundMaskTex(uv, 0).a,
|
|
126
128
|
0.0,
|
|
127
129
|
1.0
|
|
128
130
|
);
|
|
129
|
-
let
|
|
130
|
-
|
|
131
|
+
let qV = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0)));
|
|
132
|
+
pT = mix(qV, nP, jN);
|
|
131
133
|
if (bloomIntensity > 0.0) {
|
|
132
|
-
var unbloomedColor =
|
|
133
|
-
max(finalColor.rgb -
|
|
134
|
+
var unbloomedColor = fm(
|
|
135
|
+
max(finalColor.rgb - jU.rgb, vec3f(0.0))
|
|
134
136
|
* exposure
|
|
135
137
|
);
|
|
136
|
-
unbloomedColor *= 1.0 - toneMappingParams.y *
|
|
137
|
-
if (!
|
|
138
|
-
unbloomedColor =
|
|
138
|
+
unbloomedColor *= 1.0 - toneMappingParams.y * ji;
|
|
139
|
+
if (!gS) {
|
|
140
|
+
unbloomedColor = bH(unbloomedColor);
|
|
139
141
|
}
|
|
140
|
-
let
|
|
142
|
+
let ub = select(
|
|
141
143
|
${sdrEncoding === 'srgb' ? 'linearToSrgb(unbloomedColor)' : 'pow(max(unbloomedColor, vec3f(0.0)), vec3f(1.0 / 2.2))'},
|
|
142
144
|
linearToSrgb(unbloomedColor),
|
|
143
|
-
|
|
145
|
+
gS
|
|
144
146
|
);
|
|
145
|
-
|
|
146
|
-
* (1.0 -
|
|
147
|
+
pT += max(nP - ub, vec3f(0.0))
|
|
148
|
+
* (1.0 - jN);
|
|
147
149
|
}
|
|
148
150
|
}
|
|
149
|
-
finalColor = vec4f(
|
|
151
|
+
finalColor = vec4f(pT, finalColor.a);
|
|
150
152
|
if (bloomIntensity > 0.0) {
|
|
151
|
-
finalColor.a = max(finalColor.a, min(dot(
|
|
153
|
+
finalColor.a = max(finalColor.a, min(dot(jU.rgb, vec3f(0.2125, 0.7154, 0.0721)), 1.0));
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
if (shadowCatcherEnabled > 0.5) {
|
|
@@ -162,36 +164,36 @@ let background = load_catcherBackgroundTex(uv, 0);
|
|
|
162
164
|
|
|
163
165
|
|
|
164
166
|
|
|
165
|
-
let
|
|
166
|
-
var foregroundColor =
|
|
167
|
-
var backgroundColor =
|
|
168
|
-
foregroundColor *= 1.0 - toneMappingParams.y *
|
|
169
|
-
backgroundColor *= 1.0 - toneMappingParams.y *
|
|
170
|
-
if (!
|
|
171
|
-
foregroundColor =
|
|
172
|
-
backgroundColor =
|
|
167
|
+
let lN = select(0.0, clamp(background.a - coverage, 0.0, 1.0 - coverage), flatBackgroundColor.a > 0.5);
|
|
168
|
+
var foregroundColor = fm((foreground.rgb + jU.rgb) * exposure);
|
|
169
|
+
var backgroundColor = fm((background.rgb / max(background.a, 0.000001) + jU.rgb) * exposure);
|
|
170
|
+
foregroundColor *= 1.0 - toneMappingParams.y * ji;
|
|
171
|
+
backgroundColor *= 1.0 - toneMappingParams.y * ji;
|
|
172
|
+
if (!gS) {
|
|
173
|
+
foregroundColor = bH(foregroundColor);
|
|
174
|
+
backgroundColor = bH(backgroundColor);
|
|
173
175
|
}
|
|
174
|
-
foregroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(foregroundColor)' : 'pow(max(foregroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(foregroundColor),
|
|
175
|
-
backgroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(backgroundColor)' : 'pow(max(backgroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(backgroundColor),
|
|
176
|
+
foregroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(foregroundColor)' : 'pow(max(foregroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(foregroundColor), gS);
|
|
177
|
+
backgroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(backgroundColor)' : 'pow(max(backgroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(backgroundColor), gS);
|
|
176
178
|
if (flatBackgroundColor.a > 0.5) {
|
|
177
|
-
var unbloomedBackground =
|
|
178
|
-
unbloomedBackground *= 1.0 - toneMappingParams.y *
|
|
179
|
-
if (!
|
|
180
|
-
let
|
|
181
|
-
let
|
|
182
|
-
backgroundColor = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0))) +
|
|
179
|
+
var unbloomedBackground = fm(background.rgb / max(background.a, 0.000001) * exposure);
|
|
180
|
+
unbloomedBackground *= 1.0 - toneMappingParams.y * ji;
|
|
181
|
+
if (!gS) { unbloomedBackground = bH(unbloomedBackground); }
|
|
182
|
+
let nQ = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(unbloomedBackground)' : 'pow(max(unbloomedBackground, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(unbloomedBackground), gS);
|
|
183
|
+
let xU = select(vec3f(0.0), max(backgroundColor - nQ, vec3f(0.0)), bloomIntensity > 0.0);
|
|
184
|
+
backgroundColor = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0))) + xU;
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
|
|
186
|
-
let
|
|
187
|
-
let
|
|
188
|
-
let
|
|
189
|
-
let
|
|
190
|
-
let
|
|
191
|
-
let alpha =
|
|
192
|
-
let premultiplied = foregroundColor *
|
|
193
|
-
+ backgroundColor *
|
|
194
|
-
+ shadowCatcherColor *
|
|
188
|
+
let gd = coverage * opacity;
|
|
189
|
+
let nF = clamp(dot(jU.rgb, vec3f(0.2125, 0.7154, 0.0721)), 0.0, 1.0);
|
|
190
|
+
let hK = max(foreground.a, nF * (1.0 - coverage - lN));
|
|
191
|
+
let jJ = max(background.a, nF * coverage);
|
|
192
|
+
let ln = (jJ - lN) * (1.0 - opacity) + lN;
|
|
193
|
+
let alpha = hK + ln + gd;
|
|
194
|
+
let premultiplied = foregroundColor * hK
|
|
195
|
+
+ backgroundColor * ln
|
|
196
|
+
+ shadowCatcherColor * gd;
|
|
195
197
|
finalColor = vec4f(premultiplied / max(alpha, 0.000001), alpha);
|
|
196
198
|
}
|
|
197
199
|
}
|
|
@@ -208,8 +210,8 @@ export function createCompositeDenoiseColorMain(output = 'output.denoiseColor',
|
|
|
208
210
|
const srgbDecode = 'select(pow((encoded + 0.055) / 1.055, vec3f(2.4)), encoded / 12.92, encoded <= vec3f(0.04045))';
|
|
209
211
|
return /* wgsl */ `
|
|
210
212
|
let encoded = max(${input}.rgb, vec3f(0.0));
|
|
211
|
-
let
|
|
212
|
-
${output} = vec4f(
|
|
213
|
+
let wa = ${sdrEncoding === 'srgb' ? srgbDecode : `select(pow(encoded, vec3f(2.2)), ${srgbDecode}, gS)`};
|
|
214
|
+
${output} = vec4f(wa, ${input}.a);
|
|
213
215
|
|
|
214
216
|
`;
|
|
215
217
|
}
|
|
@@ -219,22 +221,22 @@ export function createCompositeDenoiseAlbedoMain(output = 'output.denoiseAlbedo'
|
|
|
219
221
|
|
|
220
222
|
|
|
221
223
|
let rawAlbedo = load_flatBackgroundMaskTex(uv, 0);
|
|
222
|
-
var
|
|
224
|
+
var qM = rawAlbedo.rgb;
|
|
223
225
|
if (shadowCatcherEnabled > 0.5 && flatBackgroundColor.a < 0.5) {
|
|
224
226
|
let coverage = clamp(load_shadowCatcherTex(uv, 0).r, 0.0, 1.0);
|
|
225
227
|
let background = load_catcherBackgroundTex(uv, 0);
|
|
226
228
|
if (coverage > 0.0 && background.a > 0.0) {
|
|
227
|
-
var
|
|
228
|
-
|
|
229
|
-
if (!
|
|
229
|
+
var iW = fm(background.rgb / background.a * exposure);
|
|
230
|
+
iW *= 1.0 - toneMappingParams.y * ji;
|
|
231
|
+
if (!gS) { iW = bH(iW); }
|
|
230
232
|
|
|
231
233
|
|
|
232
234
|
|
|
233
|
-
let
|
|
234
|
-
|
|
235
|
+
let tS = clamp(background.a, 0.0, coverage);
|
|
236
|
+
qM += tS * (clamp(iW, vec3f(0.0), vec3f(1.0)) - vec3f(1.0));
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
|
-
${output} = vec4f(clamp(
|
|
239
|
+
${output} = vec4f(clamp(qM, vec3f(0.0), vec3f(1.0)), rawAlbedo.a);
|
|
238
240
|
`;
|
|
239
241
|
}
|
|
240
242
|
export const compositeDenoiseOutputMain = createCompositeDenoiseColorMain() + createCompositeDenoiseAlbedoMain();
|
|
@@ -253,15 +255,15 @@ output.color = vec4f(select(vec3f(0.0), encoded, alpha > 0.0), alpha);
|
|
|
253
255
|
export const compositeDenoiseDisplayMain = createCompositeDenoiseDisplayMain();
|
|
254
256
|
// Shared hit normalization; CPU readback retains its f32 reference path.
|
|
255
257
|
export const hdrResolveWGSL = /* wgsl */ `
|
|
256
|
-
fn
|
|
258
|
+
fn fF(color: f32, count: f32, hit: f32, wf: f32, rgb: bool) -> f32 {
|
|
257
259
|
if (count <= 0.0) {
|
|
258
260
|
return 0.0;
|
|
259
261
|
}
|
|
260
|
-
let total = max(count,
|
|
262
|
+
let total = max(count, wf);
|
|
261
263
|
let divisor = select(total, hit, (rgb && (hit > 0.0)));
|
|
262
264
|
return (color / divisor);
|
|
263
265
|
}
|
|
264
|
-
fn
|
|
266
|
+
fn ka(color: f32, coverage: f32, flat: bool, rgb: bool) -> f32 {
|
|
265
267
|
if ((flat && rgb) && (coverage > 0.0)) {
|
|
266
268
|
return (color * coverage);
|
|
267
269
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.frag.wgsl.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/compose.frag.wgsl.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;;;;;;;CAO5C,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0EtC,kBAAkB;;;;;;;;;;;;;;;;CAgBnB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,cAAkC,MAAM;IACxE,OAAO,UAAU,CAAC;;;;;;;;;;;;;;;;;EAiBhB,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;EAuBxG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiC3F,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,yDAAyD;2BACpH,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,yDAAyD;;;;;kBAKnG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;CAsB3K,CAAC;AACF,CAAC;AACD,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;AAE/C,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,UAAU,+BAA+B,CAAC,MAAM,GAAG,qBAAqB,EAAE,KAAK,GAAG,YAAY,EAAE,cAAkC,MAAM;IAC5I,MAAM,UAAU,GAAG,gGAAgG,CAAC;IACpH,OAAO,UAAU,CAAC;oBACA,KAAK;WACH,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,oCAAoC,UAAU,OAAc;EACtH,MAAM,gBAA2B,KAAK;;CAEvC,CAAC;AACF,CAAC;AACD,MAAM,UAAU,gCAAgC,CAAC,MAAM,GAAG,sBAAsB;IAC9E,OAAO,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;EAoBlB,MAAM;CACP,CAAC;AACF,CAAC;AACD,MAAM,CAAC,MAAM,0BAA0B,GAAG,+BAA+B,EAAE,GAAG,gCAAgC,EAAE,CAAC;AAEjH,MAAM,UAAU,iCAAiC,CAAC,cAAkC,MAAM;IACxF,OAAO,UAAU,CAAC;;;;;;;gBAOJ,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,qFAAqF;;CAEtJ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,iCAAiC,EAAE,CAAC;AAE/E,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;CAexC,CAAC","sourcesContent":["export const linearToSrgbDefine = /* wgsl */ `\nfn linearToSrgb(color: vec3f) -> vec3f {\n let linear = max(color, vec3f(0.0));\n let low = linear * 12.92;\n let high = 1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055;\n return select(high, low, linear <= vec3f(0.0031308));\n}\n`;\n\nexport const composeDefine = /* wgsl */ `\n\nfn linearToneMapping(color: vec3f) -> vec3f {\n return clamp(color, vec3f(0.0), vec3f(1.0));\n}\nfn reinhardToneMapping(color: vec3f) -> vec3f {\n return clamp(color / (vec3f(1.0) + color), vec3f(0.0), vec3f(1.0));\n}\nfn cineonToneMapping(inputColor: vec3f) -> vec3f {\n let color = max(vec3f(0.0), inputColor - 0.004);\n return pow((color * (6.2 * color + 0.5)) /\n (color * (6.2 * color + 1.7) + 0.06), vec3f(2.2));\n}\nfn rrtAndOdtFit(value: vec3f) -> vec3f {\n let numerator = value * (value + 0.0245786) - 0.000090537;\n let denominator = value * (0.983729 * value + 0.4329510) + 0.238081;\n return numerator / denominator;\n}\nfn acesToneMapping(inputColor: vec3f) -> vec3f {\n let inputMatrix = mat3x3f(\n vec3f(0.59719, 0.07600, 0.02840),\n vec3f(0.35458, 0.90834, 0.13383),\n vec3f(0.04823, 0.01566, 0.83777)\n );\n let outputMatrix = mat3x3f(\n vec3f(1.60475, -0.10208, -0.00327),\n vec3f(-0.53108, 1.10813, -0.07276),\n vec3f(-0.07367, -0.00605, 1.07602)\n );\n let color = inputMatrix * (inputColor / 0.6);\n return clamp(outputMatrix * rrtAndOdtFit(color), vec3f(0.0), vec3f(1.0));\n}\nfn agxDefaultContrastApprox(value: vec3f) -> vec3f {\n let value2 = value * value;\n let value4 = value2 * value2;\n return 15.5 * value4 * value2 - 40.14 * value4 * value\n + 31.96 * value4 - 6.868 * value2 * value\n + 0.4298 * value2 + 0.1191 * value - 0.00232;\n}\nfn agxToneMapping(inputColor: vec3f) -> vec3f {\n let linearRec2020ToLinearSrgb = mat3x3f(\n vec3f(1.6605, -0.1246, -0.0182),\n vec3f(-0.5876, 1.1329, -0.1006),\n vec3f(-0.0728, -0.0083, 1.1187)\n );\n let linearSrgbToLinearRec2020 = mat3x3f(\n vec3f(0.6274, 0.0691, 0.0164),\n vec3f(0.3293, 0.9195, 0.0880),\n vec3f(0.0433, 0.0113, 0.8956)\n );\n let insetMatrix = mat3x3f(\n vec3f(0.856627153315983, 0.137318972929847, 0.11189821299995),\n vec3f(0.0951212405381588, 0.761241990602591, 0.0767994186031903),\n vec3f(0.0482516061458583, 0.101439036467562, 0.811302368396859)\n );\n let outsetMatrix = mat3x3f(\n vec3f(1.1271005818144368, -0.1413297634984383, -0.14132976349843826),\n vec3f(-0.11060664309660323, 1.157823702216272, -0.11060664309660294),\n vec3f(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)\n );\n var color = insetMatrix * (linearSrgbToLinearRec2020 * inputColor);\n color = clamp((log2(max(color, vec3f(1e-10))) + 12.47393) / 16.5, vec3f(0.0), vec3f(1.0));\n color = outsetMatrix * agxDefaultContrastApprox(color);\n color = pow(max(color, vec3f(0.0)), vec3f(2.2));\n return clamp(linearRec2020ToLinearSrgb * color, vec3f(0.0), vec3f(1.0));\n}\nfn applyToneMapping(color: vec3f) -> vec3f {\n let toneMappingMode = i32(toneMappingParams.x);\n if (toneMappingMode == 1) { return acesToneMapping(color); }\n if (toneMappingMode == 2) { return cineonToneMapping(color); }\n if (toneMappingMode == 3) { return reinhardToneMapping(color); }\n if (toneMappingMode == 4) { return linearToneMapping(color); }\n return agxToneMapping(color);\n}\n${linearToSrgbDefine}\nfn gradeColor(inputColor: vec3f) -> vec3f {\n let contrast = colorGradingParams.x;\n let saturation = colorGradingParams.y;\n let temperature = colorGradingParams.z;\n let tint = colorGradingParams.w;\n let balance = vec3f(\n 1.0 + temperature * 0.16 + tint * 0.04,\n 1.0 - tint * 0.12,\n 1.0 - temperature * 0.16 + tint * 0.04\n );\n var color = max(inputColor * balance, vec3f(0.0));\n color = max((color - 0.18) * contrast + 0.18, vec3f(0.0));\n let luminance = dot(color, vec3f(0.2126, 0.7152, 0.0722));\n return max(mix(vec3f(luminance), color, saturation), vec3f(0.0));\n}\n`;\n\nexport function createComposeMain(sdrEncoding: 'gamma22' | 'srgb' = 'srgb'): string {\n return /* wgsl */ `\n\nvar finalColor = load_colorTex(uv, 0);\nvar bloomTexel = vec4(0.0);\nif (bloomIntensity > 0.0) {\n bloomTexel = load_bloomTex(uv, 0) * bloomIntensity;\n finalColor = vec4f(finalColor.rgb + bloomTexel.rgb, finalColor.a);\n}\n\nvar gradedColor = gradeColor(finalColor.rgb * exposure);\nlet vignetteEdge = smoothstep(0.2, 0.72, distance(vec2f(uv) / vec2f(colorTexRegion()), vec2f(0.5)));\ngradedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\nlet hdrOutput = hdrOutputEnabled > 0.5;\nif (!hdrOutput) {\n gradedColor = applyToneMapping(gradedColor);\n}\nlet encodedDisplay = select(\n ${sdrEncoding === 'srgb' ? 'linearToSrgb(gradedColor)' : 'pow(max(gradedColor, vec3f(0.0)), vec3f(1.0 / 2.2))'},\n linearToSrgb(gradedColor),\n hdrOutput\n);\nvar displayColor = encodedDisplay;\nif (flatBackgroundColor.a > 0.5) {\n let surfaceCoverage = clamp(\n load_flatBackgroundMaskTex(uv, 0).a,\n 0.0,\n 1.0\n );\n let flatBackgroundDisplay = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0)));\n displayColor = mix(flatBackgroundDisplay, encodedDisplay, surfaceCoverage);\n if (bloomIntensity > 0.0) {\n var unbloomedColor = gradeColor(\n max(finalColor.rgb - bloomTexel.rgb, vec3f(0.0))\n * exposure\n );\n unbloomedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n unbloomedColor = applyToneMapping(unbloomedColor);\n }\n let encodedUnbloomed = select(\n ${sdrEncoding === 'srgb' ? 'linearToSrgb(unbloomedColor)' : 'pow(max(unbloomedColor, vec3f(0.0)), vec3f(1.0 / 2.2))'},\n linearToSrgb(unbloomedColor),\n hdrOutput\n );\n displayColor += max(encodedDisplay - encodedUnbloomed, vec3f(0.0))\n * (1.0 - surfaceCoverage);\n }\n}\nfinalColor = vec4f(displayColor, finalColor.a);\nif (bloomIntensity > 0.0) {\n finalColor.a = max(finalColor.a, min(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 1.0));\n}\n\nif (shadowCatcherEnabled > 0.5) {\n let shadowCatcher = load_shadowCatcherTex(uv, 0);\n let coverage = clamp(shadowCatcher.r, 0.0, 1.0);\n let opacity = max(clamp(shadowCatcher.a / max(coverage, 0.000001), 0.0, 1.0) - (1.0 - shadowCatcherAlpha), 0.0);\n if (coverage > 0.0 || flatBackgroundColor.a > 0.5) {\n let foreground = load_foregroundTex(uv, 0);\n let background = load_catcherBackgroundTex(uv, 0);\n // An opaque flat backdrop also owns primary misses outside the receiver.\n // Its alpha contains catcher coverage plus miss coverage; only the catcher\n // fraction receives shadow. These weights come from the accumulation,\n // independently of the quantized denoising/albedo guide.\n let flatMissCoverage = select(0.0, clamp(background.a - coverage, 0.0, 1.0 - coverage), flatBackgroundColor.a > 0.5);\n var foregroundColor = gradeColor((foreground.rgb + bloomTexel.rgb) * exposure);\n var backgroundColor = gradeColor((background.rgb / max(background.a, 0.000001) + bloomTexel.rgb) * exposure);\n foregroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n backgroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n foregroundColor = applyToneMapping(foregroundColor);\n backgroundColor = applyToneMapping(backgroundColor);\n }\n foregroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(foregroundColor)' : 'pow(max(foregroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(foregroundColor), hdrOutput);\n backgroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(backgroundColor)' : 'pow(max(backgroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(backgroundColor), hdrOutput);\n if (flatBackgroundColor.a > 0.5) {\n var unbloomedBackground = gradeColor(background.rgb / max(background.a, 0.000001) * exposure);\n unbloomedBackground *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { unbloomedBackground = applyToneMapping(unbloomedBackground); }\n let encodedUnbloomedBackground = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(unbloomedBackground)' : 'pow(max(unbloomedBackground, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(unbloomedBackground), hdrOutput);\n let bloomSpill = select(vec3f(0.0), max(backgroundColor - encodedUnbloomedBackground, vec3f(0.0)), bloomIntensity > 0.0);\n backgroundColor = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0))) + bloomSpill;\n }\n // Foreground and catcher are disjoint primary samples, not overlapping\n // alpha layers. Shadow only the catcher background before averaging.\n let shadowAlpha = coverage * opacity;\n let bloomAlpha = clamp(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 0.0, 1.0);\n let foregroundAlpha = max(foreground.a, bloomAlpha * (1.0 - coverage - flatMissCoverage));\n let backgroundAlpha = max(background.a, bloomAlpha * coverage);\n let visibleBackgroundAlpha = (backgroundAlpha - flatMissCoverage) * (1.0 - opacity) + flatMissCoverage;\n let alpha = foregroundAlpha + visibleBackgroundAlpha + shadowAlpha;\n let premultiplied = foregroundColor * foregroundAlpha\n + backgroundColor * visibleBackgroundAlpha\n + shadowCatcherColor * shadowAlpha;\n finalColor = vec4f(premultiplied / max(alpha, 0.000001), alpha);\n }\n}\n\noutput.color = finalColor;\n\n// output.color = load_bloomTex(uv, 0) * bloomIntensity;\n`;\n}\nexport const composeMain = createComposeMain();\n\n// Preserve the existing display composition, but give OIDN a floating-point,\n// linear-light image. Alpha is deliberately not used as a second color layer.\nexport function createCompositeDenoiseColorMain(output = 'output.denoiseColor', input = 'finalColor', sdrEncoding: 'gamma22' | 'srgb' = 'srgb'): string {\n const srgbDecode = 'select(pow((encoded + 0.055) / 1.055, vec3f(2.4)), encoded / 12.92, encoded <= vec3f(0.04045))';\n return /* wgsl */ `\nlet encoded = max(${input}.rgb, vec3f(0.0));\nlet displayLinear = ${sdrEncoding === 'srgb' ? srgbDecode : `select(pow(encoded, vec3f(2.2)), ${srgbDecode}, hdrOutput)`};\n${output} = vec4f(displayLinear, ${input}.a);\n\n`;\n}\nexport function createCompositeDenoiseAlbedoMain(output = 'output.denoiseAlbedo'): string {\n return /* wgsl */ `// The receiver is invisible: its visible texture is the displayed background,\n// not the neutral reflectance used for its lighting estimate. Match the beauty\n// reconstruction filter, including mixed foreground/receiver primary samples.\n// Exclude the stochastic shadow and bloom so neither is preserved as texture.\nlet rawAlbedo = load_flatBackgroundMaskTex(uv, 0);\nvar compositeAlbedo = rawAlbedo.rgb;\nif (shadowCatcherEnabled > 0.5 && flatBackgroundColor.a < 0.5) {\n let coverage = clamp(load_shadowCatcherTex(uv, 0).r, 0.0, 1.0);\n let background = load_catcherBackgroundTex(uv, 0);\n if (coverage > 0.0 && background.a > 0.0) {\n var backgroundAlbedo = gradeColor(background.rgb / background.a * exposure);\n backgroundAlbedo *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { backgroundAlbedo = applyToneMapping(backgroundAlbedo); }\n // Background alpha already includes primary catcher coverage. Retain the\n // neutral receiver for its transparent part, without counting coverage twice\n // or adding the stochastic shadow opacity to the texture guide.\n let backgroundWeight = clamp(background.a, 0.0, coverage);\n compositeAlbedo += backgroundWeight * (clamp(backgroundAlbedo, vec3f(0.0), vec3f(1.0)) - vec3f(1.0));\n }\n}\n${output} = vec4f(clamp(compositeAlbedo, vec3f(0.0), vec3f(1.0)), rawAlbedo.a);\n`;\n}\nexport const compositeDenoiseOutputMain = createCompositeDenoiseColorMain() + createCompositeDenoiseAlbedoMain();\n\nexport function createCompositeDenoiseDisplayMain(sdrEncoding: 'gamma22' | 'srgb' = 'srgb'): string {\n return /* wgsl */ `\nlet denoised = load_colorTex(uv, 0);\n// Keep the original primary coverage, including transparency. OIDN only\n// filters RGB; filtering coverage separately reintroduces silhouette seams.\n// The built-in filter weights color and coverage together and may replace it.\nlet alpha = select(load_composedTex(uv, 0).a, clamp(denoised.a, 0.0, 1.0), denoisedAlpha > 0.5);\nlet linear = max(denoised.rgb, vec3f(0.0));\nlet encoded = ${sdrEncoding === 'srgb' ? 'linearToSrgb(linear)' : 'select(pow(linear, vec3f(1.0 / 2.2)), linearToSrgb(linear), hdrOutputEnabled > 0.5)'};\noutput.color = vec4f(select(vec3f(0.0), encoded, alpha > 0.0), alpha);\n`;\n}\n\nexport const compositeDenoiseDisplayMain = createCompositeDenoiseDisplayMain();\n\n// Shared hit normalization; CPU readback retains its f32 reference path.\nexport const hdrResolveWGSL = /* wgsl */ `\nfn hdr_resolve_component(color: f32, count: f32, hit: f32, minimum_count: f32, rgb: bool) -> f32 {\nif (count <= 0.0) {\nreturn 0.0;\n}\nlet total = max(count, minimum_count);\nlet divisor = select(total, hit, (rgb && (hit > 0.0)));\nreturn (color / divisor);\n}\nfn hdr_flat_component(color: f32, coverage: f32, flat: bool, rgb: bool) -> f32 {\nif ((flat && rgb) && (coverage > 0.0)) {\nreturn (color * coverage);\n}\nreturn color;\n}\n`;\n"]}
|
|
1
|
+
{"version":3,"file":"compose.frag.wgsl.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/compose.frag.wgsl.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,MAAM,CAAC,MAAM,kBAAkB,GAAqC,EAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAC,CAAC;AAEzH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;;;;;;;CAO5C,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0EtC,kBAAkB;;;;;;;;;;;;;;;;CAgBnB,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,cAAkC,MAAM;IACxE,OAAO,UAAU,CAAC;;;;;;;;;;;;;;;;;EAiBhB,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;EAuBxG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiC3F,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,yDAAyD;2BACpH,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,yDAAyD;;;;;kBAKnG,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;CAsB3K,CAAC;AACF,CAAC;AACD,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;AAE/C,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,UAAU,+BAA+B,CAAC,MAAM,GAAG,qBAAqB,EAAE,KAAK,GAAG,YAAY,EAAE,cAAkC,MAAM;IAC5I,MAAM,UAAU,GAAG,gGAAgG,CAAC;IACpH,OAAO,UAAU,CAAC;oBACA,KAAK;WACH,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,oCAAoC,UAAU,OAAc;EACtH,MAAM,gBAA2B,KAAK;;CAEvC,CAAC;AACF,CAAC;AACD,MAAM,UAAU,gCAAgC,CAAC,MAAM,GAAG,sBAAsB;IAC9E,OAAO,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;EAoBlB,MAAM;CACP,CAAC;AACF,CAAC;AACD,MAAM,CAAC,MAAM,0BAA0B,GAAG,+BAA+B,EAAE,GAAG,gCAAgC,EAAE,CAAC;AAEjH,MAAM,UAAU,iCAAiC,CAAC,cAAkC,MAAM;IACxF,OAAO,UAAU,CAAC;;;;;;;gBAOJ,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,qFAAqF;;CAEtJ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,iCAAiC,EAAE,CAAC;AAE/E,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;CAexC,CAAC","sourcesContent":["/** Mode indices understood by applyToneMapping. */\nexport const TONE_MAPPING_MODES: Readonly<Record<string, number>> = {agx: 0, aces: 1, cineon: 2, reinhard: 3, linear: 4};\n\nexport const linearToSrgbDefine = /* wgsl */ `\nfn linearToSrgb(color: vec3f) -> vec3f {\n let linear = max(color, vec3f(0.0));\n let low = linear * 12.92;\n let high = 1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055;\n return select(high, low, linear <= vec3f(0.0031308));\n}\n`;\n\nexport const composeDefine = /* wgsl */ `\n\nfn linearToneMapping(color: vec3f) -> vec3f {\n return clamp(color, vec3f(0.0), vec3f(1.0));\n}\nfn reinhardToneMapping(color: vec3f) -> vec3f {\n return clamp(color / (vec3f(1.0) + color), vec3f(0.0), vec3f(1.0));\n}\nfn cineonToneMapping(inputColor: vec3f) -> vec3f {\n let color = max(vec3f(0.0), inputColor - 0.004);\n return pow((color * (6.2 * color + 0.5)) /\n (color * (6.2 * color + 1.7) + 0.06), vec3f(2.2));\n}\nfn rrtAndOdtFit(value: vec3f) -> vec3f {\n let numerator = value * (value + 0.0245786) - 0.000090537;\n let denominator = value * (0.983729 * value + 0.4329510) + 0.238081;\n return numerator / denominator;\n}\nfn acesToneMapping(inputColor: vec3f) -> vec3f {\n let inputMatrix = mat3x3f(\n vec3f(0.59719, 0.07600, 0.02840),\n vec3f(0.35458, 0.90834, 0.13383),\n vec3f(0.04823, 0.01566, 0.83777)\n );\n let outputMatrix = mat3x3f(\n vec3f(1.60475, -0.10208, -0.00327),\n vec3f(-0.53108, 1.10813, -0.07276),\n vec3f(-0.07367, -0.00605, 1.07602)\n );\n let color = inputMatrix * (inputColor / 0.6);\n return clamp(outputMatrix * rrtAndOdtFit(color), vec3f(0.0), vec3f(1.0));\n}\nfn agxDefaultContrastApprox(value: vec3f) -> vec3f {\n let value2 = value * value;\n let value4 = value2 * value2;\n return 15.5 * value4 * value2 - 40.14 * value4 * value\n + 31.96 * value4 - 6.868 * value2 * value\n + 0.4298 * value2 + 0.1191 * value - 0.00232;\n}\nfn agxToneMapping(inputColor: vec3f) -> vec3f {\n let linearRec2020ToLinearSrgb = mat3x3f(\n vec3f(1.6605, -0.1246, -0.0182),\n vec3f(-0.5876, 1.1329, -0.1006),\n vec3f(-0.0728, -0.0083, 1.1187)\n );\n let linearSrgbToLinearRec2020 = mat3x3f(\n vec3f(0.6274, 0.0691, 0.0164),\n vec3f(0.3293, 0.9195, 0.0880),\n vec3f(0.0433, 0.0113, 0.8956)\n );\n let insetMatrix = mat3x3f(\n vec3f(0.856627153315983, 0.137318972929847, 0.11189821299995),\n vec3f(0.0951212405381588, 0.761241990602591, 0.0767994186031903),\n vec3f(0.0482516061458583, 0.101439036467562, 0.811302368396859)\n );\n let outsetMatrix = mat3x3f(\n vec3f(1.1271005818144368, -0.1413297634984383, -0.14132976349843826),\n vec3f(-0.11060664309660323, 1.157823702216272, -0.11060664309660294),\n vec3f(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)\n );\n var color = insetMatrix * (linearSrgbToLinearRec2020 * inputColor);\n color = clamp((log2(max(color, vec3f(1e-10))) + 12.47393) / 16.5, vec3f(0.0), vec3f(1.0));\n color = outsetMatrix * agxDefaultContrastApprox(color);\n color = pow(max(color, vec3f(0.0)), vec3f(2.2));\n return clamp(linearRec2020ToLinearSrgb * color, vec3f(0.0), vec3f(1.0));\n}\nfn applyToneMapping(color: vec3f) -> vec3f {\n let toneMappingMode = i32(toneMappingParams.x);\n if (toneMappingMode == 1) { return acesToneMapping(color); }\n if (toneMappingMode == 2) { return cineonToneMapping(color); }\n if (toneMappingMode == 3) { return reinhardToneMapping(color); }\n if (toneMappingMode == 4) { return linearToneMapping(color); }\n return agxToneMapping(color);\n}\n${linearToSrgbDefine}\nfn gradeColor(inputColor: vec3f) -> vec3f {\n let contrast = colorGradingParams.x;\n let saturation = colorGradingParams.y;\n let temperature = colorGradingParams.z;\n let tint = colorGradingParams.w;\n let balance = vec3f(\n 1.0 + temperature * 0.16 + tint * 0.04,\n 1.0 - tint * 0.12,\n 1.0 - temperature * 0.16 + tint * 0.04\n );\n var color = max(inputColor * balance, vec3f(0.0));\n color = max((color - 0.18) * contrast + 0.18, vec3f(0.0));\n let luminance = dot(color, vec3f(0.2126, 0.7152, 0.0722));\n return max(mix(vec3f(luminance), color, saturation), vec3f(0.0));\n}\n`;\n\nexport function createComposeMain(sdrEncoding: 'gamma22' | 'srgb' = 'srgb'): string {\n return /* wgsl */ `\n\nvar finalColor = load_colorTex(uv, 0);\nvar bloomTexel = vec4(0.0);\nif (bloomIntensity > 0.0) {\n bloomTexel = load_bloomTex(uv, 0) * bloomIntensity;\n finalColor = vec4f(finalColor.rgb + bloomTexel.rgb, finalColor.a);\n}\n\nvar gradedColor = gradeColor(finalColor.rgb * exposure);\nlet vignetteEdge = smoothstep(0.2, 0.72, distance(vec2f(uv) / vec2f(colorTexRegion()), vec2f(0.5)));\ngradedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\nlet hdrOutput = hdrOutputEnabled > 0.5;\nif (!hdrOutput) {\n gradedColor = applyToneMapping(gradedColor);\n}\nlet encodedDisplay = select(\n ${sdrEncoding === 'srgb' ? 'linearToSrgb(gradedColor)' : 'pow(max(gradedColor, vec3f(0.0)), vec3f(1.0 / 2.2))'},\n linearToSrgb(gradedColor),\n hdrOutput\n);\nvar displayColor = encodedDisplay;\nif (flatBackgroundColor.a > 0.5) {\n let surfaceCoverage = clamp(\n load_flatBackgroundMaskTex(uv, 0).a,\n 0.0,\n 1.0\n );\n let flatBackgroundDisplay = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0)));\n displayColor = mix(flatBackgroundDisplay, encodedDisplay, surfaceCoverage);\n if (bloomIntensity > 0.0) {\n var unbloomedColor = gradeColor(\n max(finalColor.rgb - bloomTexel.rgb, vec3f(0.0))\n * exposure\n );\n unbloomedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n unbloomedColor = applyToneMapping(unbloomedColor);\n }\n let encodedUnbloomed = select(\n ${sdrEncoding === 'srgb' ? 'linearToSrgb(unbloomedColor)' : 'pow(max(unbloomedColor, vec3f(0.0)), vec3f(1.0 / 2.2))'},\n linearToSrgb(unbloomedColor),\n hdrOutput\n );\n displayColor += max(encodedDisplay - encodedUnbloomed, vec3f(0.0))\n * (1.0 - surfaceCoverage);\n }\n}\nfinalColor = vec4f(displayColor, finalColor.a);\nif (bloomIntensity > 0.0) {\n finalColor.a = max(finalColor.a, min(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 1.0));\n}\n\nif (shadowCatcherEnabled > 0.5) {\n let shadowCatcher = load_shadowCatcherTex(uv, 0);\n let coverage = clamp(shadowCatcher.r, 0.0, 1.0);\n let opacity = max(clamp(shadowCatcher.a / max(coverage, 0.000001), 0.0, 1.0) - (1.0 - shadowCatcherAlpha), 0.0);\n if (coverage > 0.0 || flatBackgroundColor.a > 0.5) {\n let foreground = load_foregroundTex(uv, 0);\n let background = load_catcherBackgroundTex(uv, 0);\n // An opaque flat backdrop also owns primary misses outside the receiver.\n // Its alpha contains catcher coverage plus miss coverage; only the catcher\n // fraction receives shadow. These weights come from the accumulation,\n // independently of the quantized denoising/albedo guide.\n let flatMissCoverage = select(0.0, clamp(background.a - coverage, 0.0, 1.0 - coverage), flatBackgroundColor.a > 0.5);\n var foregroundColor = gradeColor((foreground.rgb + bloomTexel.rgb) * exposure);\n var backgroundColor = gradeColor((background.rgb / max(background.a, 0.000001) + bloomTexel.rgb) * exposure);\n foregroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n backgroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n foregroundColor = applyToneMapping(foregroundColor);\n backgroundColor = applyToneMapping(backgroundColor);\n }\n foregroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(foregroundColor)' : 'pow(max(foregroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(foregroundColor), hdrOutput);\n backgroundColor = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(backgroundColor)' : 'pow(max(backgroundColor, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(backgroundColor), hdrOutput);\n if (flatBackgroundColor.a > 0.5) {\n var unbloomedBackground = gradeColor(background.rgb / max(background.a, 0.000001) * exposure);\n unbloomedBackground *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { unbloomedBackground = applyToneMapping(unbloomedBackground); }\n let encodedUnbloomedBackground = select(${sdrEncoding === 'srgb' ? 'linearToSrgb(unbloomedBackground)' : 'pow(max(unbloomedBackground, vec3f(0.0)), vec3f(1.0 / 2.2))'}, linearToSrgb(unbloomedBackground), hdrOutput);\n let bloomSpill = select(vec3f(0.0), max(backgroundColor - encodedUnbloomedBackground, vec3f(0.0)), bloomIntensity > 0.0);\n backgroundColor = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0))) + bloomSpill;\n }\n // Foreground and catcher are disjoint primary samples, not overlapping\n // alpha layers. Shadow only the catcher background before averaging.\n let shadowAlpha = coverage * opacity;\n let bloomAlpha = clamp(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 0.0, 1.0);\n let foregroundAlpha = max(foreground.a, bloomAlpha * (1.0 - coverage - flatMissCoverage));\n let backgroundAlpha = max(background.a, bloomAlpha * coverage);\n let visibleBackgroundAlpha = (backgroundAlpha - flatMissCoverage) * (1.0 - opacity) + flatMissCoverage;\n let alpha = foregroundAlpha + visibleBackgroundAlpha + shadowAlpha;\n let premultiplied = foregroundColor * foregroundAlpha\n + backgroundColor * visibleBackgroundAlpha\n + shadowCatcherColor * shadowAlpha;\n finalColor = vec4f(premultiplied / max(alpha, 0.000001), alpha);\n }\n}\n\noutput.color = finalColor;\n\n// output.color = load_bloomTex(uv, 0) * bloomIntensity;\n`;\n}\nexport const composeMain = createComposeMain();\n\n// Preserve the existing display composition, but give OIDN a floating-point,\n// linear-light image. Alpha is deliberately not used as a second color layer.\nexport function createCompositeDenoiseColorMain(output = 'output.denoiseColor', input = 'finalColor', sdrEncoding: 'gamma22' | 'srgb' = 'srgb'): string {\n const srgbDecode = 'select(pow((encoded + 0.055) / 1.055, vec3f(2.4)), encoded / 12.92, encoded <= vec3f(0.04045))';\n return /* wgsl */ `\nlet encoded = max(${input}.rgb, vec3f(0.0));\nlet displayLinear = ${sdrEncoding === 'srgb' ? srgbDecode : `select(pow(encoded, vec3f(2.2)), ${srgbDecode}, hdrOutput)`};\n${output} = vec4f(displayLinear, ${input}.a);\n\n`;\n}\nexport function createCompositeDenoiseAlbedoMain(output = 'output.denoiseAlbedo'): string {\n return /* wgsl */ `// The receiver is invisible: its visible texture is the displayed background,\n// not the neutral reflectance used for its lighting estimate. Match the beauty\n// reconstruction filter, including mixed foreground/receiver primary samples.\n// Exclude the stochastic shadow and bloom so neither is preserved as texture.\nlet rawAlbedo = load_flatBackgroundMaskTex(uv, 0);\nvar compositeAlbedo = rawAlbedo.rgb;\nif (shadowCatcherEnabled > 0.5 && flatBackgroundColor.a < 0.5) {\n let coverage = clamp(load_shadowCatcherTex(uv, 0).r, 0.0, 1.0);\n let background = load_catcherBackgroundTex(uv, 0);\n if (coverage > 0.0 && background.a > 0.0) {\n var backgroundAlbedo = gradeColor(background.rgb / background.a * exposure);\n backgroundAlbedo *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { backgroundAlbedo = applyToneMapping(backgroundAlbedo); }\n // Background alpha already includes primary catcher coverage. Retain the\n // neutral receiver for its transparent part, without counting coverage twice\n // or adding the stochastic shadow opacity to the texture guide.\n let backgroundWeight = clamp(background.a, 0.0, coverage);\n compositeAlbedo += backgroundWeight * (clamp(backgroundAlbedo, vec3f(0.0), vec3f(1.0)) - vec3f(1.0));\n }\n}\n${output} = vec4f(clamp(compositeAlbedo, vec3f(0.0), vec3f(1.0)), rawAlbedo.a);\n`;\n}\nexport const compositeDenoiseOutputMain = createCompositeDenoiseColorMain() + createCompositeDenoiseAlbedoMain();\n\nexport function createCompositeDenoiseDisplayMain(sdrEncoding: 'gamma22' | 'srgb' = 'srgb'): string {\n return /* wgsl */ `\nlet denoised = load_colorTex(uv, 0);\n// Keep the original primary coverage, including transparency. OIDN only\n// filters RGB; filtering coverage separately reintroduces silhouette seams.\n// The built-in filter weights color and coverage together and may replace it.\nlet alpha = select(load_composedTex(uv, 0).a, clamp(denoised.a, 0.0, 1.0), denoisedAlpha > 0.5);\nlet linear = max(denoised.rgb, vec3f(0.0));\nlet encoded = ${sdrEncoding === 'srgb' ? 'linearToSrgb(linear)' : 'select(pow(linear, vec3f(1.0 / 2.2)), linearToSrgb(linear), hdrOutputEnabled > 0.5)'};\noutput.color = vec4f(select(vec3f(0.0), encoded, alpha > 0.0), alpha);\n`;\n}\n\nexport const compositeDenoiseDisplayMain = createCompositeDenoiseDisplayMain();\n\n// Shared hit normalization; CPU readback retains its f32 reference path.\nexport const hdrResolveWGSL = /* wgsl */ `\nfn hdr_resolve_component(color: f32, count: f32, hit: f32, minimum_count: f32, rgb: bool) -> f32 {\nif (count <= 0.0) {\nreturn 0.0;\n}\nlet total = max(count, minimum_count);\nlet divisor = select(total, hit, (rgb && (hit > 0.0)));\nreturn (color / divisor);\n}\nfn hdr_flat_component(color: f32, coverage: f32, flat: bool, rgb: bool) -> f32 {\nif ((flat && rgb) && (coverage > 0.0)) {\nreturn (color * coverage);\n}\nreturn color;\n}\n`;\n"]}
|
|
@@ -5,19 +5,19 @@ let filtered = load_filteredTex(uv, 0).rgb;
|
|
|
5
5
|
let foreground = load_foregroundTex(uv, 0);
|
|
6
6
|
let background = load_backgroundTex(uv, 0);
|
|
7
7
|
|
|
8
|
-
var
|
|
9
|
-
var
|
|
8
|
+
var nU = foreground;
|
|
9
|
+
var nT = background;
|
|
10
10
|
if (any(filtered != original)) {
|
|
11
|
-
let
|
|
12
|
-
let
|
|
13
|
-
let scale = select(vec3f(1.0), filtered /
|
|
14
|
-
let
|
|
15
|
-
|
|
11
|
+
let yr = abs(original) > vec3f(0.000001);
|
|
12
|
+
let ah = select(vec3f(1.0), original, yr);
|
|
13
|
+
let scale = select(vec3f(1.0), filtered / ah, yr);
|
|
14
|
+
let xI = select(filtered - original, vec3f(0.0), yr);
|
|
15
|
+
nU = vec4f(foreground.rgb * scale + xI, foreground.a);
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
nT = vec4f(background.rgb * scale + xI * background.a, background.a);
|
|
18
18
|
}
|
|
19
|
-
output.foreground =
|
|
20
|
-
output.background =
|
|
19
|
+
output.foreground = nU;
|
|
20
|
+
output.background = nT;
|
|
21
21
|
`;
|
|
22
22
|
/** Custom output alpha is ignored; retain the input composition's coverage. */
|
|
23
23
|
export const customDenoiseCoverageMain = /* wgsl */ `
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** Extra entry point in the ray-tracing module; reuses its scene bindings. */
|
|
2
|
-
declare const _default: "\n@group(3) @binding(4) var<uniform> depthArea: vec4f;\n\n@compute @workgroup_size(7, 7)\nfn depthQuery(@builtin(global_invocation_id) id: vec3u) {\n let index = id.x + id.y * 7u;\n let offset = vec2f(id.xy) / 6.0 * 2.0 - 1.0;\n let uv = depthArea.xy + depthArea.zw * offset * vec2f(1.0, -1.0);\n outColor[index] = vec4f(0.0);\n if (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) { return; }\n var ray = initCameraRay(uv);\n let eye = cameraUniform.viewInv[3].xyz;\n let forward = -normalize(cameraUniform.viewInv[2].xyz);\n var si: SurfaceInteraction;\n si.triangleIndex = -1;\n // Ignore invisible catchers and alpha-cutout holes, without stochastic DOF\n // or pixel jitter. A bounded continuation prevents coincident surfaces\n // from keeping the query alive indefinitely.\n for (var layer = 0; layer < 32; layer++) {\n intersectScene(ray, &si, 0, false, false);\n if (!si.hit) { return; }\n var material: OpenPbrResolvedMaterial;\n getMaterial(&material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);\n if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {\n outColor[index] = vec4f(max(dot(si.position - eye, forward), 0.0), 0.0, 0.0, 0.0);\n return;\n }\n ray.o = si.position + ray.d * (EPS * 0.02);\n }\n}\n";
|
|
2
|
+
declare const _default: "\n@group(3) @binding(4) var<uniform> depthArea: vec4f;\n\n@compute @workgroup_size(7, 7)\nfn depthQuery(@builtin(global_invocation_id) id: vec3u) {\n let index = id.x + id.y * 7u;\n let picking = depthArea.z < 0.0;\n if (picking && index != 0u) {return;}\n let offset = vec2f(id.xy) / 6.0 * 2.0 - 1.0;\n let uv = select(depthArea.xy + depthArea.zw * offset * vec2f(1.0, -1.0), depthArea.xy, picking);\n outColor[index] = vec4f(0.0);\n if (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) { return; }\n var ray = initCameraRay(uv);\n let eye = cameraUniform.viewInv[3].xyz;\n let forward = -normalize(cameraUniform.viewInv[2].xyz);\n var si: SurfaceInteraction;\n si.triangleIndex = -1;\n // Ignore invisible catchers and alpha-cutout holes, without stochastic DOF\n // or pixel jitter. A bounded continuation prevents coincident surfaces\n // from keeping the query alive indefinitely.\n for (var layer = 0; layer < 32; layer++) {\n intersectScene(ray, &si, 0, false, false);\n if (!si.hit) { return; }\n var material: OpenPbrResolvedMaterial;\n getMaterial(&material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);\n if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {\n if (picking) {\n let instance = u32(si.instanceIndex) + 1u;\n let materialIndex = u32(si.materialIndex) + 1u;\n outColor[index] = vec4f(f32(instance & 65535u), f32(instance >> 16u),\n f32(materialIndex & 65535u), f32(materialIndex >> 16u));\n } else {\n outColor[index] = vec4f(max(dot(si.position - eye, forward), 0.0), 0.0, 0.0, 0.0);\n }\n return;\n }\n ray.o = si.position + ray.d * (EPS * 0.02);\n }\n}\n";
|
|
3
3
|
export default _default;
|
|
@@ -6,11 +6,13 @@ export default /* wgsl */ `
|
|
|
6
6
|
@compute @workgroup_size(${DEPTH_SAMPLE_GRID}, ${DEPTH_SAMPLE_GRID})
|
|
7
7
|
fn depthQuery(@builtin(global_invocation_id) id: vec3u) {
|
|
8
8
|
let index = id.x + id.y * ${DEPTH_SAMPLE_GRID}u;
|
|
9
|
+
let picking = depthArea.z < 0.0;
|
|
10
|
+
if (picking && index != 0u) {return;}
|
|
9
11
|
let offset = vec2f(id.xy) / ${DEPTH_SAMPLE_GRID - 1}.0 * 2.0 - 1.0;
|
|
10
|
-
let uv = depthArea.xy + depthArea.zw * offset * vec2f(1.0, -1.0);
|
|
12
|
+
let uv = select(depthArea.xy + depthArea.zw * offset * vec2f(1.0, -1.0), depthArea.xy, picking);
|
|
11
13
|
outColor[index] = vec4f(0.0);
|
|
12
14
|
if (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) { return; }
|
|
13
|
-
var ray =
|
|
15
|
+
var ray = cV(uv);
|
|
14
16
|
let eye = cameraUniform.viewInv[3].xyz;
|
|
15
17
|
let forward = -normalize(cameraUniform.viewInv[2].xyz);
|
|
16
18
|
var si: SurfaceInteraction;
|
|
@@ -22,9 +24,16 @@ for (var layer = 0; layer < 32; layer++) {
|
|
|
22
24
|
intersectScene(ray, &si, 0, false, false);
|
|
23
25
|
if (!si.hit) { return; }
|
|
24
26
|
var material: OpenPbrResolvedMaterial;
|
|
25
|
-
|
|
27
|
+
getMaterial(&material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
26
28
|
if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {
|
|
29
|
+
if (picking) {
|
|
30
|
+
let instance = u32(si.instanceIndex) + 1u;
|
|
31
|
+
let materialIndex = u32(si.materialIndex) + 1u;
|
|
32
|
+
outColor[index] = vec4f(f32(instance & 65535u), f32(instance >> 16u),
|
|
33
|
+
f32(materialIndex & 65535u), f32(materialIndex >> 16u));
|
|
34
|
+
} else {
|
|
27
35
|
outColor[index] = vec4f(max(dot(si.position - eye, forward), 0.0), 0.0, 0.0, 0.0);
|
|
36
|
+
}
|
|
28
37
|
return;
|
|
29
38
|
}
|
|
30
39
|
ray.o = si.position + ray.d * (EPS * 0.02);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"depthQuery.wgsl.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/depthQuery.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,8EAA8E;AAC9E,eAAe,UAAU,CAAC;;;2BAGC,iBAAiB,KAAK,iBAAiB;;4BAEpC,iBAAiB
|
|
1
|
+
{"version":3,"file":"depthQuery.wgsl.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/depthQuery.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,8EAA8E;AAC9E,eAAe,UAAU,CAAC;;;2BAGC,iBAAiB,KAAK,iBAAiB;;4BAEpC,iBAAiB;;;8BAGf,iBAAiB,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BpD,CAAC","sourcesContent":["import { DEPTH_SAMPLE_GRID } from '../depthQuery.js';\n\n/** Extra entry point in the ray-tracing module; reuses its scene bindings. */\nexport default /* wgsl */ `\n@group(3) @binding(4) var<uniform> depthArea: vec4f;\n\n@compute @workgroup_size(${DEPTH_SAMPLE_GRID}, ${DEPTH_SAMPLE_GRID})\nfn depthQuery(@builtin(global_invocation_id) id: vec3u) {\n let index = id.x + id.y * ${DEPTH_SAMPLE_GRID}u;\n let picking = depthArea.z < 0.0;\n if (picking && index != 0u) {return;}\n let offset = vec2f(id.xy) / ${DEPTH_SAMPLE_GRID - 1}.0 * 2.0 - 1.0;\n let uv = select(depthArea.xy + depthArea.zw * offset * vec2f(1.0, -1.0), depthArea.xy, picking);\n outColor[index] = vec4f(0.0);\n if (any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) { return; }\n var ray = initCameraRay(uv);\n let eye = cameraUniform.viewInv[3].xyz;\n let forward = -normalize(cameraUniform.viewInv[2].xyz);\n var si: SurfaceInteraction;\n si.triangleIndex = -1;\n // Ignore invisible catchers and alpha-cutout holes, without stochastic DOF\n // or pixel jitter. A bounded continuation prevents coincident surfaces\n // from keeping the query alive indefinitely.\n for (var layer = 0; layer < 32; layer++) {\n intersectScene(ray, &si, 0, false, false);\n if (!si.hit) { return; }\n var material: OpenPbrResolvedMaterial;\n getMaterial(&material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);\n if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {\n if (picking) {\n let instance = u32(si.instanceIndex) + 1u;\n let materialIndex = u32(si.materialIndex) + 1u;\n outColor[index] = vec4f(f32(instance & 65535u), f32(instance >> 16u),\n f32(materialIndex & 65535u), f32(materialIndex >> 16u));\n } else {\n outColor[index] = vec4f(max(dot(si.position - eye, forward), 0.0), 0.0, 0.0, 0.0);\n }\n return;\n }\n ray.o = si.position + ray.d * (EPS * 0.02);\n }\n}\n`;\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const easuShader = "\n@group(0) @binding(0) var colorImage: texture_2d<f32>;\n@group(0) @binding(1) var<uniform> outputSize: vec4f;\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {\n let p = vec2f(f32((index << 1u) & 2u), f32(index & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\nconst offsets = array<vec2i,12>(vec2i(0,-1),vec2i(1,-1),vec2i(-1,0),vec2i(0,0),vec2i(1,0),vec2i(2,0),\n vec2i(-1,1),vec2i(0,1),vec2i(1,1),vec2i(2,1),vec2i(0,2),vec2i(1,2));\nfn loadColor(p: vec2i) -> vec4f {return textureLoad(colorImage, clamp(p,vec2i(0),vec2i(textureDimensions(colorImage))-1),0);}\nfn gradient(a: f32,b: f32,c: f32,d: f32,e: f32,w: f32) -> vec3f {\n let direction = vec2f(d-b,e-a);\n let length = clamp(abs(direction)/max(vec2f(max(abs(d-c),abs(c-b)),max(abs(e-c),abs(c-a))),vec2f(1e-8)),vec2f(0),vec2f(1));\n return vec3f(direction,dot(length,length))*w;\n}\nfn easuWeight(offset: vec2f, direction: vec2f, length: vec2f, lobe: f32) -> f32 {\n let v = vec2f(dot(offset,direction),dot(offset,vec2f(-direction.y,direction.x)))*length;\n let distance = min(dot(v,v),1.0/lobe);\n let b = 0.4*distance-1.0;\n let a = lobe*distance-1.0;\n return (1.5625*b*b-0.5625)*a*a;\n}\n@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {\n let point = position.xy*vec2f(textureDimensions(colorImage))/outputSize.xy-0.5;\n let base = vec2i(floor(point)); let phase = fract(point);\n var colors: array<vec4f,12>;\n var luma: array<f32,12>;\n // FSR expects [0,1]. Normalize the neighborhood for direction estimation\n // in extended-range output; filter the original RGB without clipping it to 1.\n var range = 1.0;\n for(var i=0u;i<12u;i++){colors[i]=loadColor(base+offsets[i]);range=max(range,max(max(colors[i].r,colors[i].g),colors[i].b));}\n for(var i=0u;i<12u;i++){luma[i]=dot(colors[i].rgb/range,vec3f(0.5,1.0,0.5));}\n let g = gradient(luma[0],luma[2],luma[3],luma[4],luma[7],(1.0-phase.x)*(1.0-phase.y))+\n gradient(luma[1],luma[3],luma[4],luma[5],luma[8],phase.x*(1.0-phase.y))+\n gradient(luma[3],luma[6],luma[7],luma[8],luma[10],(1.0-phase.x)*phase.y)+\n gradient(luma[4],luma[7],luma[8],luma[9],luma[11],phase.x*phase.y);\n var direction = vec2f(1.0,0.0);\n if(dot(g.xy,g.xy)>=1.0/32768.0){direction=normalize(g.xy);}\n let edge = (g.z*0.5)*(g.z*0.5);\n let stretch = dot(direction,direction)/max(abs(direction.x),abs(direction.y));\n let length = vec2f(1.0+(stretch-1.0)*edge,1.0-0.5*edge);\n let lobe = 0.5+(0.21-0.5)*edge;\n var result=vec4f(0); var total=0.0;\n for(var i=0u;i<12u;i++){\n let weight=easuWeight(vec2f(offsets[i])-phase,direction,length,lobe);\n result+=colors[i]*weight;total+=weight;\n }\n let lower=min(min(colors[3],colors[4]),min(colors[7],colors[8]));\n let upper=max(max(colors[3],colors[4]),max(colors[7],colors[8]));\n return clamp(result/total,lower,upper);\n}\n";
|
|
2
|
+
export declare const areaDownsampleShader = "\n@group(0) @binding(0) var colorImage: texture_2d<f32>;\n@group(0) @binding(1) var<uniform> outputSize: vec4f;\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {\n let p = vec2f(f32((index << 1u) & 2u), f32(index & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\n@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {\n let scale = vec2f(textureDimensions(colorImage))/outputSize.xy;\n let start = floor(position.xy)*scale; let end = start+scale;\n var sum = vec4f(0);\n for (var y = i32(floor(start.y)); y < i32(ceil(end.y)); y++) {\n for (var x = i32(floor(start.x)); x < i32(ceil(end.x)); x++) {\n let overlap = max(vec2f(0), min(vec2f(vec2i(x+1,y+1)), end)-max(vec2f(vec2i(x,y)), start));\n let color = textureLoad(colorImage, vec2i(x,y), 0);\n sum += vec4f(color.rgb*color.a, color.a)*overlap.x*overlap.y;\n }\n }\n return vec4f(sum.rgb/max(sum.a, 1e-8), sum.a/(scale.x*scale.y));\n}\n";
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Adapted from AMD FidelityFX FSR 1, ffx_fsr1.h v1.20210629,
|
|
2
|
+
// FsrEasuSetF/FsrEasuTapF/FsrEasuF (32-bit path). MIT; see LICENSES/FidelityFX-FSR.txt.
|
|
3
|
+
// https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/master/ffx-fsr/ffx_fsr1.h
|
|
4
|
+
// Uses exact reciprocals instead of the reference's low precision approximations.
|
|
5
|
+
export const easuShader = /* wgsl */ `
|
|
6
|
+
@group(0) @binding(0) var colorImage: texture_2d<f32>;
|
|
7
|
+
@group(0) @binding(1) var<uniform> outputSize: vec4f;
|
|
8
|
+
@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {
|
|
9
|
+
let p = vec2f(f32((index << 1u) & 2u), f32(index & 2u));
|
|
10
|
+
return vec4f(p * 2.0 - 1.0, 0.0, 1.0);
|
|
11
|
+
}
|
|
12
|
+
const offsets = array<vec2i,12>(vec2i(0,-1),vec2i(1,-1),vec2i(-1,0),vec2i(0,0),vec2i(1,0),vec2i(2,0),
|
|
13
|
+
vec2i(-1,1),vec2i(0,1),vec2i(1,1),vec2i(2,1),vec2i(0,2),vec2i(1,2));
|
|
14
|
+
fn ns(p: vec2i) -> vec4f {return textureLoad(colorImage, clamp(p,vec2i(0),vec2i(textureDimensions(colorImage))-1),0);}
|
|
15
|
+
fn tB(a: f32,b: f32,c: f32,d: f32,e: f32,w: f32) -> vec3f {
|
|
16
|
+
let direction = vec2f(d-b,e-a);
|
|
17
|
+
let length = clamp(abs(direction)/max(vec2f(max(abs(d-c),abs(c-b)),max(abs(e-c),abs(c-a))),vec2f(1e-8)),vec2f(0),vec2f(1));
|
|
18
|
+
return vec3f(direction,dot(length,length))*w;
|
|
19
|
+
}
|
|
20
|
+
fn sJ(offset: vec2f, direction: vec2f, length: vec2f, lobe: f32) -> f32 {
|
|
21
|
+
let v = vec2f(dot(offset,direction),dot(offset,vec2f(-direction.y,direction.x)))*length;
|
|
22
|
+
let distance = min(dot(v,v),1.0/lobe);
|
|
23
|
+
let b = 0.4*distance-1.0;
|
|
24
|
+
let a = lobe*distance-1.0;
|
|
25
|
+
return (1.5625*b*b-0.5625)*a*a;
|
|
26
|
+
}
|
|
27
|
+
@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {
|
|
28
|
+
let point = position.xy*vec2f(textureDimensions(colorImage))/outputSize.xy-0.5;
|
|
29
|
+
let base = vec2i(floor(point)); let phase = fract(point);
|
|
30
|
+
var colors: array<vec4f,12>;
|
|
31
|
+
var lQ: array<f32,12>;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
var range = 1.0;
|
|
35
|
+
for(var i=0u;i<12u;i++){colors[i]=ns(base+offsets[i]);range=max(range,max(max(colors[i].r,colors[i].g),colors[i].b));}
|
|
36
|
+
for(var i=0u;i<12u;i++){lQ[i]=dot(colors[i].rgb/range,vec3f(0.5,1.0,0.5));}
|
|
37
|
+
let g = tB(lQ[0],lQ[2],lQ[3],lQ[4],lQ[7],(1.0-phase.x)*(1.0-phase.y))+
|
|
38
|
+
tB(lQ[1],lQ[3],lQ[4],lQ[5],lQ[8],phase.x*(1.0-phase.y))+
|
|
39
|
+
tB(lQ[3],lQ[6],lQ[7],lQ[8],lQ[10],(1.0-phase.x)*phase.y)+
|
|
40
|
+
tB(lQ[4],lQ[7],lQ[8],lQ[9],lQ[11],phase.x*phase.y);
|
|
41
|
+
var direction = vec2f(1.0,0.0);
|
|
42
|
+
if(dot(g.xy,g.xy)>=1.0/32768.0){direction=normalize(g.xy);}
|
|
43
|
+
let edge = (g.z*0.5)*(g.z*0.5);
|
|
44
|
+
let qD = dot(direction,direction)/max(abs(direction.x),abs(direction.y));
|
|
45
|
+
let length = vec2f(1.0+(qD-1.0)*edge,1.0-0.5*edge);
|
|
46
|
+
let lobe = 0.5+(0.21-0.5)*edge;
|
|
47
|
+
var result=vec4f(0); var total=0.0;
|
|
48
|
+
for(var i=0u;i<12u;i++){
|
|
49
|
+
let weight=sJ(vec2f(offsets[i])-phase,direction,length,lobe);
|
|
50
|
+
result+=colors[i]*weight;total+=weight;
|
|
51
|
+
}
|
|
52
|
+
let lower=min(min(colors[3],colors[4]),min(colors[7],colors[8]));
|
|
53
|
+
let upper=max(max(colors[3],colors[4]),max(colors[7],colors[8]));
|
|
54
|
+
return clamp(result/total,lower,upper);
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
// Not part of FSR: exact area average for inputs larger than the output,
|
|
58
|
+
// alpha-weighted so transparent texels do not darken coverage edges.
|
|
59
|
+
export const areaDownsampleShader = /* wgsl */ `
|
|
60
|
+
@group(0) @binding(0) var colorImage: texture_2d<f32>;
|
|
61
|
+
@group(0) @binding(1) var<uniform> outputSize: vec4f;
|
|
62
|
+
@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {
|
|
63
|
+
let p = vec2f(f32((index << 1u) & 2u), f32(index & 2u));
|
|
64
|
+
return vec4f(p * 2.0 - 1.0, 0.0, 1.0);
|
|
65
|
+
}
|
|
66
|
+
@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {
|
|
67
|
+
let scale = vec2f(textureDimensions(colorImage))/outputSize.xy;
|
|
68
|
+
let start = floor(position.xy)*scale; let end = start+scale;
|
|
69
|
+
var sum = vec4f(0);
|
|
70
|
+
for (var y = i32(floor(start.y)); y < i32(ceil(end.y)); y++) {
|
|
71
|
+
for (var x = i32(floor(start.x)); x < i32(ceil(end.x)); x++) {
|
|
72
|
+
let tK = max(vec2f(0), min(vec2f(vec2i(x+1,y+1)), end)-max(vec2f(vec2i(x,y)), start));
|
|
73
|
+
let color = textureLoad(colorImage, vec2i(x,y), 0);
|
|
74
|
+
sum += vec4f(color.rgb*color.a, color.a)*tK.x*tK.y;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return vec4f(sum.rgb/max(sum.a, 1e-8), sum.a/(scale.x*scale.y));
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
//# sourceMappingURL=easu.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easu.wgsl.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/easu.wgsl.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,wFAAwF;AACxF,mFAAmF;AACnF,kFAAkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDpC,CAAC;AAEF,yEAAyE;AACzE,qEAAqE;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;CAoB9C,CAAC","sourcesContent":["// Adapted from AMD FidelityFX FSR 1, ffx_fsr1.h v1.20210629,\n// FsrEasuSetF/FsrEasuTapF/FsrEasuF (32-bit path). MIT; see LICENSES/FidelityFX-FSR.txt.\n// https://github.com/GPUOpen-Effects/FidelityFX-FSR/blob/master/ffx-fsr/ffx_fsr1.h\n// Uses exact reciprocals instead of the reference's low precision approximations.\nexport const easuShader = /* wgsl */ `\n@group(0) @binding(0) var colorImage: texture_2d<f32>;\n@group(0) @binding(1) var<uniform> outputSize: vec4f;\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {\n let p = vec2f(f32((index << 1u) & 2u), f32(index & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\nconst offsets = array<vec2i,12>(vec2i(0,-1),vec2i(1,-1),vec2i(-1,0),vec2i(0,0),vec2i(1,0),vec2i(2,0),\n vec2i(-1,1),vec2i(0,1),vec2i(1,1),vec2i(2,1),vec2i(0,2),vec2i(1,2));\nfn loadColor(p: vec2i) -> vec4f {return textureLoad(colorImage, clamp(p,vec2i(0),vec2i(textureDimensions(colorImage))-1),0);}\nfn gradient(a: f32,b: f32,c: f32,d: f32,e: f32,w: f32) -> vec3f {\n let direction = vec2f(d-b,e-a);\n let length = clamp(abs(direction)/max(vec2f(max(abs(d-c),abs(c-b)),max(abs(e-c),abs(c-a))),vec2f(1e-8)),vec2f(0),vec2f(1));\n return vec3f(direction,dot(length,length))*w;\n}\nfn easuWeight(offset: vec2f, direction: vec2f, length: vec2f, lobe: f32) -> f32 {\n let v = vec2f(dot(offset,direction),dot(offset,vec2f(-direction.y,direction.x)))*length;\n let distance = min(dot(v,v),1.0/lobe);\n let b = 0.4*distance-1.0;\n let a = lobe*distance-1.0;\n return (1.5625*b*b-0.5625)*a*a;\n}\n@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {\n let point = position.xy*vec2f(textureDimensions(colorImage))/outputSize.xy-0.5;\n let base = vec2i(floor(point)); let phase = fract(point);\n var colors: array<vec4f,12>;\n var luma: array<f32,12>;\n // FSR expects [0,1]. Normalize the neighborhood for direction estimation\n // in extended-range output; filter the original RGB without clipping it to 1.\n var range = 1.0;\n for(var i=0u;i<12u;i++){colors[i]=loadColor(base+offsets[i]);range=max(range,max(max(colors[i].r,colors[i].g),colors[i].b));}\n for(var i=0u;i<12u;i++){luma[i]=dot(colors[i].rgb/range,vec3f(0.5,1.0,0.5));}\n let g = gradient(luma[0],luma[2],luma[3],luma[4],luma[7],(1.0-phase.x)*(1.0-phase.y))+\n gradient(luma[1],luma[3],luma[4],luma[5],luma[8],phase.x*(1.0-phase.y))+\n gradient(luma[3],luma[6],luma[7],luma[8],luma[10],(1.0-phase.x)*phase.y)+\n gradient(luma[4],luma[7],luma[8],luma[9],luma[11],phase.x*phase.y);\n var direction = vec2f(1.0,0.0);\n if(dot(g.xy,g.xy)>=1.0/32768.0){direction=normalize(g.xy);}\n let edge = (g.z*0.5)*(g.z*0.5);\n let stretch = dot(direction,direction)/max(abs(direction.x),abs(direction.y));\n let length = vec2f(1.0+(stretch-1.0)*edge,1.0-0.5*edge);\n let lobe = 0.5+(0.21-0.5)*edge;\n var result=vec4f(0); var total=0.0;\n for(var i=0u;i<12u;i++){\n let weight=easuWeight(vec2f(offsets[i])-phase,direction,length,lobe);\n result+=colors[i]*weight;total+=weight;\n }\n let lower=min(min(colors[3],colors[4]),min(colors[7],colors[8]));\n let upper=max(max(colors[3],colors[4]),max(colors[7],colors[8]));\n return clamp(result/total,lower,upper);\n}\n`;\n\n// Not part of FSR: exact area average for inputs larger than the output,\n// alpha-weighted so transparent texels do not darken coverage edges.\nexport const areaDownsampleShader = /* wgsl */ `\n@group(0) @binding(0) var colorImage: texture_2d<f32>;\n@group(0) @binding(1) var<uniform> outputSize: vec4f;\n@vertex fn vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {\n let p = vec2f(f32((index << 1u) & 2u), f32(index & 2u));\n return vec4f(p * 2.0 - 1.0, 0.0, 1.0);\n}\n@fragment fn fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {\n let scale = vec2f(textureDimensions(colorImage))/outputSize.xy;\n let start = floor(position.xy)*scale; let end = start+scale;\n var sum = vec4f(0);\n for (var y = i32(floor(start.y)); y < i32(ceil(end.y)); y++) {\n for (var x = i32(floor(start.x)); x < i32(ceil(end.x)); x++) {\n let overlap = max(vec2f(0), min(vec2f(vec2i(x+1,y+1)), end)-max(vec2f(vec2i(x,y)), start));\n let color = textureLoad(colorImage, vec2i(x,y), 0);\n sum += vec4f(color.rgb*color.a, color.a)*overlap.x*overlap.y;\n }\n }\n return vec4f(sum.rgb/max(sum.a, 1e-8), sum.a/(scale.x*scale.y));\n}\n`;\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Scene-linear log2 range covered by the tone lookup table. */
|
|
2
|
+
export declare const TONE_LUT_LOG2: readonly [-24, 24];
|
|
3
|
+
export declare const TONE_LUT_SIZE = 1024;
|
|
4
|
+
/** Detail compensation defaults and fixed regularizers shared by the Web and native passes. */
|
|
5
|
+
export declare const EASU_DETAIL: {
|
|
6
|
+
ratioRange: readonly [0.7, 1.43];
|
|
7
|
+
depthThreshold: number;
|
|
8
|
+
coverageThreshold: number;
|
|
9
|
+
minimumAlbedo: number;
|
|
10
|
+
depthTolerance: number;
|
|
11
|
+
guidedEpsilon: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* guided: scale only the albedo-correlated part of local scene-linear radiance (default);
|
|
15
|
+
* separate: lobe-share approximation; silhouettes: depth-guided edge reconstruction.
|
|
16
|
+
* The last two are retained for comparisons.
|
|
17
|
+
*/
|
|
18
|
+
export declare function easuDetailShader(separate?: boolean, silhouettes?: boolean, guided?: boolean): string;
|
|
19
|
+
export declare const albedoDownsampleShader: (depthOutput?: boolean) => string;
|
|
20
|
+
export declare const toneLutShader: string;
|
|
21
|
+
export declare const guidedCoefficientShader: string;
|