Files
minecraft-pt/shaders/Lib/Programs/Composite/Bloom_CS.glsl
T

100 lines
2.7 KiB
GLSL

// MinecraftPT — Bloom_CS
// Bloom compute passes: two downsample levels + axial blur X/Y.
// Uses two alternating images (bloomA/bloomB) to avoid read-write conflicts.
#include "/Lib/Settings.glsl"
#include "/Lib/Utilities.glsl"
const ivec3 workGroups = ivec3(int(ceil(viewWidth * 0.03125)), int(ceil(viewHeight * 0.03125)), 1);
layout (local_size_x = 8, local_size_y = 8) in;
layout (rgba16f) uniform writeonly image2D img_bloomA;
layout (rgba16f) uniform writeonly image2D img_bloomB;
uniform sampler2D colortex12;
uniform sampler2D bloomA;
uniform sampler2D bloomB;
// Downsample pass
#ifdef PROGRAM_BLOOM_DOWNSAMPLE
void main(){
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
vec3 color = vec3(0.0);
#if PROGRAM_BLOOM_DOWNSAMPLE_LEVEL == 1
// Level 1: 2x2 box from the HDR scene -> bloomA
for (int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
color += texelFetch(colortex12, texel * 2 + ivec2(i, j), 0).rgb;
}}
color *= 0.25;
float brightness = luminance(color);
color *= saturate(brightness * BLOOM_CLAMP_STRENGTH);
ivec2 imgSize = imageSize(img_bloomA);
if (all(lessThan(texel, imgSize))){
imageStore(img_bloomA, texel, vec4(color, 1.0));
}
#else
// Level 2: 2x2 box from bloomA -> bloomB
for (int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
color += texelFetch(bloomA, texel * 2 + ivec2(i, j), 0).rgb;
}}
color *= 0.25;
float brightness = luminance(color);
color *= saturate(brightness * BLOOM_CLAMP_STRENGTH);
ivec2 imgSize = imageSize(img_bloomB);
if (all(lessThan(texel, imgSize))){
imageStore(img_bloomB, texel, vec4(color, 1.0));
}
#endif
}
#endif
// Axial blur pass (X or Y depending on defines)
#ifdef PROGRAM_BLOOM_AXIALBLUR
void main(){
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
ivec2 imgSize = imageSize(img_bloomA);
if (any(greaterThanEqual(texel, imgSize))) return;
vec2 uv = (vec2(texel) + 0.5) / vec2(imgSize);
// Which buffer to read (BLOOM_AXIAL_READ_A defined for the pass reading bloomA)
#ifdef BLOOM_AXIAL_READ_A
sampler2D src = bloomA;
#else
sampler2D src = bloomB;
#endif
#ifdef PROGRAM_BLOOM_AXIALBLUR_X
vec2 axis = vec2(1.0, 0.0);
#else
vec2 axis = vec2(0.0, 1.0);
#endif
vec3 color = vec3(0.0);
float weightSum = 0.0;
for (int i = -8; i <= 8; i++){
vec2 coord = uv + axis * float(i) / vec2(imgSize);
float w = exp(-float(i * i) * 0.05);
color += textureLod(src, coord, 0.0).rgb * w;
weightSum += w;
}
// Write to the opposite buffer of the read source
#ifdef BLOOM_AXIAL_READ_A
imageStore(img_bloomB, texel, vec4(color / weightSum, 1.0));
#else
imageStore(img_bloomA, texel, vec4(color / weightSum, 1.0));
#endif
}
#endif