Files
Nuake/Data/Shaders/bloom.shader
2025-01-31 18:04:43 -05:00

146 lines
4.1 KiB
GLSL

#shader vertex
#version 440 core
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec2 UVPosition;
out flat vec2 UV;
void main()
{
UV = UVPosition;
gl_Position = vec4(VertexPosition, 1.0f);
}
#shader fragment
#version 440 core
uniform int u_Stage;
uniform sampler2D u_Source;
uniform vec2 u_SourceSize;
uniform float u_Exposure;
uniform float u_Gamma;
uniform sampler2D u_Source2;
uniform vec2 u_Source2Size;
uniform int u_HasLensDirt;
uniform sampler2D u_LensDirt;
uniform float u_LensDirtIntensity;
uniform float u_Threshold;
uniform float u_BlurAmount;
uniform vec2 u_BlurDirection;
in vec2 UV;
out vec4 FragColor;
vec4 Threshold(vec4 color, vec2 uv)
{
float brightness = max(color.r, max(color.g, color.b));
float contribution = max(0, brightness - u_Threshold);
contribution /= max(brightness, 0.00001);
return color * contribution;
}
vec4 DownsampleBox13Tap(vec2 uv)
{
vec2 texelSize = 1.0 / u_SourceSize;
vec4 A = texture(u_Source, uv + texelSize * vec2(-1.0, -1.0));
vec4 B = texture(u_Source, uv + texelSize * vec2(0.0, -1.0));
vec4 C = texture(u_Source, uv + texelSize * vec2(1.0, -1.0));
vec4 D = texture(u_Source, uv + texelSize * vec2(-0.5, -0.5));
vec4 E = texture(u_Source, uv + texelSize * vec2(0.5, -0.5));
vec4 F = texture(u_Source, uv + texelSize * vec2(-1.0, 0.0));
vec4 G = texture(u_Source, uv);
vec4 H = texture(u_Source, uv + texelSize * vec2(1.0, 0.0));
vec4 I = texture(u_Source, uv + texelSize * vec2(-0.5, 0.5));
vec4 J = texture(u_Source, uv + texelSize * vec2(0.5, 0.5));
vec4 K = texture(u_Source, uv + texelSize * vec2(-1.0, 1.0));
vec4 L = texture(u_Source, uv + texelSize * vec2(0.0, 1.0));
vec4 M = texture(u_Source, uv + texelSize * vec2(1.0, 1.0));
vec2 div = (1.0 / 4.0) * vec2(0.5, 0.125);
vec4 o = (D + E + I + J) * div.x;
o += (A + B + G + F) * div.y;
o += (B + C + H + G) * div.y;
o += (F + G + L + K) * div.y;
o += (G + H + M + L) * div.y;
return o;
}
vec4 Upsample(vec2 uv)
{
vec4 d = (1.0 / u_Source2Size.xyxy) * vec4(1.0, 1.0, -1.0, 0.0) ;
vec4 s;
s = texture(u_Source2, uv - d.xy);
s += texture(u_Source2, uv - d.wy) * 2.0;
s += texture(u_Source2, uv - d.zy);
s += texture(u_Source2, uv + d.zw) * 2.0;
s += texture(u_Source2, uv) * 4.0;
s += texture(u_Source2, uv + d.xw) * 2.0;
s += texture(u_Source2, uv + d.zy);
s += texture(u_Source2, uv + d.wy) * 2.0;
s += texture(u_Source2, uv + d.xy);
return s * (1.0 / 16.0);
}
vec4 blur9(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
vec4 color = vec4(0.0);
vec2 off1 = vec2(1.3846153846) * direction;
vec2 off2 = vec2(3.2307692308) * direction;
color += texture(image, uv) * 0.2270270270;
color += texture(image, uv + (off1 / resolution)) * 0.3162162162;
color += texture(image, uv - (off1 / resolution)) * 0.3162162162;
color += texture(image, uv + (off2 / resolution)) * 0.0702702703;
color += texture(image, uv - (off2 / resolution)) * 0.0702702703;
return color;
}
void main()
{
vec4 outputColor = texture(u_Source, UV).rgba;
if (u_Stage == 0) // Threshold
{
outputColor = Threshold(outputColor, UV);
}
else if (u_Stage == 1) // Downsampling
{
outputColor = DownsampleBox13Tap(UV);
}
else if (u_Stage == 2) // Blur
{
outputColor = blur9(u_Source, UV, u_SourceSize, u_BlurDirection);
}
else if (u_Stage == 3) // Copy
{
outputColor = texture(u_Source, UV);
}
else if (u_Stage == 4) // Upsampling + combine
{
outputColor += Upsample(UV) / 2.0;
}
else if (u_Stage == 5) // Final combine
{
vec4 lensDirt = vec4(0.0f);
if(u_HasLensDirt == 1)
{
lensDirt = max(texture(u_LensDirt, UV) * u_LensDirtIntensity, 1.0 - u_LensDirtIntensity);
}
outputColor *= lensDirt;
outputColor += texture(u_Source2, UV);
vec3 color = outputColor.rgb;
outputColor = vec4(color, 1.0);//vec4(acesOperator(outputColor.rgb), 1.0f);
}
FragColor = outputColor;
}