1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Improve bloom effect (#12916)

* Remove the built-in exposure factor of 2.5
* Add physics-based bloom (https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom)
* Add luminance scaling for bloom layer to simulate HDR
* Add setting to control bloom strength
This commit is contained in:
x2048 2022-11-02 09:09:48 +01:00 committed by GitHub
parent fb3085a2c5
commit 9b24041394
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 195 additions and 59 deletions

View file

@ -0,0 +1,37 @@
// based on Phys.Bloom OpenGL tutorial https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom
// and ACM Siggraph talk in 2014 by Jorge Jimenez for Call of Duty: Advanced Warfare.
#define rendered texture0
uniform sampler2D rendered;
uniform vec2 texelSize0;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main(void)
{
vec2 tx = 2.0 * texelSize0;
vec3 a = texture2D(rendered, varTexCoord.st + vec2(-1., -1.) * tx).rgb;
vec3 b = texture2D(rendered, varTexCoord.st + vec2(0., -1.) * tx).rgb;
vec3 c = texture2D(rendered, varTexCoord.st + vec2(1., -1.) * tx).rgb;
vec3 d = texture2D(rendered, varTexCoord.st + vec2(-1., 0.) * tx).rgb;
vec3 e = texture2D(rendered, varTexCoord.st + vec2(0., 0.) * tx).rgb;
vec3 f = texture2D(rendered, varTexCoord.st + vec2(1., 0.) * tx).rgb;
vec3 g = texture2D(rendered, varTexCoord.st + vec2(-1., 1.) * tx).rgb;
vec3 h = texture2D(rendered, varTexCoord.st + vec2(0., 1.) * tx).rgb;
vec3 i = texture2D(rendered, varTexCoord.st + vec2(1., 1.) * tx).rgb;
vec3 j = texture2D(rendered, varTexCoord.st + vec2(-0.5, -0.5) * tx).rgb;
vec3 k = texture2D(rendered, varTexCoord.st + vec2(0.5, -0.5) * tx).rgb;
vec3 l = texture2D(rendered, varTexCoord.st + vec2(-0.5, 0.5) * tx).rgb;
vec3 m = texture2D(rendered, varTexCoord.st + vec2(-0.5, 0.5) * tx).rgb;
vec3 color =
(a + c + g + i) * 0.03125 +
(b + d + f + h) * 0.0625 +
(e + j + k + l + m) * 0.125;
gl_FragColor = max(vec4(color, 1.0), 1e-4);
}

View file

@ -0,0 +1,11 @@
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main(void)
{
varTexCoord.st = inTexCoord0.st;
gl_Position = inVertexPosition;
}

View file

@ -0,0 +1,35 @@
#define current texture0
#define previous texture1
uniform sampler2D current;
uniform sampler2D previous;
uniform vec2 texelSize0;
uniform mediump float bloomRadius;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main(void)
{
vec2 offset = bloomRadius * texelSize0;
vec3 a = texture2D(previous, varTexCoord.st + vec2(-1., -1.) * offset).rgb;
vec3 b = texture2D(previous, varTexCoord.st + vec2(0., -1.) * offset).rgb;
vec3 c = texture2D(previous, varTexCoord.st + vec2(1., -1.) * offset).rgb;
vec3 d = texture2D(previous, varTexCoord.st + vec2(-1., 0.) * offset).rgb;
vec3 e = texture2D(previous, varTexCoord.st + vec2(0., 0.) * offset).rgb;
vec3 f = texture2D(previous, varTexCoord.st + vec2(1., 0.) * offset).rgb;
vec3 g = texture2D(previous, varTexCoord.st + vec2(-1., 1.) * offset).rgb;
vec3 h = texture2D(previous, varTexCoord.st + vec2(0., 1.) * offset).rgb;
vec3 i = texture2D(previous, varTexCoord.st + vec2(1., 1.) * offset).rgb;
vec3 base = texture2D(current, varTexCoord.st).rgb;
gl_FragColor = max(vec4(base +
(a + c + g + i) * 0.0625 +
(b + d + f + h) * 0.125 +
e * 0.25, 1.), 1e-4);
}

View file

@ -0,0 +1,11 @@
#ifdef GL_ES
varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
void main(void)
{
varTexCoord.st = inTexCoord0.st;
gl_Position = inVertexPosition;
}

View file

@ -3,6 +3,7 @@
uniform sampler2D rendered;
uniform vec2 texelSize0;
uniform mediump float bloomRadius;
uniform mat3 bloomBlurWeights;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
@ -10,6 +11,13 @@ varying mediump vec2 varTexCoord;
centroid varying vec2 varTexCoord;
#endif
// smoothstep - squared
float smstsq(float f)
{
f = f * f * (3 - 2 * f);
return f;
}
void main(void)
{
// kernel distance and linear size
@ -19,8 +27,8 @@ void main(void)
vec4 color = vec4(0.);
mediump float sum = 0.;
for (mediump float i = 0.; i < n; i++) {
mediump float weight = pow(1. - (abs(i / bloomRadius - 1.)), 1.3);
color += texture2D(rendered, uv).rgba * weight;
mediump float weight = smstsq(1. - (abs(i / bloomRadius - 1.)));
color.rgb += texture2D(rendered, uv).rgb * weight;
sum += weight;
uv += vec2(texelSize0.x, 0.);
}

View file

@ -3,6 +3,7 @@
uniform sampler2D rendered;
uniform vec2 texelSize0;
uniform mediump float bloomRadius;
uniform mat3 bloomBlurWeights;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
@ -10,6 +11,13 @@ varying mediump vec2 varTexCoord;
centroid varying vec2 varTexCoord;
#endif
// smoothstep - squared
float smstsq(float f)
{
f = f * f * (3 - 2 * f);
return f;
}
void main(void)
{
// kernel distance and linear size
@ -19,8 +27,8 @@ void main(void)
vec4 color = vec4(0.);
mediump float sum = 0.;
for (mediump float i = 0.; i < n; i++) {
mediump float weight = pow(1. - (abs(i / bloomRadius - 1.)), 1.3);
color += texture2D(rendered, uv).rgba * weight;
mediump float weight = smstsq(1. - (abs(i / bloomRadius - 1.)));
color.rgb += texture2D(rendered, uv).rgb * weight;
sum += weight;
uv += vec2(0., texelSize0.y);
}

View file

@ -2,7 +2,7 @@
uniform sampler2D rendered;
uniform mediump float exposureFactor;
uniform float bloomLuminanceThreshold;
uniform mediump float bloomStrength;
#ifdef GL_ES
varying mediump vec2 varTexCoord;
@ -14,8 +14,14 @@ centroid varying vec2 varTexCoord;
void main(void)
{
vec2 uv = varTexCoord.st;
vec4 color = texture2D(rendered, uv).rgba;
vec3 color = texture2D(rendered, uv).rgb;
// translate to linear colorspace (approximate)
color.rgb = pow(color.rgb, vec3(2.2)) * exposureFactor;
gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image.
color = pow(color, vec3(2.2));
// Scale colors by luminance to amplify bright colors
// in SDR textures.
float luminance = dot(color, vec3(0.213, 0.515, 0.072));
luminance *= luminance;
color *= luminance * exposureFactor * bloomStrength;
gl_FragColor = vec4(color, 1.0); // force full alpha to avoid holes in the image.
}

View file

@ -16,15 +16,14 @@ centroid varying vec2 varTexCoord;
vec4 applyBloom(vec4 color, vec2 uv)
{
float bias = bloomIntensity;
vec4 bloom = texture2D(bloom, uv);
vec3 light = texture2D(bloom, uv).rgb;
#ifdef ENABLE_BLOOM_DEBUG
if (uv.x > 0.5 && uv.y < 0.5)
return vec4(bloom.rgb, color.a);
return vec4(light, color.a);
if (uv.x < 0.5)
return color;
return light;
#endif
color.rgb = mix(color.rgb, bloom.rgb, bias);
color.rgb = mix(color.rgb, light, bloomIntensity);
return color;
}
@ -86,8 +85,6 @@ void main(void)
{
#if ENABLE_TONE_MAPPING
color = applyToneMapping(color);
#else
color.rgb /= 2.5; // default exposure factor, see also RenderingEngine::DEFAULT_EXPOSURE_FACTOR;
#endif
}