// 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