53 lines
1.6 KiB
GLSL
53 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;
|
||
|
}
|