UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

3 lines (2 loc) 3.73 kB
declare const _default: "\n #include \"sampleCatmullRomPS\"\n #include \"screenDepthPS\"\n\n var sourceTexture: texture_2d<f32>;\n var sourceTextureSampler: sampler;\n var historyTexture: texture_2d<f32>;\n var historyTextureSampler: sampler;\n uniform matrix_viewProjectionPrevious: mat4x4f;\n uniform matrix_viewProjectionInverse: mat4x4f;\n uniform jitters: vec4f; // xy: current frame, zw: previous frame\n uniform textureSize: vec2f;\n\n varying uv0: vec2f;\n\n fn reproject(uv: vec2f, depth: f32) -> vec2f {\n\n var ndc = vec4f(uv * 2.0 - 1.0, depth, 1.0);\n\n // remove jitter from the current frame\n ndc = vec4f(ndc.xy - uniform.jitters.xy, ndc.zw);\n\n // Transform NDC to world space of the current frame\n var worldPosition = uniform.matrix_viewProjectionInverse * ndc;\n worldPosition = worldPosition / worldPosition.w;\n\n // world position to screen space of the previous frame\n let screenPrevious = uniform.matrix_viewProjectionPrevious * worldPosition;\n\n return (screenPrevious.xy / screenPrevious.w) * 0.5 + 0.5;\n }\n\n fn colorClamp(uv: vec2f, historyColor: vec4f) -> vec4f {\n\n // out of range numbers\n var minColor = vec3f(9999.0);\n var maxColor = vec3f(-9999.0);\n\n // sample a 3x3 neighborhood\n for (var ix: i32 = -1; ix <= 1; ix = ix + 1) {\n for (var iy: i32 = -1; iy <= 1; iy = iy + 1) {\n let color_sample = textureSample(sourceTexture, sourceTextureSampler, uv + vec2f(f32(ix), f32(iy)) / uniform.textureSize).rgb;\n minColor = min(minColor, color_sample);\n maxColor = max(maxColor, color_sample);\n }\n }\n\n // clamp the history color to min/max bounding box\n let clamped = clamp(historyColor.rgb, minColor, maxColor);\n return vec4f(clamped, historyColor.a);\n }\n\n @fragment\n fn fragmentMain(input: FragmentInput) -> FragmentOutput {\n var output: FragmentOutput;\n\n var uv = input.uv0;\n\n // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n // This hack is needed on webgpu, which makes TAA work but the resulting image is upside-down.\n // We could flip the image in the following pass, but ideally a better solution should be found.\n uv.y = 1.0 - uv.y;\n // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n // current frame\n let srcColor = textureSample(sourceTexture, sourceTextureSampler, uv);\n\n // current depth is in linear space, convert it to non-linear space\n let linearDepth = getLinearScreenDepth(uv0);\n let depth = delinearizeDepth(linearDepth);\n\n // previous frame\n let historyUv = reproject(uv0, depth);\n\n #ifdef QUALITY_HIGH\n\n // high quality history, sharper result\n var historyColor: vec4f = SampleTextureCatmullRom(historyTexture, historyTextureSampler, historyUv, uniform.textureSize);\n\n #else\n\n // single sample history, more blurry result\n var historyColor: vec4f = textureSample(historyTexture, historyTextureSampler, historyUv);\n\n #endif\n\n // handle disocclusion by clamping the history color\n let historyColorClamped = colorClamp(uv, historyColor);\n\n // handle history buffer outside of the frame\n let mixFactor_condition = historyUv.x < 0.0 || historyUv.x > 1.0 || historyUv.y < 0.0 || historyUv.y > 1.0;\n let mixFactor = select(0.05, 1.0, mixFactor_condition);\n\n output.color = mix(historyColorClamped, srcColor, mixFactor);\n return output;\n }\n"; export default _default;