f53a170539
We also now pre-expose our lighting before writing to the HDR buffers. This solves some precision issues and prevents the Sun from producing infinite values.
52 lines
1.6 KiB
GLSL
52 lines
1.6 KiB
GLSL
/*
|
|
* Bloom - upsampling step
|
|
* "Next Generation Post Processing in Call of Duty Advanced Warfare"
|
|
* ACM Siggraph (2014)
|
|
* Based on the implementation by Alexander Christensen
|
|
* https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom
|
|
*/
|
|
|
|
#version 330 core
|
|
|
|
layout(location = 0) out vec3 fragColor;
|
|
|
|
in vec2 texcoord;
|
|
|
|
uniform sampler2D tex;
|
|
uniform float filter_radius;
|
|
|
|
void main()
|
|
{
|
|
// The filter kernel is applied with a radius, specified in texture
|
|
// coordinates, so that the radius will vary across mip resolutions.
|
|
float x = filter_radius;
|
|
float y = filter_radius;
|
|
|
|
// Take 9 samples around current texel:
|
|
// a - b - c
|
|
// d - e - f
|
|
// g - h - i
|
|
// === ('e' is the current texel) ===
|
|
vec3 a = texture(tex, vec2(texcoord.x - x, texcoord.y + y)).rgb;
|
|
vec3 b = texture(tex, vec2(texcoord.x, texcoord.y + y)).rgb;
|
|
vec3 c = texture(tex, vec2(texcoord.x + x, texcoord.y + y)).rgb;
|
|
|
|
vec3 d = texture(tex, vec2(texcoord.x - x, texcoord.y)).rgb;
|
|
vec3 e = texture(tex, vec2(texcoord.x, texcoord.y)).rgb;
|
|
vec3 f = texture(tex, vec2(texcoord.x + x, texcoord.y)).rgb;
|
|
|
|
vec3 g = texture(tex, vec2(texcoord.x - x, texcoord.y - y)).rgb;
|
|
vec3 h = texture(tex, vec2(texcoord.x, texcoord.y - y)).rgb;
|
|
vec3 i = texture(tex, vec2(texcoord.x + x, texcoord.y - y)).rgb;
|
|
|
|
// Apply weighted distribution, by using a 3x3 tent filter:
|
|
// 1 | 1 2 1 |
|
|
// -- * | 2 4 2 |
|
|
// 16 | 1 2 1 |
|
|
vec3 upsample = e * 4.0;
|
|
upsample += (b+d+f+h) * 2.0;
|
|
upsample += (a+c+g+i);
|
|
upsample /= 16.0;
|
|
|
|
fragColor = upsample;
|
|
}
|