#version 450 layout(push_constant) uniform Push { vec4 SourceSize; vec4 OriginalSize; vec4 OutputSize; uint FrameCount; } params; layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; } global; #include "smaa-common.h" #pragma stage vertex layout(location = 0) in vec4 Position; layout(location = 1) in vec2 TexCoord; layout(location = 0) out vec2 texcoord; layout(location = 1) out vec4 offset; void main() { gl_Position = global.MVP * Position; texcoord = TexCoord; offset = fma(SMAA_RT_METRICS.xyxy, vec4( 1.0, 0.0, 0.0, 1.0), texcoord.xyxy); } #pragma stage fragment layout(location = 0) in vec2 texcoord; layout(location = 1) in vec4 offset; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; layout(set = 0, binding = 3) uniform sampler2D Original; //----------------------------------------------------------------------------- // Neighborhood Blending Pixel Shader (Third Pass) vec4 SMAANeighborhoodBlendingPS(vec2 texcoord, vec4 offset, sampler2D colorTex, sampler2D blendTex #if SMAA_REPROJECTION , SMAATexture2D(velocityTex) #endif ) { // Fetch the blending weights for current pixel: vec4 a; a.x = texture(blendTex, offset.xy).a; // Right a.y = texture(blendTex, offset.zw).g; // Top a.wz = texture(blendTex, texcoord).xz; // Bottom / Left // Is there any blending weight with a value greater than 0.0? // SMAA_BRANCH if (dot(a, vec4(1.0, 1.0, 1.0, 1.0)) < 1e-5) { vec4 color = textureLod(colorTex, texcoord, 0.0); #if SMAA_REPROJECTION vec2 velocity = SMAA_DECODE_VELOCITY(textureLod(velocityTex, texcoord, 0.0)); // Pack velocity into the alpha channel: color.a = sqrt(5.0 * length(velocity)); #endif return color; } else { bool h = max(a.x, a.z) > max(a.y, a.w); // max(horizontal) > max(vertical) // Calculate the blending offsets: vec4 blendingOffset = vec4(0.0, a.y, 0.0, a.w); vec2 blendingWeight = a.yw; SMAAMovc(bvec4(h, h, h, h), blendingOffset, vec4(a.x, 0.0, a.z, 0.0)); SMAAMovc(bvec2(h, h), blendingWeight, a.xz); blendingWeight /= dot(blendingWeight, vec2(1.0, 1.0)); // Calculate the texture coordinates: vec4 blendingCoord = fma(blendingOffset, vec4(SMAA_RT_METRICS.xy, -SMAA_RT_METRICS.xy), texcoord.xyxy); // We exploit bilinear filtering to mix current pixel with the chosen // neighbor: vec4 color = blendingWeight.x * textureLod(colorTex, blendingCoord.xy, 0.0); color += blendingWeight.y * textureLod(colorTex, blendingCoord.zw, 0.0); #if SMAA_REPROJECTION // Antialias velocity for proper reprojection in a later stage: vec2 velocity = blendingWeight.x * SMAA_DECODE_VELOCITY(textureLod(velocityTex, blendingCoord.xy, 0.0)); velocity += blendingWeight.y * SMAA_DECODE_VELOCITY(textureLod(velocityTex, blendingCoord.zw, 0.0)); // Pack velocity into the alpha channel: color.a = sqrt(5.0 * length(velocity)); #endif return color; } } void main() { FragColor = SMAANeighborhoodBlendingPS(texcoord, offset, Original, Source); }