engine/bin/data/shaders/display/bloom/up.comp.glsl

60 lines
1.7 KiB
GLSL

#version 450
#pragma shader_stage(compute)
#define COMPUTE 1
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout (constant_id = 0) const uint MIPS = 6;
layout (binding = 0, rgba16f) uniform image2D imageColor;
layout (binding = 1) uniform sampler2D samplerBloom;
layout (binding = 2) uniform UBO {
float threshold;
float smoothness;
uint size;
float padding1;
float weights[32];
} ubo;
// 9-tap bilinear tent filter
vec3 tentFilter(sampler2D tex, vec2 uv, float lod) {
vec2 texSize = vec2(textureSize(tex, int(lod)));
vec4 d = (1.0 / texSize.xyxy) * vec4(1.0, 1.0, -1.0, 0.0);
vec3 s = textureLod(tex, uv - d.xy, lod).rgb;
s += textureLod(tex, uv - d.wy, lod).rgb * 2.0;
s += textureLod(tex, uv - d.zy, lod).rgb;
s += textureLod(tex, uv + d.zw, lod).rgb * 2.0;
s += textureLod(tex, uv, lod).rgb * 4.0;
s += textureLod(tex, uv + d.xw, lod).rgb * 2.0;
s += textureLod(tex, uv + d.zy, lod).rgb;
s += textureLod(tex, uv + d.wy, lod).rgb * 2.0;
s += textureLod(tex, uv + d.xy, lod).rgb;
return s * (1.0 / 16.0);
}
void main() {
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
ivec2 size = imageSize(imageColor);
if ( texel.x >= size.x || texel.y >= size.y ) return;
vec2 uv = (vec2(texel) + 0.5) / vec2(size);
vec3 bloomAcc = vec3(0.0);
float weightSum = 0.0;
for ( uint i = 0; i < min(MIPS, ubo.size); ++i ) {
float w = ubo.weights[i];
bloomAcc += textureLod(samplerBloom, uv, float(i)).rgb * w;
//bloomAcc += tentFilter(samplerBloom, uv, float(i)) * w;
weightSum += w;
}
if ( weightSum > 0.0 ) bloomAcc /= weightSum;
vec3 base = imageLoad( imageColor, texel ).rgb;
imageStore( imageColor, texel, vec4(base + bloomAcc, 1.0) );
}