91 lines
No EOL
3.3 KiB
GLSL
91 lines
No EOL
3.3 KiB
GLSL
#version 450
|
|
|
|
layout(constant_id = 0) const int USE_AA = 0;
|
|
|
|
const float SPAN_MAX = 8.0;
|
|
const float REDUCE_MIN = 1.0/128.0;
|
|
const float REDUCE_MUL = 1.0/32.0;
|
|
|
|
layout(location = 0) in vec2 inTextCoord;
|
|
layout(location = 0) out vec4 outFragColor;
|
|
|
|
layout(set = 0, binding = 0) uniform sampler2D inputTexture;
|
|
layout(set = 0, binding = 1) uniform sampler2D bloomImage;
|
|
|
|
layout(push_constant) uniform PassConfig {
|
|
int horizontal;
|
|
float GAMMA_CONST;
|
|
float Exposure;
|
|
float blur_radius;
|
|
vec2 bloomSize;
|
|
} config;
|
|
|
|
// Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa
|
|
vec4 fxaa(sampler2D tex, vec2 uv) {
|
|
vec2 u_texel = 1.0 / vec2(textureSize(inputTexture, 0));
|
|
|
|
//Sample center and 4 corners
|
|
vec3 rgbCC = texture(tex, uv).rgb;
|
|
vec3 rgb00 = texture(tex, uv+vec2(-0.5,-0.5)*u_texel).rgb;
|
|
vec3 rgb10 = texture(tex, uv+vec2(+0.5,-0.5)*u_texel).rgb;
|
|
vec3 rgb01 = texture(tex, uv+vec2(-0.5,+0.5)*u_texel).rgb;
|
|
vec3 rgb11 = texture(tex, uv+vec2(+0.5,+0.5)*u_texel).rgb;
|
|
|
|
//Luma coefficients
|
|
const vec3 luma = vec3(0.299, 0.587, 0.114);
|
|
//Get luma from the 5 samples
|
|
float lumaCC = dot(rgbCC, luma);
|
|
float luma00 = dot(rgb00, luma);
|
|
float luma10 = dot(rgb10, luma);
|
|
float luma01 = dot(rgb01, luma);
|
|
float luma11 = dot(rgb11, luma);
|
|
|
|
//Compute gradient from luma values
|
|
vec2 dir = vec2((luma01 + luma11) - (luma00 + luma10), (luma00 + luma01) - (luma10 + luma11));
|
|
//Diminish dir length based on total luma
|
|
float dirReduce = max((luma00 + luma10 + luma01 + luma11) * REDUCE_MUL, REDUCE_MIN);
|
|
//Divide dir by the distance to nearest edge plus dirReduce
|
|
float rcpDir = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
|
//Multiply by reciprocal and limit to pixel span
|
|
dir = clamp(dir * rcpDir, -SPAN_MAX, SPAN_MAX) * u_texel.xy;
|
|
|
|
//Average middle texels along dir line
|
|
vec4 A = 0.5 * (
|
|
texture(tex, uv - dir * (1.0/6.0)) +
|
|
texture(tex, uv + dir * (1.0/6.0)));
|
|
|
|
//Average with outer texels along dir line
|
|
vec4 B = A * 0.5 + 0.25 * (
|
|
texture(tex, uv - dir * (0.5)) +
|
|
texture(tex, uv + dir * (0.5)));
|
|
|
|
|
|
//Get lowest and highest luma values
|
|
float lumaMin = min(lumaCC, min(min(luma00, luma10), min(luma01, luma11)));
|
|
float lumaMax = max(lumaCC, max(max(luma00, luma10), max(luma01, luma11)));
|
|
|
|
//Get average luma
|
|
float lumaB = dot(B.rgb, luma);
|
|
//If the average is outside the luma range, using the middle average
|
|
return ((lumaB < lumaMin) || (lumaB > lumaMax)) ? A : B;
|
|
}
|
|
|
|
vec3 bloomAt(ivec2 pixel, ivec2 size) {
|
|
return texelFetch(bloomImage, clamp(pixel, ivec2(0), size - 1), 0).rgb;
|
|
}
|
|
|
|
vec3 upsampleBloom(vec2 uv) {
|
|
ivec2 size = textureSize(bloomImage, 0);
|
|
vec2 pixel = uv * vec2(size) - 0.5;
|
|
ivec2 base = ivec2(floor(pixel));
|
|
vec2 blend = fract(pixel);
|
|
return mix(mix(bloomAt(base, size), bloomAt(base + ivec2(1, 0), size), blend.x),
|
|
mix(bloomAt(base + ivec2(0, 1), size), bloomAt(base + ivec2(1, 1), size), blend.x), blend.y);
|
|
}
|
|
|
|
void main(){
|
|
vec4 sceneColor = USE_AA == 1 ? fxaa(inputTexture, inTextCoord) : texture(inputTexture, inTextCoord);
|
|
vec3 hdrColour = max(sceneColor.rgb + upsampleBloom(inTextCoord), vec3(0.0));
|
|
vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure);
|
|
outFragColor = vec4(pow(result, vec3(1.0 / config.GAMMA_CONST)), sceneColor.a);
|
|
} |