diff options
author | x2048 <codeforsmile@gmail.com> | 2022-09-29 20:34:05 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-29 20:34:05 +0200 |
commit | 9df79a4b2d68979c3e15797d518d957787ba4e21 (patch) | |
tree | 027f372a420f1aa3aa72bf72de34c5e6062b9090 /client/shaders | |
parent | 3978b9b8ed1c318c3f9a088beb331c26bca6de6b (diff) | |
download | minetest-9df79a4b2d68979c3e15797d518d957787ba4e21.tar.xz |
Bloom (#12791)
Adds configurable light exposure control and bloom effect (light bleeding) with client-side settings.
Diffstat (limited to 'client/shaders')
-rw-r--r-- | client/shaders/blur_h/opengl_fragment.glsl | 29 | ||||
-rw-r--r-- | client/shaders/blur_h/opengl_vertex.glsl | 11 | ||||
-rw-r--r-- | client/shaders/blur_v/opengl_fragment.glsl | 29 | ||||
-rw-r--r-- | client/shaders/blur_v/opengl_vertex.glsl | 11 | ||||
-rw-r--r-- | client/shaders/extract_bloom/opengl_fragment.glsl | 21 | ||||
-rw-r--r-- | client/shaders/extract_bloom/opengl_vertex.glsl | 11 | ||||
-rw-r--r-- | client/shaders/second_stage/opengl_fragment.glsl | 61 |
7 files changed, 166 insertions, 7 deletions
diff --git a/client/shaders/blur_h/opengl_fragment.glsl b/client/shaders/blur_h/opengl_fragment.glsl new file mode 100644 index 000000000..c5818f9d8 --- /dev/null +++ b/client/shaders/blur_h/opengl_fragment.glsl @@ -0,0 +1,29 @@ +#define rendered texture0 + +uniform sampler2D rendered; +uniform vec2 texelSize0; +uniform mediump float bloomRadius = 3.0; + +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif + +void main(void) +{ + // kernel distance and linear size + mediump float n = 2. * bloomRadius + 1.; + + vec2 uv = varTexCoord.st - vec2(bloomRadius * texelSize0.x, 0.); + 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; + sum += weight; + uv += vec2(texelSize0.x, 0.); + } + color /= sum; + gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image. +} diff --git a/client/shaders/blur_h/opengl_vertex.glsl b/client/shaders/blur_h/opengl_vertex.glsl new file mode 100644 index 000000000..12692c296 --- /dev/null +++ b/client/shaders/blur_h/opengl_vertex.glsl @@ -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; +} diff --git a/client/shaders/blur_v/opengl_fragment.glsl b/client/shaders/blur_v/opengl_fragment.glsl new file mode 100644 index 000000000..6820ca10d --- /dev/null +++ b/client/shaders/blur_v/opengl_fragment.glsl @@ -0,0 +1,29 @@ +#define rendered texture0 + +uniform sampler2D rendered; +uniform vec2 texelSize0; +uniform mediump float bloomRadius = 3.0; + +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif + +void main(void) +{ + // kernel distance and linear size + mediump float n = 2. * bloomRadius + 1.; + + vec2 uv = varTexCoord.st - vec2(0., bloomRadius * texelSize0.y); + 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; + sum += weight; + uv += vec2(0., texelSize0.y); + } + color /= sum; + gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image. +} diff --git a/client/shaders/blur_v/opengl_vertex.glsl b/client/shaders/blur_v/opengl_vertex.glsl new file mode 100644 index 000000000..12692c296 --- /dev/null +++ b/client/shaders/blur_v/opengl_vertex.glsl @@ -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; +} diff --git a/client/shaders/extract_bloom/opengl_fragment.glsl b/client/shaders/extract_bloom/opengl_fragment.glsl new file mode 100644 index 000000000..8c25328ac --- /dev/null +++ b/client/shaders/extract_bloom/opengl_fragment.glsl @@ -0,0 +1,21 @@ +#define rendered texture0 + +uniform sampler2D rendered; +uniform mediump float exposureFactor = 2.5; +uniform float bloomLuminanceThreshold = 1.0; + +#ifdef GL_ES +varying mediump vec2 varTexCoord; +#else +centroid varying vec2 varTexCoord; +#endif + + +void main(void) +{ + vec2 uv = varTexCoord.st; + vec4 color = texture2D(rendered, uv).rgba; + // 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. +} diff --git a/client/shaders/extract_bloom/opengl_vertex.glsl b/client/shaders/extract_bloom/opengl_vertex.glsl new file mode 100644 index 000000000..12692c296 --- /dev/null +++ b/client/shaders/extract_bloom/opengl_vertex.glsl @@ -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; +} diff --git a/client/shaders/second_stage/opengl_fragment.glsl b/client/shaders/second_stage/opengl_fragment.glsl index 965450fcb..b929b33b4 100644 --- a/client/shaders/second_stage/opengl_fragment.glsl +++ b/client/shaders/second_stage/opengl_fragment.glsl @@ -1,6 +1,10 @@ -uniform sampler2D baseTexture; +#define rendered texture0 +#define bloom texture1 -#define rendered baseTexture +uniform sampler2D rendered; +uniform sampler2D bloom; +uniform mediump float exposureFactor = 2.5; +uniform lowp float bloomIntensity = 1.0; #ifdef GL_ES varying mediump vec2 varTexCoord; @@ -8,6 +12,24 @@ varying mediump vec2 varTexCoord; centroid varying vec2 varTexCoord; #endif +#if ENABLE_BLOOM + +vec4 applyBloom(vec4 color, vec2 uv) +{ + float bias = bloomIntensity; + vec4 bloom = texture2D(bloom, uv); +#if ENABLE_BLOOM_DEBUG + if (uv.x > 0.5 && uv.y < 0.5) + return vec4(bloom.rgb, color.a); + if (uv.x < 0.5) + return color; +#endif + color.rgb = mix(color.rgb, bloom.rgb, bias); + return color; +} + +#endif + #if ENABLE_TONE_MAPPING /* Hable's UC2 Tone mapping parameters @@ -28,15 +50,13 @@ vec3 uncharted2Tonemap(vec3 x) vec4 applyToneMapping(vec4 color) { - color = vec4(pow(color.rgb, vec3(2.2)), color.a); - const float gamma = 1.6; - const float exposureBias = 5.5; + const float exposureBias = 2.0; color.rgb = uncharted2Tonemap(exposureBias * color.rgb); // Precalculated white_scale from //vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W)); vec3 whiteScale = vec3(1.036015346); color.rgb *= whiteScale; - return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a); + return color; } #endif @@ -45,9 +65,36 @@ void main(void) vec2 uv = varTexCoord.st; vec4 color = texture2D(rendered, uv).rgba; + // translate to linear colorspace (approximate) + color.rgb = pow(color.rgb, vec3(2.2)); + +#if ENABLE_BLOOM_DEBUG + if (uv.x > 0.5 || uv.y > 0.5) +#endif + { + color.rgb *= exposureFactor; + } + + +#if ENABLE_BLOOM + color = applyBloom(color, uv); +#endif + +#if ENABLE_BLOOM_DEBUG + if (uv.x > 0.5 || uv.y > 0.5) +#endif + { #if ENABLE_TONE_MAPPING - color = applyToneMapping(color); + color = applyToneMapping(color); +#else + color.rgb /= 2.5; // default exposure factor, see also RenderingEngine::DEFAULT_EXPOSURE_FACTOR; #endif + } + + color.rgb = clamp(color.rgb, vec3(0.), vec3(1.)); + + // return to sRGB colorspace (approximate) + color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); gl_FragColor = vec4(color.rgb, 1.0); // force full alpha to avoid holes in the image. } |