100 lines
2.7 KiB
GLSL
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 |