@zephyr3d/scene 0.9.20 → 0.9.22
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/dist/camera/camera.js +208 -208
- package/dist/camera/camera.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/posteffect/posteffect.js +16 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/ssgi.js +644 -0
- package/dist/posteffect/ssgi.js.map +1 -0
- package/dist/posteffect/sss.js +129 -44
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/render/lightpass.js +5 -1
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +21 -6
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +41 -0
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +42 -39
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/shaders/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shadow/esm.js +3 -1
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +4 -1
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +4 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +2 -0
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +5 -1
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +4 -1
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -1
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/package.json +1 -1
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssgi.js","sources":["../../src/posteffect/ssgi.ts"],"sourcesContent":["import { AbstractPostEffect, PostEffectLayer } from './posteffect';\nimport type { PostEffectSetupContext } from './posteffect';\nimport { linearToGamma } from '../shaders/misc';\nimport type { BindGroup, FrameBuffer, GPUProgram, Texture2D } from '@zephyr3d/device';\nimport type { DrawContext } from '../render';\nimport { screenSpaceRayTracing_HiZ, screenSpaceRayTracing_Linear2D } from '../shaders/ssr';\nimport { SSGI_rand2, SSGI_cosineSampleHemisphere } from '../shaders/ssgi';\nimport type { Nullable } from '@zephyr3d/base';\nimport { Matrix4x4, Vector2, Vector4 } from '@zephyr3d/base';\nimport { copyTexture, fetchSampler } from '../utility/misc';\nimport { BilateralBlurBlitter } from '../blitter/bilateralblur';\nimport { ShaderHelper } from '../material';\nimport { RGHistoryResources } from '../render/rendergraph/history_resources';\nimport { FrameResources } from '../render/rendergraph/blackboard';\nimport type { RGExecuteContext, RGHandle, RGPassBuilder, RGTextureDesc } from '../render/rendergraph/types';\n\n/**\n * SSGI post effect\n *\n * @remarks\n * Screen space global illumination: gathers one-bounce indirect diffuse\n * lighting by cosine-weighted hemisphere ray marching against the scene\n * depth buffer (Hi-Z accelerated when available), then denoises the result\n * with a bilateral blur and optional temporal accumulation before adding\n * it to the scene color. Internal used in light pass.\n *\n * @internal\n */\nexport class SSGI extends AbstractPostEffect {\n private static _tracePrograms: Record<string, GPUProgram> = {};\n private static _combineProgram?: GPUProgram;\n private static _temporalProgram?: GPUProgram;\n private static _blurBlitterH: Nullable<BilateralBlurBlitter> = null;\n private static _blurBlitterV: Nullable<BilateralBlurBlitter> = null;\n private _traceBindGroups: Record<string, BindGroup>;\n private _combineBindGroup: Nullable<BindGroup>;\n private _temporalBindGroup: Nullable<BindGroup>;\n /**\n * Creates an instance of SSGI post effect\n */\n constructor() {\n super();\n this._layer = PostEffectLayer.opaque;\n this._traceBindGroups = {};\n this._combineBindGroup = null;\n this._temporalBindGroup = null;\n }\n /** {@inheritDoc AbstractPostEffect.requireLinearDepthTexture} */\n requireLinearDepthTexture() {\n return true;\n }\n /** {@inheritDoc AbstractPostEffect.requireDepthAttachment} */\n requireDepthAttachment() {\n return true;\n }\n /** {@inheritDoc AbstractPostEffect.requireMotionVectorTexture} */\n requireMotionVectorTexture(ctx: DrawContext) {\n return !!ctx.camera.ssgiTemporal;\n }\n /**\n * Declares SSGI's internal steps (trace, optional bilateral blur, optional\n * temporal resolve, combine) as individual render graph passes.\n */\n setup(s: PostEffectSetupContext): RGHandle {\n const { graph, ctx, history } = s;\n // SSGI needs the surface normal MRT and dynamic loops; neither is\n // available on WebGL1. Pass the input through untouched in that case.\n if (ctx.device.type === 'webgl' || !s.blackboard.get(FrameResources.SSRNormal)) {\n return s.input;\n }\n const camera = ctx.camera;\n const halfRes = !!camera.ssgiHalfResolution;\n const traceWidth = Math.max(1, halfRes ? s.width >> 1 : s.width);\n const traceHeight = Math.max(1, halfRes ? s.height >> 1 : s.height);\n const linearDepthHandle = s.blackboard.get(FrameResources.LinearDepth);\n const texDesc: RGTextureDesc = {\n format: 'rgba16f',\n sizeMode: 'absolute',\n width: traceWidth,\n height: traceHeight\n };\n const readCommon = (builder: RGPassBuilder) => {\n if (linearDepthHandle) {\n builder.read(linearDepthHandle);\n }\n // Normal MRT, HiZ and the scene color are reached through DrawContext\n // fields; the dependency list carries their handles.\n for (const dep of s.dependencies) {\n builder.read(dep);\n }\n };\n const getLinearDepth = (rg: RGExecuteContext) =>\n linearDepthHandle ? rg.getTexture<Texture2D>(linearDepthHandle) : ctx.linearDepthTexture!;\n\n // 1. Trace cosine-weighted hemisphere rays against the depth buffer and\n // gather the radiance at the hit points.\n const traceHandle = graph.addPass('SSGI:Trace', (builder) => {\n builder.read(s.input);\n readCommon(builder);\n const out = builder.createTexture({ ...texDesc, label: 'SSGI:trace' });\n const fb = builder.createFramebuffer({\n label: 'SSGI:traceFB',\n width: traceWidth,\n height: traceHeight,\n colorAttachments: out,\n depthAttachment: null,\n ignoreDepthStencil: true\n });\n builder.setExecute((rg) => {\n const device = ctx.device;\n device.pushDeviceStates();\n try {\n device.setFramebuffer(rg.getFramebuffer(fb));\n this.trace(ctx, rg.getTexture<Texture2D>(s.input), getLinearDepth(rg));\n } finally {\n device.popDeviceStates();\n }\n });\n return out;\n });\n\n // 2. Temporal accumulation BEFORE the spatial blur: accumulating the raw\n // per-pixel estimate raises the effective sample count over time, and the\n // blur then only has to clean the residual noise. (Blurring first would\n // turn per-frame noise into large low-frequency blobs that flicker.)\n // The history stores the pre-blur accumulated signal.\n const wantTemporal = !!camera.ssgiTemporal;\n const motionVectorHandle = wantTemporal ? s.blackboard.get(FrameResources.MotionVector) : null;\n const historySize = { width: traceWidth, height: traceHeight };\n const prevRadianceHandle =\n wantTemporal && history && motionVectorHandle\n ? history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_RADIANCE, texDesc, historySize)\n : null;\n const prevMotionVectorHandle =\n wantTemporal && history && motionVectorHandle\n ? history.importPreviousIfCompatible(\n graph,\n RGHistoryResources.SSGI_MOTION_VECTOR,\n {\n format: 'rgba16f',\n sizeMode: 'absolute',\n width: s.width,\n height: s.height\n },\n { width: s.width, height: s.height }\n )\n : null;\n let radianceHandle = traceHandle;\n const canTemporal = !!(motionVectorHandle && prevRadianceHandle && prevMotionVectorHandle);\n if (canTemporal) {\n radianceHandle = graph.addPass('SSGI:Temporal', (builder) => {\n builder.read(traceHandle);\n builder.read(prevRadianceHandle!);\n builder.read(prevMotionVectorHandle!);\n builder.read(motionVectorHandle!);\n readCommon(builder);\n const out = builder.createTexture({ ...texDesc, label: 'SSGI:temporal' });\n const fb = builder.createFramebuffer({\n label: 'SSGI:temporalFB',\n width: traceWidth,\n height: traceHeight,\n colorAttachments: out,\n depthAttachment: null,\n ignoreDepthStencil: true\n });\n builder.setExecute((rg) => {\n const device = ctx.device;\n device.pushDeviceStates();\n try {\n this.temporal(\n ctx,\n rg.getTexture<Texture2D>(traceHandle),\n rg.getTexture<Texture2D>(prevRadianceHandle!),\n rg.getTexture<Texture2D>(prevMotionVectorHandle!),\n rg.getFramebuffer<FrameBuffer>(fb)\n );\n } finally {\n device.popDeviceStates();\n }\n });\n return out;\n });\n }\n // The accumulated (pre-blur) signal is what feeds next frame's history.\n const accumulatedHandle = radianceHandle;\n\n // 3. Bilateral blur (horizontal + vertical) guided by scene depth cleans\n // the residual noise left after accumulation.\n if (camera.ssgiBlurKernelSize > 0) {\n const blurInputHandle = radianceHandle;\n radianceHandle = graph.addPass('SSGI:Blur', (builder) => {\n builder.read(blurInputHandle);\n readCommon(builder);\n const middle = builder.createTexture({ ...texDesc, label: 'SSGI:blurH' });\n const out = builder.createTexture({ ...texDesc, label: 'SSGI:blur' });\n const middleFB = builder.createFramebuffer({\n label: 'SSGI:blurHFB',\n width: traceWidth,\n height: traceHeight,\n colorAttachments: middle,\n depthAttachment: null,\n ignoreDepthStencil: true\n });\n const outFB = builder.createFramebuffer({\n label: 'SSGI:blurFB',\n width: traceWidth,\n height: traceHeight,\n colorAttachments: out,\n depthAttachment: null,\n ignoreDepthStencil: true\n });\n builder.setExecute((rg) => {\n const device = ctx.device;\n device.pushDeviceStates();\n try {\n const depthTex = getLinearDepth(rg);\n const blitterH = (SSGI._blurBlitterH = SSGI._blurBlitterH ?? new BilateralBlurBlitter(false));\n this.blurPass(\n ctx,\n blitterH,\n depthTex,\n rg.getTexture<Texture2D>(blurInputHandle),\n rg.getFramebuffer<FrameBuffer>(middleFB)\n );\n const blitterV = (SSGI._blurBlitterV = SSGI._blurBlitterV ?? new BilateralBlurBlitter(true));\n this.blurPass(\n ctx,\n blitterV,\n depthTex,\n rg.getTexture<Texture2D>(middle),\n rg.getFramebuffer<FrameBuffer>(outFB)\n );\n } finally {\n device.popDeviceStates();\n }\n });\n return out;\n });\n }\n\n // 4. Upsample, modulate by the albedo approximation and add to the scene\n // color; queue history commits.\n const finalRadianceHandle = radianceHandle;\n return graph.addPass('PostEffect:SSGI', (builder) => {\n builder.read(s.input);\n builder.read(finalRadianceHandle);\n if (accumulatedHandle !== finalRadianceHandle) {\n builder.read(accumulatedHandle);\n }\n if (motionVectorHandle) {\n builder.read(motionVectorHandle);\n }\n readCommon(builder);\n const output = s.createOutput(builder, { needDepthAttachment: true });\n builder.setExecute((rg) => {\n const device = ctx.device;\n device.pushDeviceStates();\n try {\n device.setFramebuffer(output.framebuffer ? rg.getFramebuffer(output.framebuffer) : null);\n const inputTex = rg.getTexture<Texture2D>(s.input);\n const radianceTex = rg.getTexture<Texture2D>(finalRadianceHandle);\n copyTexture(\n inputTex,\n device.getFramebuffer()!,\n fetchSampler('clamp_nearest_nomip'),\n AbstractPostEffect.getDefaultRenderState(ctx, 'eq')\n );\n this.combine(ctx, inputTex, radianceTex, output.srgbOutput);\n // Commit history whenever temporal is wanted - even on frames where\n // the temporal pass could not run yet (no compatible history). This\n // seeds the very first frame; gating the commit on canTemporal\n // would deadlock: no history -> no temporal -> no commit -> no\n // history, forever.\n if (wantTemporal && history && motionVectorHandle) {\n // Commit the PRE-blur accumulated signal: feeding the blurred\n // result back would compound the blur every frame.\n const accumulatedTex = rg.getTexture<Texture2D>(accumulatedHandle);\n history.queueRetainedCommit(\n RGHistoryResources.SSGI_RADIANCE,\n {\n format: accumulatedTex.format,\n sizeMode: 'absolute',\n width: accumulatedTex.width,\n height: accumulatedTex.height\n },\n { width: accumulatedTex.width, height: accumulatedTex.height },\n accumulatedTex\n );\n if (ctx.motionVectorTexture) {\n history.queueRetainedCommit(\n RGHistoryResources.SSGI_MOTION_VECTOR,\n {\n format: ctx.motionVectorTexture.format,\n sizeMode: 'absolute',\n width: ctx.motionVectorTexture.width,\n height: ctx.motionVectorTexture.height\n },\n { width: ctx.motionVectorTexture.width, height: ctx.motionVectorTexture.height },\n ctx.motionVectorTexture\n );\n }\n }\n } finally {\n device.popDeviceStates();\n }\n });\n return output.color;\n });\n }\n /** @internal */\n blurPass(\n ctx: DrawContext,\n blitter: BilateralBlurBlitter,\n depthTex: Texture2D,\n srcTex: Texture2D,\n fbTo: FrameBuffer\n ) {\n const camera = ctx.camera;\n blitter.kernelRadius = (Math.max(1, camera.ssgiBlurKernelSize >> 0) - 1) >> 1;\n blitter.stdDev = camera.ssgiBlurStdDev;\n blitter.size = new Vector2(srcTex.width, srcTex.height);\n blitter.depthTex = depthTex;\n blitter.depthCutoff = camera.ssgiBlurDepthCutoff;\n blitter.blurSizeTex = null;\n blitter.sampler = fetchSampler('clamp_nearest_nomip');\n blitter.cameraNearFar.setXY(camera.getNearPlane(), camera.getFarPlane());\n blitter.srgbOut = false;\n blitter.blit(srcTex, fbTo, fetchSampler('clamp_linear_nomip'));\n }\n /** @internal */\n trace(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D) {\n const device = ctx.device;\n const hash = `${!!ctx.HiZTexture}:${!!ctx.SSRCalcThickness}`;\n let program = SSGI._tracePrograms[hash];\n if (program === undefined) {\n const created = this._createTraceProgram(ctx);\n if (!created) {\n return;\n }\n program = created;\n SSGI._tracePrograms[hash] = program;\n }\n let bindGroup = this._traceBindGroups[hash];\n if (!bindGroup) {\n bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);\n this._traceBindGroups[hash] = bindGroup;\n }\n const camera = ctx.camera;\n const nearestSampler = fetchSampler('clamp_nearest');\n const linearSampler = fetchSampler('clamp_linear');\n const fb = device.getFramebuffer()!;\n const traceWidth = fb.getWidth();\n const traceHeight = fb.getHeight();\n bindGroup.setTexture('colorTex', inputColorTexture, linearSampler);\n bindGroup.setTexture('normalTex', ctx.SSRNormalTexture!, nearestSampler);\n bindGroup.setTexture('depthTex', sceneDepthTexture, nearestSampler);\n bindGroup.setValue('cameraNearFar', new Vector2(camera.getNearPlane(), camera.getFarPlane()));\n bindGroup.setValue('projMatrix', camera.getProjectionMatrix());\n bindGroup.setValue('invProjMatrix', Matrix4x4.invert(camera.getProjectionMatrix()));\n bindGroup.setValue('viewMatrix', camera.viewMatrix);\n bindGroup.setValue(\n 'ssgiParams',\n new Vector4(camera.ssgiRadius, camera.ssgiMaxSteps, camera.ssgiThickness, camera.ssgiSamples)\n );\n // Advance the noise sequence only when the temporal resolve can converge\n // it; a static pattern is less objectionable than unaccumulated flicker.\n bindGroup.setValue('frameIndex', camera.ssgiTemporal ? device.frameInfo.frameCounter % 1024 : 0);\n if (ctx.HiZTexture) {\n bindGroup.setTexture('hizTex', ctx.HiZTexture, nearestSampler);\n bindGroup.setValue('depthMipLevels', ctx.HiZTexture.mipLevelCount);\n bindGroup.setValue(\n 'targetSize',\n new Vector4(traceWidth, traceHeight, ctx.HiZTexture.width, ctx.HiZTexture.height)\n );\n } else {\n bindGroup.setValue('ssgiStride', camera.ssgiStride);\n bindGroup.setValue(\n 'targetSize',\n new Vector4(traceWidth, traceHeight, sceneDepthTexture.width, sceneDepthTexture.height)\n );\n }\n bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\n device.setProgram(program);\n device.setBindGroup(0, bindGroup);\n this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'always'));\n }\n /** @internal */\n temporal(\n ctx: DrawContext,\n currentRadianceTex: Texture2D,\n prevRadianceTex: Texture2D,\n prevMotionVectorTex: Texture2D,\n outFramebuffer: FrameBuffer\n ) {\n const device = ctx.device;\n let program = SSGI._temporalProgram;\n if (!program) {\n program = this._createTemporalProgram(ctx);\n SSGI._temporalProgram = program;\n }\n if (!this._temporalBindGroup) {\n this._temporalBindGroup = device.createBindGroup(program.bindGroupLayouts[0]);\n }\n this._temporalBindGroup.setTexture(\n 'historyColorTex',\n prevRadianceTex,\n fetchSampler('clamp_linear_nomip')\n );\n this._temporalBindGroup.setTexture(\n 'currentColorTex',\n currentRadianceTex,\n fetchSampler('clamp_nearest_nomip')\n );\n this._temporalBindGroup.setTexture(\n 'motionVector',\n ctx.motionVectorTexture!,\n fetchSampler('clamp_linear_nomip')\n );\n this._temporalBindGroup.setTexture(\n 'prevMotionVector',\n prevMotionVectorTex,\n fetchSampler('clamp_linear_nomip')\n );\n this._temporalBindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\n this._temporalBindGroup.setValue(\n 'texSize',\n new Vector2(currentRadianceTex.width, currentRadianceTex.height)\n );\n this._temporalBindGroup.setValue('temporalWeight', ctx.camera.ssgiTemporalWeight);\n device.setFramebuffer(outFramebuffer);\n device.setProgram(program);\n device.setBindGroup(0, this._temporalBindGroup);\n this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'always'));\n }\n /** @internal */\n combine(ctx: DrawContext, inputColorTexture: Texture2D, radianceTex: Texture2D, srgbOut: boolean) {\n const device = ctx.device;\n let program = SSGI._combineProgram;\n if (program === undefined) {\n program = this._createCombineProgram(ctx);\n SSGI._combineProgram = program;\n }\n if (!this._combineBindGroup) {\n this._combineBindGroup = device.createBindGroup(program!.bindGroupLayouts[0]);\n }\n this._combineBindGroup.setTexture('colorTex', inputColorTexture, fetchSampler('clamp_nearest'));\n this._combineBindGroup.setTexture('radianceTex', radianceTex, fetchSampler('clamp_linear'));\n this._combineBindGroup.setValue('ssgiIntensity', ctx.camera.ssgiIntensity);\n this._combineBindGroup.setValue(\n 'targetSize',\n new Vector2(inputColorTexture.width, inputColorTexture.height)\n );\n this._combineBindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\n this._combineBindGroup.setValue('srgbOut', srgbOut ? 1 : 0);\n device.setProgram(program);\n device.setBindGroup(0, this._combineBindGroup);\n this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, 'gt'));\n }\n /** @internal */\n private _createTraceProgram(ctx: DrawContext): Nullable<GPUProgram> {\n const program = ctx.device.buildRenderProgram({\n vertex(pb) {\n this.flip = pb.int().uniform(0);\n this.$inputs.pos = pb.vec2().attrib('position');\n this.$outputs.uv = pb.vec2();\n pb.main(function () {\n this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\n this.$if(pb.notEqual(this.flip, 0), function () {\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\n });\n });\n },\n fragment(pb) {\n this.colorTex = pb.tex2D().uniform(0);\n this.normalTex = pb.tex2D().uniform(0);\n this.depthTex = pb.tex2D().uniform(0);\n this.cameraNearFar = pb.vec2().uniform(0);\n this.projMatrix = pb.mat4().uniform(0);\n this.invProjMatrix = pb.mat4().uniform(0);\n this.viewMatrix = pb.mat4().uniform(0);\n // (radius, maxIterations, thickness, numRays)\n this.ssgiParams = pb.vec4().uniform(0);\n this.frameIndex = pb.float().uniform(0);\n this.targetSize = pb.vec4().uniform(0);\n if (ctx.HiZTexture) {\n this.hizTex = pb.tex2D().uniform(0);\n this.depthMipLevels = pb.int().uniform(0);\n } else {\n this.ssgiStride = pb.float().uniform(0);\n }\n this.$outputs.outColor = pb.vec4();\n pb.func('getPosition', [pb.vec2('uv'), pb.mat4('mat')], function () {\n this.$l.linearDepth = ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0);\n this.$l.nonLinearDepth = pb.div(\n pb.sub(pb.div(this.cameraNearFar.x, this.linearDepth), this.cameraNearFar.y),\n pb.sub(this.cameraNearFar.x, this.cameraNearFar.y)\n );\n this.$l.clipSpacePos = pb.vec4(\n pb.sub(pb.mul(this.uv, 2), pb.vec2(1)),\n pb.sub(pb.mul(pb.clamp(this.nonLinearDepth, 0, 1), 2), 1),\n 1\n );\n this.$l.wPos = pb.mul(this.mat, this.clipSpacePos);\n this.$return(pb.vec4(pb.div(this.wPos.xyz, this.wPos.w), this.linearDepth));\n });\n pb.main(function () {\n this.$l.screenUV = pb.div(pb.vec2(this.$builtins.fragCoord.xy), this.targetSize.xy);\n this.$l.color = pb.vec3(0);\n this.$l.pos = this.getPosition(this.screenUV, this.invProjMatrix);\n this.$if(pb.lessThan(this.pos.w, 1), function () {\n this.$l.viewPos = this.pos.xyz;\n this.$l.worldNormal = pb.sub(\n pb.mul(pb.textureSampleLevel(this.normalTex, this.screenUV, 0).rgb, 2),\n pb.vec3(1)\n );\n this.$l.viewNormal = pb.normalize(pb.mul(this.viewMatrix, pb.vec4(this.worldNormal, 0)).xyz);\n this.$l.numRays = pb.max(this.ssgiParams.w, 1);\n this.$l.sum = pb.vec3(0);\n this.$for(pb.float('ray'), 0, this.numRays, function () {\n this.$l.rand = SSGI_rand2(\n this,\n pb.vec2(this.$builtins.fragCoord.xy),\n pb.add(pb.mul(this.frameIndex, this.numRays), this.ray)\n );\n this.$l.rayDir = SSGI_cosineSampleHemisphere(this, this.viewNormal, this.rand);\n this.$l.hitInfo = pb.vec4(0);\n if (ctx.HiZTexture) {\n this.hitInfo = screenSpaceRayTracing_HiZ(\n this,\n this.viewPos,\n this.rayDir,\n this.viewMatrix,\n this.projMatrix,\n this.invProjMatrix,\n this.cameraNearFar,\n this.depthMipLevels,\n this.ssgiParams.y,\n this.ssgiParams.x,\n this.ssgiParams.z,\n this.targetSize,\n this.hizTex,\n this.normalTex\n );\n } else {\n this.hitInfo = screenSpaceRayTracing_Linear2D(\n this,\n this.viewPos,\n this.rayDir,\n this.viewMatrix,\n this.projMatrix,\n this.invProjMatrix,\n this.cameraNearFar,\n this.ssgiParams.x,\n this.ssgiParams.y,\n this.ssgiParams.z,\n this.ssgiStride,\n this.targetSize,\n this.depthTex,\n this.normalTex,\n // Backface depth is only present when the depth prepass was\n // built with SSR thickness computation enabled.\n !!ctx.SSRCalcThickness\n );\n }\n this.$l.hitAlpha = pb.clamp(this.hitInfo.w, 0, 1);\n // Hemisphere rays frequently graze the screen plane; the\n // projective ray setup can then produce Inf/NaN which would be\n // smeared into large blocks by the bilateral blur. NaN fails\n // any comparison, so this test also rejects it.\n this.$l.hitValid = pb.and(\n pb.all(pb.lessThan(pb.abs(this.hitInfo), pb.vec4(1e30))),\n pb.greaterThan(this.hitAlpha, 0)\n );\n this.$if(this.hitValid, function () {\n this.$l.hitUV = pb.clamp(this.hitInfo.xy, pb.vec2(0), pb.vec2(1));\n // Firefly clamp: an HDR sun/sky sample can be orders of\n // magnitude brighter than the surroundings; unclamped it\n // dominates the low-spp estimate as isolated bright dots no\n // spatial filter can remove.\n this.$l.radiance = pb.min(\n pb.textureSampleLevel(this.colorTex, this.hitUV, 0).rgb,\n pb.vec3(4)\n );\n this.sum = pb.add(this.sum, pb.mul(this.radiance, this.hitAlpha));\n });\n });\n // Cosine-weighted sampling: the irradiance estimate over the\n // hemisphere reduces to the plain average of the hit radiances.\n this.color = pb.div(this.sum, this.numRays);\n });\n // Reinhard-compress into [0, 1) (mirrors the SSR intersect pass).\n // The bilateral blur weights neighbors by color distance; in linear\n // HDR a firefly is \"far\" from every neighbor and survives the blur\n // untouched. Compressed, bright outliers stay within blurring range\n // and the denoiser can actually converge them. combine() inverts\n // this mapping.\n this.color = pb.div(this.color, pb.add(this.color, pb.vec3(1)));\n this.$outputs.outColor = pb.vec4(this.color, 1);\n });\n }\n });\n if (!program) {\n return null;\n }\n program.name = '@SSGI_Trace';\n return program;\n }\n /** @internal */\n private _createTemporalProgram(ctx: DrawContext) {\n const program = ctx.device.buildRenderProgram({\n vertex(pb) {\n this.flip = pb.int().uniform(0);\n this.$inputs.pos = pb.vec2().attrib('position');\n this.$outputs.uv = pb.vec2();\n pb.main(function () {\n this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\n this.$if(pb.notEqual(this.flip, 0), function () {\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\n });\n });\n },\n fragment(pb) {\n this.historyColorTex = pb.tex2D().uniform(0);\n this.currentColorTex = pb.tex2D().uniform(0);\n this.motionVector = pb.tex2D().uniform(0);\n this.prevMotionVector = pb.tex2D().uniform(0);\n this.texSize = pb.vec2().uniform(0);\n this.temporalWeight = pb.float().uniform(0);\n this.$outputs.outColor = pb.vec4();\n pb.main(function () {\n // Sample-count adaptive accumulation with fixed-gamma variance\n // clipping. The accumulated frame count N rides in the alpha\n // channel of the radiance history: early frames blend with\n // 1/(N+1) (fast convergence), converged pixels blend at the\n // temporalWeight cap. A FIXED-weight EMA never settles - its\n // stationary state is a random walk inside the clip box, visible\n // as slowly rippling low-frequency noise after the blur. With\n // count-based weighting the estimator is a true running average,\n // so the converged value stops moving.\n // TAA-style box collapsing with velocity is deliberately avoided:\n // camera jitter alone would collapse the box and reject all\n // history, preventing convergence of the stochastic signal.\n this.$l.screenUV = pb.div(pb.vec2(this.$builtins.fragCoord.xy), this.texSize);\n this.$l.currentColor = pb.textureSampleLevel(this.currentColorTex, this.screenUV, 0).rgb;\n this.$l.velocitySample = pb.textureSampleLevel(this.motionVector, this.screenUV, 0);\n this.$l.velocity = this.velocitySample.xy;\n // Sky/unwritten motion vector sentinel: no history\n this.$if(\n pb.and(pb.greaterThanEqual(this.velocity.x, 5e4), pb.greaterThanEqual(this.velocity.y, 5e4)),\n function () {\n this.$outputs.outColor = pb.vec4(this.currentColor, 1);\n }\n ).$else(function () {\n this.$l.reprojectedUV = pb.sub(this.screenUV, this.velocity);\n this.$l.offscreen = pb.or(\n pb.any(pb.lessThan(this.reprojectedUV, pb.vec2(0))),\n pb.any(pb.greaterThan(this.reprojectedUV, pb.vec2(1)))\n );\n this.$if(this.offscreen, function () {\n this.$outputs.outColor = pb.vec4(this.currentColor, 1);\n }).$else(function () {\n this.$l.historySample = pb.textureSampleLevel(this.historyColorTex, this.reprojectedUV, 0);\n this.$l.historyColor = this.historySample.rgb;\n this.$l.historyCount = pb.max(this.historySample.a, 1);\n // 3x3 neighborhood statistics of the current stochastic estimate\n this.$l.m1 = pb.vec3(0);\n this.$l.m2 = pb.vec3(0);\n for (let i = -1; i <= 1; i++) {\n for (let j = -1; j <= 1; j++) {\n const c = `c${(i + 1) * 3 + j + 1}`;\n this.$l[c] = pb.textureSampleLevel(\n this.currentColorTex,\n pb.add(this.screenUV, pb.div(pb.vec2(i, j), this.texSize)),\n 0\n ).rgb;\n this.m1 = pb.add(this.m1, this[c]);\n this.m2 = pb.add(this.m2, pb.mul(this[c], this[c]));\n }\n }\n this.m1 = pb.div(this.m1, 9);\n this.m2 = pb.div(this.m2, 9);\n this.$l.sigma = pb.sqrt(pb.max(pb.sub(this.m2, pb.mul(this.m1, this.m1)), pb.vec3(0)));\n // gamma = 2 with a small absolute slack: tolerant to the noise a\n // converged history legitimately sits in (compressed-space values).\n this.$l.halfExtent = pb.add(pb.mul(this.sigma, 2), pb.vec3(0.03));\n this.$l.clampedHistory = pb.clamp(\n this.historyColor,\n pb.sub(this.m1, this.halfExtent),\n pb.add(this.m1, this.halfExtent)\n );\n // How much the clip moved the history signals stale data;\n // knock the effective count down so recovery is fast.\n this.$l.clipAmount = pb.length(pb.sub(this.clampedHistory, this.historyColor));\n this.$l.clipReset = pb.clamp(pb.mul(this.clipAmount, 8), 0, 1);\n // Disocclusion: previous frame's motion at the reprojected point\n // should agree with the current motion; a large mismatch means the\n // surface was not visible last frame.\n this.$l.prevVelocity = pb.textureSampleLevel(this.prevMotionVector, this.reprojectedUV, 0).xy;\n this.$l.velocityDiff = pb.length(\n pb.mul(pb.sub(this.velocity, this.prevVelocity), this.texSize)\n );\n this.$l.disocclusion = pb.clamp(pb.mul(pb.sub(this.velocityDiff, 2.5), 0.1), 0, 1);\n this.$l.confidence = pb.mul(pb.sub(1, this.disocclusion), pb.sub(1, this.clipReset));\n this.$l.effectiveCount = pb.max(pb.mul(this.historyCount, this.confidence), 0);\n // Count-based blend weight, capped by temporalWeight:\n // maxCount = w/(1-w) so the cap and the weight limit agree.\n this.$l.wMax = pb.clamp(this.temporalWeight, 0, 0.99);\n this.$l.maxCount = pb.div(this.wMax, pb.sub(1, this.wMax));\n this.$l.w = pb.min(this.wMax, pb.div(this.effectiveCount, pb.add(this.effectiveCount, 1)));\n this.$l.newCount = pb.min(pb.add(this.effectiveCount, 1), this.maxCount);\n this.$outputs.outColor = pb.vec4(\n pb.mix(this.currentColor, this.clampedHistory, this.w),\n this.newCount\n );\n });\n });\n });\n }\n })!;\n program.name = '@SSGI_Temporal';\n return program;\n }\n /** @internal */\n private _createCombineProgram(ctx: DrawContext) {\n const program = ctx.device.buildRenderProgram({\n vertex(pb) {\n this.flip = pb.int().uniform(0);\n this.$inputs.pos = pb.vec2().attrib('position');\n this.$outputs.uv = pb.vec2();\n pb.main(function () {\n this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\n this.$if(pb.notEqual(this.flip, 0), function () {\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\n });\n });\n },\n fragment(pb) {\n this.colorTex = pb.tex2D().uniform(0);\n this.radianceTex = pb.tex2D().uniform(0);\n this.targetSize = pb.vec2().uniform(0);\n this.ssgiIntensity = pb.float().uniform(0);\n this.srgbOut = pb.int().uniform(0);\n this.$outputs.outColor = pb.vec4();\n pb.main(function () {\n this.$l.screenUV = pb.div(pb.vec2(this.$builtins.fragCoord.xy), this.targetSize);\n this.$l.sceneColor = pb.textureSampleLevel(this.colorTex, this.screenUV, 0).rgb;\n // Invert the Reinhard compression applied by the trace pass\n // (x/(1+x) -> y/(1-y)); the clamp bounds the expansion so a fully\n // saturated texel cannot blow up to infinity.\n this.$l.compressed = pb.clamp(\n pb.textureSampleLevel(this.radianceTex, this.screenUV, 0).rgb,\n pb.vec3(0),\n pb.vec3(0.98)\n );\n this.$l.radiance = pb.div(this.compressed, pb.sub(pb.vec3(1), this.compressed));\n // The forward pipeline keeps no albedo GBuffer; approximate the\n // surface reflectance by the chromaticity of the lit scene color\n // (hue preserved, luminance normalized). Unlike scaling by the\n // scene color itself this keeps indirect light visible in shadowed\n // areas - exactly where GI matters.\n this.$l.luma = pb.dot(this.sceneColor, pb.vec3(0.2126, 0.7152, 0.0722));\n this.$l.albedoApprox = pb.clamp(\n pb.div(this.sceneColor, pb.vec3(pb.add(this.luma, 1e-3))),\n pb.vec3(0),\n pb.vec3(1)\n );\n this.$l.combined = pb.add(\n this.sceneColor,\n pb.mul(this.radiance, this.albedoApprox, this.ssgiIntensity)\n );\n this.$if(pb.equal(this.srgbOut, 0), function () {\n this.$outputs.outColor = pb.vec4(this.combined, 1);\n }).$else(function () {\n this.$outputs.outColor = pb.vec4(linearToGamma(this, this.combined), 1);\n });\n });\n }\n })!;\n program.name = '@SSGI_Combine';\n return program;\n }\n}\n"],"names":["SSGI","AbstractPostEffect","_tracePrograms","_combineProgram","_temporalProgram","_blurBlitterH","_blurBlitterV","_traceBindGroups","_combineBindGroup","_temporalBindGroup","_layer","PostEffectLayer","opaque","requireLinearDepthTexture","requireDepthAttachment","requireMotionVectorTexture","ctx","camera","ssgiTemporal","setup","s","graph","history","device","type","blackboard","get","FrameResources","SSRNormal","input","halfRes","ssgiHalfResolution","traceWidth","Math","max","width","traceHeight","height","linearDepthHandle","LinearDepth","texDesc","format","sizeMode","readCommon","builder","read","dep","dependencies","getLinearDepth","rg","getTexture","linearDepthTexture","traceHandle","addPass","out","createTexture","label","fb","createFramebuffer","colorAttachments","depthAttachment","ignoreDepthStencil","setExecute","pushDeviceStates","setFramebuffer","getFramebuffer","trace","popDeviceStates","wantTemporal","motionVectorHandle","MotionVector","historySize","prevRadianceHandle","importPreviousIfCompatible","RGHistoryResources","SSGI_RADIANCE","prevMotionVectorHandle","SSGI_MOTION_VECTOR","radianceHandle","canTemporal","temporal","accumulatedHandle","ssgiBlurKernelSize","blurInputHandle","middle","middleFB","outFB","depthTex","blitterH","BilateralBlurBlitter","blurPass","blitterV","finalRadianceHandle","output","createOutput","needDepthAttachment","framebuffer","inputTex","radianceTex","copyTexture","fetchSampler","getDefaultRenderState","combine","srgbOutput","accumulatedTex","queueRetainedCommit","motionVectorTexture","color","blitter","srcTex","fbTo","kernelRadius","stdDev","ssgiBlurStdDev","size","Vector2","depthCutoff","ssgiBlurDepthCutoff","blurSizeTex","sampler","cameraNearFar","setXY","getNearPlane","getFarPlane","srgbOut","blit","inputColorTexture","sceneDepthTexture","hash","HiZTexture","SSRCalcThickness","program","undefined","created","_createTraceProgram","bindGroup","createBindGroup","bindGroupLayouts","nearestSampler","linearSampler","getWidth","getHeight","setTexture","SSRNormalTexture","setValue","getProjectionMatrix","Matrix4x4","invert","viewMatrix","Vector4","ssgiRadius","ssgiMaxSteps","ssgiThickness","ssgiSamples","frameInfo","frameCounter","mipLevelCount","ssgiStride","needFlip","setProgram","setBindGroup","drawFullscreenQuad","currentRadianceTex","prevRadianceTex","prevMotionVectorTex","outFramebuffer","_createTemporalProgram","ssgiTemporalWeight","_createCombineProgram","ssgiIntensity","buildRenderProgram","vertex","pb","flip","int","uniform","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","add","mul","xy","$if","notEqual","y","neg","fragment","colorTex","tex2D","normalTex","projMatrix","mat4","invProjMatrix","ssgiParams","frameIndex","float","targetSize","hizTex","depthMipLevels","outColor","func","$l","linearDepth","ShaderHelper","sampleLinearDepth","nonLinearDepth","div","sub","x","clipSpacePos","clamp","wPos","mat","$return","xyz","w","screenUV","fragCoord","vec3","getPosition","lessThan","viewPos","worldNormal","textureSampleLevel","rgb","viewNormal","normalize","numRays","sum","$for","rand","SSGI_rand2","ray","rayDir","SSGI_cosineSampleHemisphere","hitInfo","screenSpaceRayTracing_HiZ","z","screenSpaceRayTracing_Linear2D","hitAlpha","hitValid","and","all","abs","greaterThan","hitUV","radiance","min","name","historyColorTex","currentColorTex","motionVector","prevMotionVector","texSize","temporalWeight","currentColor","velocitySample","velocity","greaterThanEqual","$else","reprojectedUV","offscreen","or","any","historySample","historyColor","historyCount","a","m1","m2","i","j","c","sigma","sqrt","halfExtent","clampedHistory","clipAmount","length","clipReset","prevVelocity","velocityDiff","disocclusion","confidence","effectiveCount","wMax","maxCount","newCount","mix","sceneColor","compressed","luma","dot","albedoApprox","combined","equal","linearToGamma"],"mappings":"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"}
|
package/dist/posteffect/sss.js
CHANGED
|
@@ -22,14 +22,14 @@ import { linearToGamma } from '../shaders/misc.js';
|
|
|
22
22
|
import { fetchSampler } from '../utility/misc.js';
|
|
23
23
|
import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
24
24
|
|
|
25
|
-
/**
|
|
26
|
-
* Screen-space subsurface scattering post effect.
|
|
27
|
-
*
|
|
28
|
-
* @remarks
|
|
29
|
-
* Uses a depth/normal-aware separable blur driven by per-pixel SSS profiles
|
|
30
|
-
* written by skin materials during the main shading pass.
|
|
31
|
-
*
|
|
32
|
-
* @internal
|
|
25
|
+
/**
|
|
26
|
+
* Screen-space subsurface scattering post effect.
|
|
27
|
+
*
|
|
28
|
+
* @remarks
|
|
29
|
+
* Uses a depth/normal-aware separable blur driven by per-pixel SSS profiles
|
|
30
|
+
* written by skin materials during the main shading pass.
|
|
31
|
+
*
|
|
32
|
+
* @internal
|
|
33
33
|
*/ class SSS extends AbstractPostEffect {
|
|
34
34
|
static _profileLUTWidth = 256;
|
|
35
35
|
static _profileLUTHeight = 7;
|
|
@@ -79,9 +79,32 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
79
79
|
}
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Whether the combine pass should read the screen-space shadow mask for the
|
|
84
|
+
* combine light instead of recomputing its shadow. Enabled when the camera
|
|
85
|
+
* renders the mask and the combine light was actually written into it: the
|
|
86
|
+
* mask already holds the identical shadow — same shadow impl (PCSS/VSM/…),
|
|
87
|
+
* distance fade and shadowStrength — so this skips a full redundant per-pixel
|
|
88
|
+
* shadow evaluation. Shadow mode is irrelevant: the mask is rendered with the
|
|
89
|
+
* light's own impl. Falls back to the inline path when the light is not in the
|
|
90
|
+
* mask (e.g. it overflows {@link MAX_SHADOW_MASK_LIGHTS}).
|
|
91
|
+
*
|
|
92
|
+
* Only valid at execute time, after the ShadowMaps and ShadowMask passes have
|
|
93
|
+
* populated shadowMapInfo / maskOrdinal.
|
|
94
|
+
*/ useCombineShadowMask(ctx, shadowLight) {
|
|
95
|
+
if (!shadowLight || !ctx.screenSpaceShadowMask) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const shadowMapParams = ctx.shadowMapInfo?.get(shadowLight);
|
|
99
|
+
return !!(shadowMapParams?.shadowMap && shadowMapParams.impl && shadowMapParams.maskOrdinal != null);
|
|
100
|
+
}
|
|
82
101
|
getCombineProgramKey(ctx, shadowLight) {
|
|
83
102
|
const shadowMapParams = shadowLight ? ctx.shadowMapInfo?.get(shadowLight) : null;
|
|
84
|
-
|
|
103
|
+
if (!shadowMapParams?.shaderHash) {
|
|
104
|
+
return 'default';
|
|
105
|
+
}
|
|
106
|
+
// The mask-sampling shader is independent of the PCSS impl hash.
|
|
107
|
+
return this.useCombineShadowMask(ctx, shadowLight) ? 'shadowMask' : `shadow:${shadowMapParams.shaderHash}`;
|
|
85
108
|
}
|
|
86
109
|
requireLinearDepthTexture() {
|
|
87
110
|
return true;
|
|
@@ -89,6 +112,14 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
89
112
|
requireDepthAttachment() {
|
|
90
113
|
return true;
|
|
91
114
|
}
|
|
115
|
+
requireShadowMask(ctx) {
|
|
116
|
+
// Runs at graph-build time, before shadowMapInfo is populated (that happens
|
|
117
|
+
// during the ShadowMaps pass execute), so it cannot inspect the combine
|
|
118
|
+
// light. Keep the mask alive whenever the camera renders it; combine()
|
|
119
|
+
// decides at execute time whether to sample it, and _setupFromApply only
|
|
120
|
+
// reads the handle when the mask was actually produced this frame.
|
|
121
|
+
return !!ctx.screenSpaceShadowMask;
|
|
122
|
+
}
|
|
92
123
|
apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
|
|
93
124
|
const device = ctx.device;
|
|
94
125
|
const outputFramebuffer = device.getFramebuffer();
|
|
@@ -257,33 +288,52 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
257
288
|
bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);
|
|
258
289
|
if (shadowLight) {
|
|
259
290
|
const shadowMapParams = ctx.shadowMapInfo.get(shadowLight);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
291
|
+
if (this.useCombineShadowMask(ctx, shadowLight)) {
|
|
292
|
+
// Screen-space shadow mask path: bind the mask array and select this
|
|
293
|
+
// light's layer/channel from its recorded ordinal (layer = s>>2,
|
|
294
|
+
// channel = s&3). A missing mask falls back to the fully-lit dummy.
|
|
295
|
+
const ordinal = shadowMapParams.maskOrdinal ?? 0;
|
|
296
|
+
const layer = ordinal >> 2;
|
|
297
|
+
const channel = ordinal & 3;
|
|
298
|
+
bindGroup.setValue('shadowMaskLayer', layer);
|
|
299
|
+
bindGroup.setValue('shadowMaskChannel', new Float32Array([
|
|
300
|
+
channel === 0 ? 1 : 0,
|
|
301
|
+
channel === 1 ? 1 : 0,
|
|
302
|
+
channel === 2 ? 1 : 0,
|
|
303
|
+
channel === 3 ? 1 : 0
|
|
304
|
+
]));
|
|
305
|
+
bindGroup.setTexture('Z_UniformShadowMask', ctx.shadowMaskTexture ?? ShaderHelper.getDummyShadowMask(device), fetchSampler('clamp_nearest'));
|
|
306
|
+
} else {
|
|
307
|
+
const cameraPos = ctx.camera.getWorldPosition();
|
|
308
|
+
bindGroup.setValue('camera', {
|
|
309
|
+
position: new Vector4(cameraPos.x, cameraPos.y, cameraPos.z, 0),
|
|
310
|
+
params: new Vector4(ctx.camera.getNearPlane(), ctx.camera.getFarPlane(), 1, 1),
|
|
311
|
+
shadowDebugCascades: ctx.camera.shadowDebugCascades ? 1 : 0,
|
|
312
|
+
framestamp: ctx.device.frameInfo.frameCounter
|
|
313
|
+
});
|
|
314
|
+
bindGroup.setValue('light', {
|
|
315
|
+
sunDir: new Float32Array([
|
|
316
|
+
sunDir.x,
|
|
317
|
+
sunDir.y,
|
|
318
|
+
sunDir.z
|
|
319
|
+
]),
|
|
320
|
+
envLightStrength: ctx.env?.light.strength ?? 0,
|
|
321
|
+
envLightSpecularStrength: ctx.env?.light.specularStrength ?? 1,
|
|
322
|
+
shadowStrength: shadowLight.shadow.shadowStrength,
|
|
323
|
+
shadowCascades: shadowMapParams.numShadowCascades,
|
|
324
|
+
positionAndRange: shadowLight.positionAndRange,
|
|
325
|
+
directionAndCutoff: shadowLight.directionAndCutoff,
|
|
326
|
+
diffuseAndIntensity: shadowLight.diffuseAndIntensity,
|
|
327
|
+
extraParams: shadowLight.extraParams,
|
|
328
|
+
implParams: shadowMapParams.impl.getParams(),
|
|
329
|
+
cascadeDistances: shadowMapParams.cascadeDistances,
|
|
330
|
+
depthBiasValues: shadowMapParams.depthBiasValues[0],
|
|
331
|
+
shadowCameraParams: shadowMapParams.cameraParams,
|
|
332
|
+
depthBiasScales: shadowMapParams.depthBiasScales,
|
|
333
|
+
shadowMatrices: new Float32Array(shadowMapParams.shadowMatrices)
|
|
334
|
+
});
|
|
335
|
+
bindGroup.setTexture('Z_UniformShadowMap', shadowMapParams.shadowMap, shadowMapParams.shadowMapSampler);
|
|
336
|
+
}
|
|
287
337
|
}
|
|
288
338
|
device.setProgram(program);
|
|
289
339
|
device.setBindGroup(0, bindGroup);
|
|
@@ -490,6 +540,11 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
490
540
|
createCombineProgram(ctx, shadowLight) {
|
|
491
541
|
const shadowMapParams = shadowLight ? ctx.shadowMapInfo?.get(shadowLight) : null;
|
|
492
542
|
const shadowEnabled = !!(shadowLight && shadowMapParams?.shadowMap && shadowMapParams.impl);
|
|
543
|
+
// When the screen-space shadow mask is available for the combine light,
|
|
544
|
+
// sample it instead of recomputing PCSS (which also avoids the dpdx-in-
|
|
545
|
+
// non-uniform-control-flow constraint entirely on this path).
|
|
546
|
+
const useShadowMask = this.useCombineShadowMask(ctx, shadowLight);
|
|
547
|
+
const pcssEnabled = shadowEnabled && !useShadowMask;
|
|
493
548
|
const program = ctx.device.buildRenderProgram({
|
|
494
549
|
vertex (pb) {
|
|
495
550
|
this.flip = pb.int().uniform(0);
|
|
@@ -504,11 +559,12 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
504
559
|
});
|
|
505
560
|
},
|
|
506
561
|
fragment (pb) {
|
|
507
|
-
if (
|
|
562
|
+
if (pcssEnabled) {
|
|
508
563
|
const cameraStruct = pb.defineStruct([
|
|
509
564
|
pb.vec4('position'),
|
|
510
565
|
pb.vec4('params'),
|
|
511
|
-
pb.float('shadowDebugCascades')
|
|
566
|
+
pb.float('shadowDebugCascades'),
|
|
567
|
+
pb.int('framestamp')
|
|
512
568
|
]);
|
|
513
569
|
const lightStruct = pb.defineStruct([
|
|
514
570
|
pb.vec3('sunDir'),
|
|
@@ -522,6 +578,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
522
578
|
pb.vec4('extraParams'),
|
|
523
579
|
pb.vec4('cascadeDistances'),
|
|
524
580
|
pb.vec4('depthBiasValues'),
|
|
581
|
+
pb.vec4('implParams'),
|
|
525
582
|
pb.vec4('shadowCameraParams'),
|
|
526
583
|
pb.vec4('depthBiasScales'),
|
|
527
584
|
pb.vec4[16]('shadowMatrices')
|
|
@@ -535,6 +592,14 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
535
592
|
}
|
|
536
593
|
this.Z_UniformShadowMap = shadowTex.uniform(0);
|
|
537
594
|
}
|
|
595
|
+
if (useShadowMask) {
|
|
596
|
+
// Screen-space shadow mask: one RGBA8 array layer per 4 lights. The
|
|
597
|
+
// combine light's visibility is one channel of one layer, selected via
|
|
598
|
+
// the layer index and a one-hot channel selector bound at draw time.
|
|
599
|
+
this.Z_UniformShadowMask = pb.tex2DArray().uniform(0);
|
|
600
|
+
this.shadowMaskLayer = pb.int().uniform(0);
|
|
601
|
+
this.shadowMaskChannel = pb.vec4().uniform(0);
|
|
602
|
+
}
|
|
538
603
|
this.colorTex = pb.tex2D().uniform(0);
|
|
539
604
|
this.diffuseTex = pb.tex2D().uniform(0);
|
|
540
605
|
this.blurTex = pb.tex2D().uniform(0);
|
|
@@ -708,7 +773,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
708
773
|
this.spotFactor = pb.smoothStep(this.dirCutoff.w, pb.mix(this.dirCutoff.w, 1, 0.5), this.spotFactor);
|
|
709
774
|
this.$return(pb.mul(this.spotFactor, this.falloff, this.falloff));
|
|
710
775
|
});
|
|
711
|
-
if (
|
|
776
|
+
if (pcssEnabled) {
|
|
712
777
|
pb.func('calculateTransmissionShadow', [
|
|
713
778
|
pb.vec3('worldPos'),
|
|
714
779
|
pb.float('depth01'),
|
|
@@ -776,6 +841,28 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
776
841
|
this.$l.profilePreset = this.readProfilePreset(this.param);
|
|
777
842
|
this.$l.depth01 = this.readDepth01(this.uv);
|
|
778
843
|
this.$l.result = this.baseColor.rgb;
|
|
844
|
+
// Transmission shadow. On the PCSS path the shadow uses implicit
|
|
845
|
+
// derivatives (dpdx) inside the impl; WGSL requires those in uniform
|
|
846
|
+
// control flow, so it is computed here rather than inside the
|
|
847
|
+
// profile-active branch below (a per-pixel, non-uniform branch). On the
|
|
848
|
+
// shadow-mask path the value is a single texture fetch (no PCSS).
|
|
849
|
+
this.$l.transmissionShadowRaw = pb.float(1);
|
|
850
|
+
this.$l.transmissionShadow = pb.float(1);
|
|
851
|
+
if (pcssEnabled) {
|
|
852
|
+
this.$l.shadowNormalWS = this.decodeNormal(this.uv);
|
|
853
|
+
this.$l.shadowViewPos = this.reconstructViewPos(this.uv, this.depth01);
|
|
854
|
+
this.$l.shadowWorldPos = pb.mul(this.invViewMatrix, pb.vec4(this.shadowViewPos, 1)).xyz;
|
|
855
|
+
this.$l.shadowSunDirWS = this.calculateMainLightDirection(this.shadowWorldPos, this.mainLightType, this.mainLightPosRange, this.mainLightDirCutoff, this.sunDir);
|
|
856
|
+
this.transmissionShadowRaw = this.calculateTransmissionShadow(this.shadowWorldPos, this.depth01, pb.clamp(pb.abs(pb.dot(this.shadowNormalWS, this.shadowSunDirWS)), 0, 1));
|
|
857
|
+
this.transmissionShadow = this.transmissionShadowRaw;
|
|
858
|
+
} else if (useShadowMask) {
|
|
859
|
+
// The mask already holds the identical shadow (same PCSS + distance
|
|
860
|
+
// fade + shadowStrength) rendered by the ShadowMaskPass; read the
|
|
861
|
+
// combine light's channel. Sample by screen UV, matching how the
|
|
862
|
+
// other screen-space inputs (color/depth) are sampled above.
|
|
863
|
+
this.transmissionShadowRaw = pb.dot(pb.textureArraySampleLevel(this.Z_UniformShadowMask, this.uv, this.shadowMaskLayer, 0), this.shadowMaskChannel);
|
|
864
|
+
this.transmissionShadow = this.transmissionShadowRaw;
|
|
865
|
+
}
|
|
779
866
|
this.$if(pb.and(pb.and(pb.and(pb.greaterThan(this.profileStrength, 1e-4), pb.greaterThan(this.profileSlot, 0)), this.profileActive), pb.lessThan(this.depth01, 1)), function() {
|
|
780
867
|
this.$l.widthStrength = pb.clamp(this.param.g, 0, 0.999);
|
|
781
868
|
this.$l.profileSettingsA = this.readProfileSettingsA(this.profileSlot);
|
|
@@ -819,11 +906,9 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
819
906
|
this.$l.sunDirWS = this.calculateMainLightDirection(this.worldPos, this.mainLightType, this.mainLightPosRange, this.mainLightDirCutoff, this.sunDir);
|
|
820
907
|
this.$l.mainLightAttenuation = this.calculateMainLightAttenuation(this.worldPos, this.mainLightType, this.mainLightPosRange, this.mainLightDirCutoff);
|
|
821
908
|
this.$l.frontLit = pb.mul(pb.dot(this.normalWS, this.sunDirWS), this.mainLightAttenuation);
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
this.transmissionShadowRaw = this.calculateTransmissionShadow(this.worldPos, this.depth01, pb.clamp(pb.abs(pb.dot(this.normalWS, this.sunDirWS)), 0, 1));
|
|
826
|
-
}
|
|
909
|
+
// transmissionShadowRaw/transmissionShadow were computed in uniform
|
|
910
|
+
// control flow at the top of main (PCSS sampling uses dpdx, which
|
|
911
|
+
// WGSL forbids inside this non-uniform branch); reuse them here.
|
|
827
912
|
this.transmissionShadow = this.transmissionShadowRaw;
|
|
828
913
|
this.$l.transmissionLightAttenuation = pb.mul(this.mainLightAttenuation, this.transmissionShadow);
|
|
829
914
|
this.$l.thinnessComponents = this.estimateScreenThinnessComponents(this.uv, this.depth01, this.normalWS, this.radiusResponse);
|