From e5db851f30b23ce279bad038f9c36715ff9d1a23 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 7 May 2019 11:27:52 +0100 Subject: [PATCH] Added FXAA to post-processing shader Former-commit-id: 9cfdb3762b63688d1b59d65066c90355c7209c62 --- voxygen/shaders/figure.frag | 1 + voxygen/shaders/figure.vert | 1 + voxygen/shaders/postprocess.frag | 139 +++++++++++++++++++++++++++- voxygen/shaders/postprocess.vert | 1 + voxygen/shaders/skybox.frag | 1 + voxygen/shaders/skybox.vert | 1 + voxygen/shaders/terrain.frag | 1 + voxygen/shaders/terrain.vert | 1 + voxygen/src/render/pipelines/mod.rs | 4 + voxygen/src/scene/mod.rs | 1 + 10 files changed, 148 insertions(+), 3 deletions(-) diff --git a/voxygen/shaders/figure.frag b/voxygen/shaders/figure.frag index bf6889d61c..6bc12dafb3 100644 --- a/voxygen/shaders/figure.frag +++ b/voxygen/shaders/figure.frag @@ -19,6 +19,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; struct BoneData { diff --git a/voxygen/shaders/figure.vert b/voxygen/shaders/figure.vert index 7880d7876c..2c7c87d508 100644 --- a/voxygen/shaders/figure.vert +++ b/voxygen/shaders/figure.vert @@ -19,6 +19,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; struct BoneData { diff --git a/voxygen/shaders/postprocess.frag b/voxygen/shaders/postprocess.frag index 392e2c6956..2b5dab93f8 100644 --- a/voxygen/shaders/postprocess.frag +++ b/voxygen/shaders/postprocess.frag @@ -18,12 +18,145 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; out vec4 tgt_color; -void main() { - vec4 src_color = texture2D(src_color, (f_pos + 1.0) / 2.0); +/** +Basic FXAA implementation based on the code on geeks3d.com with the +modification that the texture2DLod stuff was removed since it's +unsupported by WebGL. - tgt_color = 1.0 - 1.0 / (src_color + 1.0); +-- + +From: +https://github.com/mitsuhiko/webgl-meincraft + +Copyright (c) 2011 by Armin Ronacher. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FXAA_REDUCE_MIN + #define FXAA_REDUCE_MIN (1.0/ 128.0) +#endif +#ifndef FXAA_REDUCE_MUL + #define FXAA_REDUCE_MUL (1.0 / 8.0) +#endif +#ifndef FXAA_SPAN_MAX + #define FXAA_SPAN_MAX 8.0 +#endif + +//optimized version for mobile, where dependent +//texture reads can be a bottleneck +vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, + vec2 v_rgbNW, vec2 v_rgbNE, + vec2 v_rgbSW, vec2 v_rgbSE, + vec2 v_rgbM) { + vec4 color; + mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); + vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; + vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; + vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; + vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; + vec4 texColor = texture2D(tex, v_rgbM); + vec3 rgbM = texColor.xyz; + vec3 luma = vec3(0.299, 0.587, 0.114); + float lumaNW = dot(rgbNW, luma); + float lumaNE = dot(rgbNE, luma); + float lumaSW = dot(rgbSW, luma); + float lumaSE = dot(rgbSE, luma); + float lumaM = dot(rgbM, luma); + float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); + float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); + + mediump vec2 dir; + dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); + dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); + + float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * + (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); + + float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); + dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), + max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), + dir * rcpDirMin)) * inverseVP; + + vec3 rgbA = 0.5 * ( + texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); + vec3 rgbB = rgbA * 0.5 + 0.25 * ( + texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); + + float lumaB = dot(rgbB, luma); + if ((lumaB < lumaMin) || (lumaB > lumaMax)) + color = vec4(rgbA, texColor.a); + else + color = vec4(rgbB, texColor.a); + return color; +} + + +void texcoords(vec2 fragCoord, vec2 resolution, + out vec2 v_rgbNW, out vec2 v_rgbNE, + out vec2 v_rgbSW, out vec2 v_rgbSE, + out vec2 v_rgbM) { + vec2 inverseVP = 1.0 / resolution.xy; + v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; + v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; + v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; + v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; + v_rgbM = vec2(fragCoord * inverseVP); +} + + +vec4 fxaa_apply(sampler2D tex, vec2 fragCoord, vec2 resolution) { + mediump vec2 v_rgbNW; + mediump vec2 v_rgbNE; + mediump vec2 v_rgbSW; + mediump vec2 v_rgbSE; + mediump vec2 v_rgbM; + + //compute the texture coords + texcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); + + //compute FXAA + return fxaa(tex, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); +} + +void main() { + vec2 uv = (f_pos + 1.0) * 0.5; + vec4 color = fxaa_apply(src_color, uv * screen_res.xy, screen_res.xy); + + tgt_color = 1.0 - 1.0 / (color + 1.0); } diff --git a/voxygen/shaders/postprocess.vert b/voxygen/shaders/postprocess.vert index 91cde43fb7..7d3c4774f0 100644 --- a/voxygen/shaders/postprocess.vert +++ b/voxygen/shaders/postprocess.vert @@ -16,6 +16,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; out vec2 f_pos; diff --git a/voxygen/shaders/skybox.frag b/voxygen/shaders/skybox.frag index 07368c5bb2..b4ed5511a1 100644 --- a/voxygen/shaders/skybox.frag +++ b/voxygen/shaders/skybox.frag @@ -16,6 +16,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; out vec4 tgt_color; diff --git a/voxygen/shaders/skybox.vert b/voxygen/shaders/skybox.vert index 165e747ae9..825bbe7e88 100644 --- a/voxygen/shaders/skybox.vert +++ b/voxygen/shaders/skybox.vert @@ -16,6 +16,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; out vec3 f_pos; diff --git a/voxygen/shaders/terrain.frag b/voxygen/shaders/terrain.frag index 1b718c3633..45ed1a4ce9 100644 --- a/voxygen/shaders/terrain.frag +++ b/voxygen/shaders/terrain.frag @@ -18,6 +18,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; out vec4 tgt_color; diff --git a/voxygen/shaders/terrain.vert b/voxygen/shaders/terrain.vert index e195a1c464..89a386587c 100644 --- a/voxygen/shaders/terrain.vert +++ b/voxygen/shaders/terrain.vert @@ -18,6 +18,7 @@ uniform u_globals { vec4 view_distance; vec4 time_of_day; vec4 tick; + vec4 screen_res; }; out vec3 f_pos; diff --git a/voxygen/src/render/pipelines/mod.rs b/voxygen/src/render/pipelines/mod.rs index c425c2d5eb..f58b520ee4 100644 --- a/voxygen/src/render/pipelines/mod.rs +++ b/voxygen/src/render/pipelines/mod.rs @@ -27,6 +27,7 @@ gfx_defines! { view_distance: [f32; 4] = "view_distance", time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64 tick: [f32; 4] = "tick", + screen_res: [f32; 4] = "screen_res", } } @@ -41,6 +42,7 @@ impl Globals { view_distance: [0.0; 4], time_of_day: [0.0; 4], tick: [0.0; 4], + screen_res: [800.0, 500.0, 0.0, 0.0], } } @@ -53,6 +55,7 @@ impl Globals { view_distance: f32, time_of_day: f64, tick: f64, + screen_res: Vec2, ) -> Self { Self { view_mat: arr_to_mat(view_mat.into_col_array()), @@ -62,6 +65,7 @@ impl Globals { view_distance: [view_distance; 4], time_of_day: [time_of_day as f32; 4], tick: [tick as f32; 4], + screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(), } } } diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 8ede8e49ad..e445495cf3 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -135,6 +135,7 @@ impl Scene { 10.0, client.state().get_time_of_day(), client.state().get_time(), + renderer.get_resolution(), )], ) .expect("Failed to update global constants");