#version 450 core // 13-tap downsample (Jimenez, "Next Generation Post Processing in CoD:AW"). // The first pass uses a Karis average to suppress fireflies. in vec2 vUV; layout(binding = 0) uniform sampler2D uSrc; uniform vec2 uSrcTexel; uniform int uKaris; layout(location = 0) out vec4 fragColor; float luma(vec3 c) { return dot(c, vec3(0.2126, 0.7152, 0.0722)); } vec3 karis(vec3 c) { return c / (1.0 + luma(c)); } void main() { vec2 t = uSrcTexel; vec3 a = texture(uSrc, vUV + t * vec2(-2, 2)).rgb; vec3 b = texture(uSrc, vUV + t * vec2(0, 2)).rgb; vec3 c = texture(uSrc, vUV + t * vec2(2, 2)).rgb; vec3 d = texture(uSrc, vUV + t * vec2(-2, 0)).rgb; vec3 e = texture(uSrc, vUV).rgb; vec3 f = texture(uSrc, vUV + t * vec2(2, 0)).rgb; vec3 g = texture(uSrc, vUV + t * vec2(-2, -2)).rgb; vec3 h = texture(uSrc, vUV + t * vec2(0, -2)).rgb; vec3 i = texture(uSrc, vUV + t * vec2(2, -2)).rgb; vec3 j = texture(uSrc, vUV + t * vec2(-1, 1)).rgb; vec3 k = texture(uSrc, vUV + t * vec2(1, 1)).rgb; vec3 l = texture(uSrc, vUV + t * vec2(-1, -1)).rgb; vec3 m = texture(uSrc, vUV + t * vec2(1, -1)).rgb; vec3 r; if (uKaris == 1) { vec3 g0 = karis((a + b + d + e) * 0.25), g1 = karis((b + c + e + f) * 0.25); vec3 g2 = karis((d + e + g + h) * 0.25), g3 = karis((e + f + h + i) * 0.25); vec3 g4 = karis((j + k + l + m) * 0.25); r = g4 * 0.5 + (g0 + g1 + g2 + g3) * 0.125; r /= max(1.0 - luma(r), 1e-3); // undo tonemap-weighting on the average } else { r = e * 0.125 + (a + c + g + i) * 0.03125 + (b + d + f + h) * 0.0625 + (j + k + l + m) * 0.125; } fragColor = vec4(max(r, vec3(0.0)), 1.0); }