From 03e8eb42ad2207d6634bfa0cfacbcc2efd9373bf Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 9 Sep 2022 11:59:40 +0100 Subject: [PATCH 1/5] Added experimental BetterAA shader --- assets/voxygen/shaders/antialias/fxaa.glsl | 10 ++++-- assets/voxygen/shaders/postprocess-frag.glsl | 36 +++++++++++++++++++- voxygen/src/render/mod.rs | 2 ++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/assets/voxygen/shaders/antialias/fxaa.glsl b/assets/voxygen/shaders/antialias/fxaa.glsl index 24ffe84cb9..7fe89a77e7 100644 --- a/assets/voxygen/shaders/antialias/fxaa.glsl +++ b/assets/voxygen/shaders/antialias/fxaa.glsl @@ -124,8 +124,14 @@ vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { mediump vec2 v_rgbSE; mediump vec2 v_rgbM; - vec2 scaled_fc = fragCoord * FXAA_SCALE; - vec2 scaled_res = resolution * FXAA_SCALE; + #ifdef EXPERIMENTAL_BETTERAA + float fxaa_scale = textureSize(sampler2D(tex, smplr), 0).x / 900.0; + #else + float fxaa_scale = FXAA_SCALE; + #endif + + vec2 scaled_fc = fragCoord * fxaa_scale; + vec2 scaled_res = resolution * fxaa_scale; //compute the texture coords texcoords(scaled_fc, scaled_res, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); diff --git a/assets/voxygen/shaders/postprocess-frag.glsl b/assets/voxygen/shaders/postprocess-frag.glsl index 85616fe6ea..9050f64e96 100644 --- a/assets/voxygen/shaders/postprocess-frag.glsl +++ b/assets/voxygen/shaders/postprocess-frag.glsl @@ -22,6 +22,7 @@ #include #include #include +#include layout(set = 1, binding = 0) uniform texture2D t_src_color; @@ -43,6 +44,34 @@ uniform texture2D t_src_bloom; layout(location = 0) out vec4 tgt_color; +#ifdef EXPERIMENTAL_BETTERAA + vec4 clever_aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { + uvec2 src_sz = textureSize(sampler2D(tex, smplr), 0).xy; + /* vec4 interp = texture(sampler2D(tex, smplr), fragCoord / resolution); */ + /* vec4 interp = textureBicubic(tex, smplr, fragCoord * src_sz / resolution); */ + vec4 interp = aa_apply(tex, smplr, fragCoord, resolution); + vec4 original = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz), 0); + + vec4 closest = vec4(0.0); + float closest_dist = 100000.0; + for (int i = -1; i < 2; i ++) { + for (int j = -1; j < 2; j ++) { + ivec2 rpos = ivec2(i, j); + + vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz) + rpos, 0); + + float dist = distance(interp.rgb, texel.rgb); + if (dist < closest_dist) { + closest = texel; + closest_dist = dist; + } + } + } + + return mix(closest, interp, 0.0); + } +#endif + vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); @@ -209,7 +238,12 @@ void main() { } #endif - vec4 aa_color = aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); + #ifdef EXPERIMENTAL_BETTERAA + vec4 aa_color = clever_aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); + #else + vec4 aa_color = aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); + #endif + #ifdef EXPERIMENTAL_SOBEL vec3 s[8]; diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index c0b7e4f2b1..90857a4c70 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -482,4 +482,6 @@ pub enum ExperimentalShader { NoRainbows, /// Make objects appear wet when appropriate. Wetness, + /// An attempt at better anti-aliasing (requires FXAA). + BetterAA, } From 80fa0baf09cc37310aa65cb3a7a80cfddad99335 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 10 Sep 2022 10:56:22 +0100 Subject: [PATCH 2/5] Added HQX anti-aliasing --- assets/voxygen/shaders/antialias/fxaa.glsl | 9 +- assets/voxygen/shaders/antialias/hqx.glsl | 63 ++++++ .../voxygen/shaders/antialias/msaa-x16.glsl | 9 +- assets/voxygen/shaders/antialias/msaa-x4.glsl | 7 +- assets/voxygen/shaders/antialias/msaa-x8.glsl | 7 +- assets/voxygen/shaders/antialias/none.glsl | 7 +- assets/voxygen/shaders/postprocess-frag.glsl | 192 +++++++++++++++++- voxygen/src/hud/settings_window/video.rs | 6 +- voxygen/src/render/mod.rs | 17 ++ voxygen/src/render/pipelines/clouds.rs | 7 +- voxygen/src/render/pipelines/debug.rs | 7 +- voxygen/src/render/pipelines/figure.rs | 7 +- voxygen/src/render/pipelines/fluid.rs | 7 +- voxygen/src/render/pipelines/lod_object.rs | 7 +- voxygen/src/render/pipelines/lod_terrain.rs | 7 +- voxygen/src/render/pipelines/particle.rs | 7 +- voxygen/src/render/pipelines/postprocess.rs | 36 +++- .../src/render/pipelines/rain_occlusion.rs | 14 +- voxygen/src/render/pipelines/shadow.rs | 21 +- voxygen/src/render/pipelines/skybox.rs | 7 +- voxygen/src/render/pipelines/sprite.rs | 7 +- voxygen/src/render/pipelines/terrain.rs | 7 +- voxygen/src/render/pipelines/trail.rs | 7 +- voxygen/src/render/renderer.rs | 12 +- voxygen/src/render/renderer/locals.rs | 4 + .../src/render/renderer/pipeline_creation.rs | 1 + voxygen/src/render/renderer/shaders.rs | 1 + 27 files changed, 357 insertions(+), 126 deletions(-) create mode 100644 assets/voxygen/shaders/antialias/hqx.glsl diff --git a/assets/voxygen/shaders/antialias/fxaa.glsl b/assets/voxygen/shaders/antialias/fxaa.glsl index 7fe89a77e7..6d4c91f80c 100644 --- a/assets/voxygen/shaders/antialias/fxaa.glsl +++ b/assets/voxygen/shaders/antialias/fxaa.glsl @@ -117,7 +117,12 @@ void texcoords(vec2 fragCoord, vec2 resolution, } -vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { +vec4 aa_apply( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + vec2 fragCoord, + vec2 resolution +) { mediump vec2 v_rgbNW; mediump vec2 v_rgbNE; mediump vec2 v_rgbSW; @@ -125,7 +130,7 @@ vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { mediump vec2 v_rgbM; #ifdef EXPERIMENTAL_BETTERAA - float fxaa_scale = textureSize(sampler2D(tex, smplr), 0).x / 900.0; + float fxaa_scale = textureSize(sampler2D(tex, smplr), 0).x / 1000.0; #else float fxaa_scale = FXAA_SCALE; #endif diff --git a/assets/voxygen/shaders/antialias/hqx.glsl b/assets/voxygen/shaders/antialias/hqx.glsl new file mode 100644 index 0000000000..6e7d9e2139 --- /dev/null +++ b/assets/voxygen/shaders/antialias/hqx.glsl @@ -0,0 +1,63 @@ +const float THRESHOLD = 0.025; +const float DEPTH_THRESHOLD = 0.05; + +bool diag( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + const float line_thickness, + inout vec4 sum, + vec2 uv, + const vec2 p1, + const vec2 p2, + const float aa_scale +) { + vec4 v1 = texelFetch(sampler2D(tex, smplr), ivec2(uv + vec2(p1.x, p1.y)), 0); + vec4 v2 = texelFetch(sampler2D(tex, smplr), ivec2(uv + vec2(p2.x, p2.y)), 0); + float d1 = 1.0 / texelFetch(sampler2D(depth_tex, depth_smplr), ivec2(uv + vec2(p1.x, p1.y)), 0).x; + float d2 = 1.0 / texelFetch(sampler2D(depth_tex, depth_smplr), ivec2(uv + vec2(p2.x, p2.y)), 0).x; + if (length((v1 - v2).rb) < THRESHOLD && abs(d1 - d2) < d1 * DEPTH_THRESHOLD + 3.0) { + vec2 dir = p2 - p1; + vec2 lp = uv - (floor(uv + p1) + 0.5); + dir = normalize(vec2(dir.y, -dir.x)); + float l = clamp((line_thickness - dot(lp, dir)) * aa_scale, 0.0, 1.0); + sum = mix(sum, (v1 + v2) * 0.5, l); + return true; + } + return false; +} + +vec4 aa_apply( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + vec2 fragCoord, + vec2 resolution +) { + uvec2 src_sz = textureSize(sampler2D(tex, smplr), 0).xy; + + vec2 upscale = resolution / src_sz; + vec2 ip = fragCoord / upscale; + //start with nearest pixel as 'background' + vec4 s = texelFetch(sampler2D(tex, smplr), ivec2(ip), 0); + + float aa_scale = upscale.x * 1.5; + + //draw anti aliased diagonal lines of surrounding pixels as 'foreground' + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(-1, 0), vec2(0, 1), aa_scale)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, 0), vec2(1, 1), aa_scale); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, -1), vec2(0, 1), aa_scale); + } + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(0, 1), vec2(1, 0), aa_scale)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(0, 1), vec2(1, -1), aa_scale); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, 1), vec2(1, 0), aa_scale); + } + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(1, 0), vec2(0, -1), aa_scale)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, 0), vec2(-1, -1), aa_scale); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, 1), vec2(0, -1), aa_scale); + } + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(0, -1), vec2(-1, 0), aa_scale)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(0, -1), vec2(-1, 1), aa_scale); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, -1), vec2(-1, 0), aa_scale); + } + + return s; +} diff --git a/assets/voxygen/shaders/antialias/msaa-x16.glsl b/assets/voxygen/shaders/antialias/msaa-x16.glsl index df5bbaaa2c..0598c3ee4a 100644 --- a/assets/voxygen/shaders/antialias/msaa-x16.glsl +++ b/assets/voxygen/shaders/antialias/msaa-x16.glsl @@ -1,4 +1,9 @@ -vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { +vec4 aa_apply( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + vec2 fragCoord, + vec2 resolution +) { ivec2 texel_coord = ivec2(fragCoord.x, fragCoord.y); vec4 sample1 = texelFetch(sampler2DMS(tex, smplr), texel_coord, 0); @@ -20,7 +25,7 @@ vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { // Average Samples vec4 msaa_color = ( - sample1 + sample2 + sample3 + sample4 + sample5 + sample6 + sample7 + sample8 + + sample1 + sample2 + sample3 + sample4 + sample5 + sample6 + sample7 + sample8 + sample9 + sample10 + sample11 + sample12 + sample13 + sample14 + sample15 + sample16 ) / 16.0; diff --git a/assets/voxygen/shaders/antialias/msaa-x4.glsl b/assets/voxygen/shaders/antialias/msaa-x4.glsl index f6d2e76841..6ab01e8aa2 100644 --- a/assets/voxygen/shaders/antialias/msaa-x4.glsl +++ b/assets/voxygen/shaders/antialias/msaa-x4.glsl @@ -1,4 +1,9 @@ -vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { +vec4 aa_apply( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + vec2 fragCoord, + vec2 resolution +) { ivec2 texel_coord = ivec2(fragCoord.x, fragCoord.y); vec4 sample1 = texelFetch(sampler2DMS(tex, smplr), texel_coord, 0); diff --git a/assets/voxygen/shaders/antialias/msaa-x8.glsl b/assets/voxygen/shaders/antialias/msaa-x8.glsl index cacdc7c4bf..1d15046299 100644 --- a/assets/voxygen/shaders/antialias/msaa-x8.glsl +++ b/assets/voxygen/shaders/antialias/msaa-x8.glsl @@ -1,4 +1,9 @@ -vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { +vec4 aa_apply( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + vec2 fragCoord, + vec2 resolution +) { ivec2 texel_coord = ivec2(fragCoord.x, fragCoord.y); vec4 sample1 = texelFetch(sampler2DMS(tex, smplr), texel_coord, 0); diff --git a/assets/voxygen/shaders/antialias/none.glsl b/assets/voxygen/shaders/antialias/none.glsl index 2e537bc3f8..ff2ae63e2e 100644 --- a/assets/voxygen/shaders/antialias/none.glsl +++ b/assets/voxygen/shaders/antialias/none.glsl @@ -1,3 +1,8 @@ -vec4 aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { +vec4 aa_apply( + texture2D tex, sampler smplr, + texture2D depth_tex, sampler depth_smplr, + vec2 fragCoord, + vec2 resolution +) { return texture(sampler2D(tex, smplr), fragCoord / resolution); } diff --git a/assets/voxygen/shaders/postprocess-frag.glsl b/assets/voxygen/shaders/postprocess-frag.glsl index 9050f64e96..18b4086385 100644 --- a/assets/voxygen/shaders/postprocess-frag.glsl +++ b/assets/voxygen/shaders/postprocess-frag.glsl @@ -29,9 +29,14 @@ uniform texture2D t_src_color; layout(set = 1, binding = 1) uniform sampler s_src_color; +layout(set = 1, binding = 2) +uniform texture2D t_src_depth; +layout(set = 1, binding = 3) +uniform sampler s_src_depth; + layout(location = 0) in vec2 uv; -layout (std140, set = 1, binding = 2) +layout (std140, set = 1, binding = 4) uniform u_locals { mat4 proj_mat_inv; mat4 view_mat_inv; @@ -45,22 +50,111 @@ uniform texture2D t_src_bloom; layout(location = 0) out vec4 tgt_color; #ifdef EXPERIMENTAL_BETTERAA - vec4 clever_aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { + vec3 wpos_at(vec2 uv) { + float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x - 0.0001; + vec4 clip_space = vec4((uv * 2.0 - 1.0) * vec2(1, -1), buf_depth, 1.0); + mat4 all_mat_inv = view_mat_inv * proj_mat_inv; + vec4 view_space = all_mat_inv * clip_space; + view_space /= view_space.w; + if (buf_depth == 0.0) { + vec3 direction = normalize(view_space.xyz); + return direction.xyz * 524288.0625 + cam_pos.xyz; + } else { + return view_space.xyz; + } + } + + float depth_at(vec2 uv) { + float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x; + return 1.0 / buf_depth; + } + + float weighted_lerp(float x, float a, float b) { + return pow(x, b / a); + /* return x; */ + float xx = b * x - a * (1.0 - x); + return sign(xx) * (1.0 - 1.0 / (1.0 + abs(xx))) * 0.5 + 0.5; + } + + float vmax(vec3 v) { + return max(v.x, max(v.y, v.z)); + } + + float vmax_but_one(vec3 v) { + float m = max(v.x, max(v.y, v.z)); + if (v.x == m) + return max(v.y, v.z); + else if (v.y == m) + return max(v.x, v.z); + else + return max(v.x, v.y); + } + + vec4 better_aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { uvec2 src_sz = textureSize(sampler2D(tex, smplr), 0).xy; - /* vec4 interp = texture(sampler2D(tex, smplr), fragCoord / resolution); */ - /* vec4 interp = textureBicubic(tex, smplr, fragCoord * src_sz / resolution); */ - vec4 interp = aa_apply(tex, smplr, fragCoord, resolution); + + vec3 wpos = wpos_at(fragCoord / resolution); + float dist = distance(cam_pos.xyz, wpos); + vec3 dir = normalize(wpos - cam_pos.xyz); + + // vec4 interp = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz), 0); + // vec4 interp = texture(sampler2D(tex, smplr), fragCoord / resolution); + // vec4 interp = textureBicubic(tex, smplr, fragCoord * src_sz / resolution); + vec4 interp = aa_apply(tex, smplr, t_src_depth, s_src_depth, fragCoord, resolution); vec4 original = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz), 0); + // GRID + /* if (mod(fragCoord.x, resolution.x / src_sz.x) < 0.9) { return vec4(0.0, 0.0, 0.0, 0.0); } */ + /* if (mod(fragCoord.y, resolution.y / src_sz.y) < 0.9) { return vec4(0.0, 0.0, 0.0, 0.0); } */ + + vec2 pos = fragCoord;// - 0.5 * src_sz; + + // vec4 t00 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(0, 0)), 0); + // vec4 t10 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(1, 0)), 0); + // vec4 t01 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(0, 1)), 0); + // vec4 t11 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(1, 1)), 0); + vec3 w00 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(0, 0)) / vec2(src_sz)); + vec3 w10 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(1, 0)) / vec2(src_sz)); + vec3 w01 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(0, 1)) / vec2(src_sz)); + vec3 w11 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(1, 1)) / vec2(src_sz)); + float d00 = distance(w00, cam_pos.xyz); + float d10 = distance(w10, cam_pos.xyz); + float d01 = distance(w01, cam_pos.xyz); + float d11 = distance(w11, cam_pos.xyz); + + vec2 px_fact = fract(pos / (resolution / vec2(src_sz))); + // vec4 t0 = mix(t00, t10, weighted_lerp(px_fact.x, d00, d10)); + // vec4 t1 = mix(t01, t11, weighted_lerp(px_fact.x, d01, d11)); + vec3 w0 = (w00 * d00 * (1 - px_fact.x) + w10 * d10 * px_fact.x) / (d00 * (1 - px_fact.x) + d10 * px_fact.x); + vec3 w1 = (w01 * d01 * (1 - px_fact.x) + w11 * d11 * px_fact.x) / (d01 * (1 - px_fact.x) + d11 * px_fact.x); + float d0 = mix(d00, d10, px_fact.x); + float d1 = mix(d01, d11, px_fact.x); + + float d_lerped = mix(d0, d1, px_fact.y); + vec3 wpos_lerped = (w0 * d0 * (1 - px_fact.y) + w1 * d1 * px_fact.y) / (d0 * (1 - px_fact.y) + d1 * px_fact.y) + vec3( + dir.y > 0.0 ? 0.0 : 0.5, + dir.x > 0.0 ? 0.5 : 0.0, + 0.5 + );//mix(w0, w1, weighted_lerp(px_fact.y, 0.1 / d0, 0.1 / d1)) + 0.5; + + // vec4 interp = mix(t0, t1, weighted_lerp(px_fact.y, d0, d1)); + + /* vec4 closest = vec4(0.0); float closest_dist = 100000.0; for (int i = -1; i < 2; i ++) { for (int j = -1; j < 2; j ++) { ivec2 rpos = ivec2(i, j); + //float l = length(normalize(vec2(rpos)) - factor); + vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz) + rpos, 0); - float dist = distance(interp.rgb, texel.rgb); + float fov = 70.0; + float texel_at_dist = dist / resolution.x * fov; + vec3 diff = mod(wpos * texel_at_dist, vec3(1.0)) - 0.5; + + float dist = distance(interp.rgb, texel.rgb);// * 0.0 + (rpos.y - diff.z) * 1.0;// * (1.0 + l * 0.5); if (dist < closest_dist) { closest = texel; closest_dist = dist; @@ -68,7 +162,85 @@ layout(location = 0) out vec4 tgt_color; } } - return mix(closest, interp, 0.0); + return closest;//interp; + */ + /* + ivec2 closest = ivec2(0); + vec3 closest_wpos = vec3(0); + float closest_dist = 100000.0; + for (int i = -1; i < 2; i ++) { + for (int j = -1; j < 2; j ++) { + ivec2 rpos = ivec2(i, j); + vec3 wpos = wpos_at(((fragCoord / resolution * vec2(src_sz)) + rpos) / vec2(src_sz)); + float dist = distance(cam_pos.xyz, wpos); + if (dist < closest_dist) { + closest = rpos; + closest_wpos = wpos; + closest_dist = dist; + } + } + } + + float fov = 70.0; + vec2 texel_at_dist = src_sz / (fov * closest_dist); + vec3 diff = fract(closest_wpos) * 2.0 - 1.0; + + vec2 rpos = vec2(diff.y * dir.x, -diff.z * -abs(dir.x)) + //+ vec2(diff.x * -dir.y, diff.z * abs(dir.y)) + //+ vec2(diff.z * -dir.z * 0, diff.x * abs(dir.z)) + ; + + vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz + closest + rpos), 0); + + return texel; + */ + + float original_dist = dist; + vec4 closest_texel = vec4(0); + vec3 closest_wpos = vec3(0); + float closest_dist = 100000.0; + vec4 weighted_sum = vec4(0.0); + float weighted_total = 0.0; + for (int i = -1; i < 2; i ++) { + for (int j = -1; j < 2; j ++) { + ivec2 rpos = ivec2(i, j); + vec3 wpos = wpos_at(floor(fragCoord / resolution * vec2(src_sz) + rpos - 1) / vec2(src_sz)); + float tdist = distance(cam_pos.xyz, wpos); + + //float fov = 1.2; + //float texel_at_dist = src_sz.x / (fov * tdist); + + vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz) + rpos, 0); + //texel = texture(sampler2D(tex, smplr), floor(fragCoord / resolution * vec2(src_sz) + rpos) / vec2(src_sz)); + + float texel_dist; + if (true && false) { + texel_dist = distance(wpos + fract(wpos_lerped * 2.0) / 2.0, wpos_lerped); + } else if (original_dist < 15.0 || true) { + texel_dist = distance(interp.rgb, texel.rgb); + } else { + texel_dist = length(mod(wpos, vec3(1.0)) - 0.5); + } + + if (texel_dist < closest_dist) { + closest_texel = texel; + closest_wpos = wpos; + closest_dist = texel_dist; + } + + //float weight = 1.0 / distance(interp.rgb, texel.rgb); + float weight = 1.0 / distance(wpos, wpos_lerped); + + weighted_sum += texel * weight; + weighted_total += weight; + } + } + + //return vec4(px_fact.xy, 1.0, 1.0); + //return mod(10.0 * d_lerped, 1.0).xxxx; + //return mod(wpos_lerped, 1.0).xyzx; + //return weighted_sum / weighted_total; + return closest_texel; } #endif @@ -185,7 +357,7 @@ vec3 _illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitte #ifdef EXPERIMENTAL_SOBEL vec3 aa_sample(vec2 uv, vec2 off) { - return aa_apply(t_src_color, s_src_color, uv * screen_res.xy + off, screen_res.xy).rgb; + return aa_apply(t_src_color, s_src_color, t_src_depth, s_src_depth, uv * screen_res.xy + off, screen_res.xy).rgb; } #endif @@ -239,9 +411,9 @@ void main() { #endif #ifdef EXPERIMENTAL_BETTERAA - vec4 aa_color = clever_aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); + vec4 aa_color = better_aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); #else - vec4 aa_color = aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); + vec4 aa_color = aa_apply(t_src_color, s_src_color, t_src_depth, s_src_depth, sample_uv * screen_res.xy, screen_res.xy); #endif diff --git a/voxygen/src/hud/settings_window/video.rs b/voxygen/src/hud/settings_window/video.rs index 6b445957a5..ef19eeee89 100644 --- a/voxygen/src/hud/settings_window/video.rs +++ b/voxygen/src/hud/settings_window/video.rs @@ -804,13 +804,15 @@ impl<'a> Widget for Video<'a> { /* AaMode::MsaaX4, AaMode::MsaaX8, AaMode::MsaaX16, */ + AaMode::Hqx, ]; let mode_label_list = [ - "No AA", + "No anti-aliasing", "FXAA", /* "MSAA x4", "MSAA x8", "MSAA x16 (experimental)", */ + "HQX", ]; // Get which AA mode is currently active @@ -941,7 +943,7 @@ impl<'a> Widget for Video<'a> { let upscale_factors = [ // Upscaling - 0.15, 0.2, 0.25, 0.35, 0.5, 0.65, 0.75, 0.85, 1.0, + 0.01, 0.025, 0.1, 0.15, 0.2, 0.25, 0.35, 0.5, 0.65, 0.75, 0.85, 1.0, // Downscaling (equivalent to SSAA) 1.25, 1.5, 1.75, 2.0, ]; diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 90857a4c70..8fc065a5df 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -93,10 +93,27 @@ pub enum AaMode { /// also struggle in the future with deferred shading, so they may be /// removed in the future. MsaaX16, + /// Fast upscaling re-aliasing. + /// + /// Screen-space technique that attempts to reconstruct lines and edges + /// in the original image. Useless at internal resolutions higher than 1.0x, + /// but potentially very effective at much lower internal resolutions. + Hqx, #[serde(other)] None, } +impl AaMode { + pub fn samples(&self) -> u32 { + match self { + AaMode::None | AaMode::Fxaa | AaMode::Hqx => 1, + AaMode::MsaaX4 => 4, + AaMode::MsaaX8 => 8, + AaMode::MsaaX16 => 16, + } + } +} + impl Default for AaMode { fn default() -> Self { AaMode::Fxaa } } diff --git a/voxygen/src/render/pipelines/clouds.rs b/voxygen/src/render/pipelines/clouds.rs index 52773d3c0c..e64356ee56 100644 --- a/voxygen/src/render/pipelines/clouds.rs +++ b/voxygen/src/render/pipelines/clouds.rs @@ -158,12 +158,7 @@ impl CloudsPipeline { ], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Clouds pipeline"), diff --git a/voxygen/src/render/pipelines/debug.rs b/voxygen/src/render/pipelines/debug.rs index 3edde4ea29..681bba4ce7 100644 --- a/voxygen/src/render/pipelines/debug.rs +++ b/voxygen/src/render/pipelines/debug.rs @@ -71,12 +71,7 @@ impl DebugPipeline { bind_group_layouts: &[&global_layouts.globals, &layout.locals], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Debug pipeline"), diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index a673e8b49d..0bca9a6412 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -190,12 +190,7 @@ impl FigurePipeline { ], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Figure pipeline"), diff --git a/voxygen/src/render/pipelines/fluid.rs b/voxygen/src/render/pipelines/fluid.rs index e4250413d8..de9c70c177 100644 --- a/voxygen/src/render/pipelines/fluid.rs +++ b/voxygen/src/render/pipelines/fluid.rs @@ -70,12 +70,7 @@ impl FluidPipeline { ], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Fluid pipeline"), diff --git a/voxygen/src/render/pipelines/lod_object.rs b/voxygen/src/render/pipelines/lod_object.rs index 8e86d9aef9..23be60873f 100644 --- a/voxygen/src/render/pipelines/lod_object.rs +++ b/voxygen/src/render/pipelines/lod_object.rs @@ -94,12 +94,7 @@ impl LodObjectPipeline { bind_group_layouts: &[&global_layout.globals, &global_layout.shadow_textures], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("LoD object pipeline"), diff --git a/voxygen/src/render/pipelines/lod_terrain.rs b/voxygen/src/render/pipelines/lod_terrain.rs index 7a4a757eaf..8d02835706 100644 --- a/voxygen/src/render/pipelines/lod_terrain.rs +++ b/voxygen/src/render/pipelines/lod_terrain.rs @@ -209,12 +209,7 @@ impl LodTerrainPipeline { bind_group_layouts: &[&global_layout.globals, &global_layout.shadow_textures], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Lod terrain pipeline"), diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index 7c701fa3f6..9b44894b48 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -200,12 +200,7 @@ impl ParticlePipeline { bind_group_layouts: &[&global_layout.globals, &global_layout.shadow_textures], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Particle pipeline"), diff --git a/voxygen/src/render/pipelines/postprocess.rs b/voxygen/src/render/pipelines/postprocess.rs index 3d67c2d4d4..5f069db833 100644 --- a/voxygen/src/render/pipelines/postprocess.rs +++ b/voxygen/src/render/pipelines/postprocess.rs @@ -53,9 +53,29 @@ impl PostProcessLayout { }, count: None, }, - // Locals + // Depth source wgpu::BindGroupLayoutEntry { binding: 2, + visibility: wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + visibility: wgpu::ShaderStage::FRAGMENT, + ty: wgpu::BindingType::Sampler { + filtering: true, + comparison: false, + }, + count: None, + }, + // Locals + wgpu::BindGroupLayoutEntry { + binding: 4, visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, @@ -70,7 +90,7 @@ impl PostProcessLayout { bind_entries.push( // src bloom wgpu::BindGroupLayoutEntry { - binding: 3, + binding: 5, visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Texture { sample_type: wgpu::TextureSampleType::Float { filterable: true }, @@ -94,8 +114,10 @@ impl PostProcessLayout { &self, device: &wgpu::Device, src_color: &wgpu::TextureView, + src_depth: &wgpu::TextureView, src_bloom: Option<&wgpu::TextureView>, sampler: &wgpu::Sampler, + depth_sampler: &wgpu::Sampler, locals: &Consts, ) -> BindGroup { let mut entries = vec![ @@ -109,6 +131,14 @@ impl PostProcessLayout { }, wgpu::BindGroupEntry { binding: 2, + resource: wgpu::BindingResource::TextureView(src_depth), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: wgpu::BindingResource::Sampler(depth_sampler), + }, + wgpu::BindGroupEntry { + binding: 4, resource: locals.buf().as_entire_binding(), }, ]; @@ -120,7 +150,7 @@ impl PostProcessLayout { // TODO: if there is no upscaling we can do the last bloom upsampling in post // process to save a pass and the need for the final full size bloom render target wgpu::BindGroupEntry { - binding: 3, + binding: 5, resource: wgpu::BindingResource::TextureView(src_bloom), }, ); diff --git a/voxygen/src/render/pipelines/rain_occlusion.rs b/voxygen/src/render/pipelines/rain_occlusion.rs index 81eac21ecf..18a2cea9ea 100644 --- a/voxygen/src/render/pipelines/rain_occlusion.rs +++ b/voxygen/src/render/pipelines/rain_occlusion.rs @@ -103,12 +103,7 @@ impl RainOcclusionFigurePipeline { bind_group_layouts: &[&global_layout.globals, &figure_layout.locals], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Rain occlusion figure pipeline"), @@ -176,12 +171,7 @@ impl RainOcclusionPipeline { bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Rain occlusion pipeline"), diff --git a/voxygen/src/render/pipelines/shadow.rs b/voxygen/src/render/pipelines/shadow.rs index 704af49da2..107d3b2216 100644 --- a/voxygen/src/render/pipelines/shadow.rs +++ b/voxygen/src/render/pipelines/shadow.rs @@ -145,12 +145,7 @@ impl ShadowFigurePipeline { bind_group_layouts: &[&global_layout.globals, &figure_layout.locals], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Directed shadow figure pipeline"), @@ -218,12 +213,7 @@ impl ShadowPipeline { bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Directed shadow pipeline"), @@ -293,12 +283,7 @@ impl PointShadowPipeline { bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Point shadow pipeline"), diff --git a/voxygen/src/render/pipelines/skybox.rs b/voxygen/src/render/pipelines/skybox.rs index 9d59ecc729..a3e9e6a863 100644 --- a/voxygen/src/render/pipelines/skybox.rs +++ b/voxygen/src/render/pipelines/skybox.rs @@ -48,12 +48,7 @@ impl SkyboxPipeline { bind_group_layouts: &[&layouts.globals, &layouts.shadow_textures], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Skybox pipeline"), diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index c309a50bfb..3c0085dd7c 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -267,12 +267,7 @@ impl SpritePipeline { ], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Sprite pipeline"), diff --git a/voxygen/src/render/pipelines/terrain.rs b/voxygen/src/render/pipelines/terrain.rs index d0661ec416..8a6e4ad16e 100644 --- a/voxygen/src/render/pipelines/terrain.rs +++ b/voxygen/src/render/pipelines/terrain.rs @@ -234,12 +234,7 @@ impl TerrainPipeline { ], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Terrain pipeline"), diff --git a/voxygen/src/render/pipelines/trail.rs b/voxygen/src/render/pipelines/trail.rs index 5584db3a61..5ab28a59c2 100644 --- a/voxygen/src/render/pipelines/trail.rs +++ b/voxygen/src/render/pipelines/trail.rs @@ -69,12 +69,7 @@ impl TrailPipeline { bind_group_layouts: &[&global_layout.globals, &global_layout.shadow_textures], }); - let samples = match aa_mode { - AaMode::None | AaMode::Fxaa => 1, - AaMode::MsaaX4 => 4, - AaMode::MsaaX8 => 8, - AaMode::MsaaX16 => 16, - }; + let samples = aa_mode.samples(); let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("Trail pipeline"), diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 804b8aacb9..35ea14643c 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -28,8 +28,8 @@ use super::{ ui, GlobalsBindGroup, GlobalsLayouts, ShadowTexturesBindGroup, }, texture::Texture, - AaMode, AddressMode, FilterMode, OtherModes, PipelineModes, RenderError, RenderMode, - ShadowMapMode, ShadowMode, Vertex, + AddressMode, FilterMode, OtherModes, PipelineModes, RenderError, RenderMode, ShadowMapMode, + ShadowMode, Vertex, }; use common::assets::{self, AssetExt, AssetHandle, ReloadWatcher}; use common_base::span; @@ -798,12 +798,8 @@ impl Renderer { let upscaled = Vec2::::from(size) .map(|e| (e as f32 * other_modes.upscale_mode.factor) as u32) .into_tuple(); - let (width, height, sample_count) = match pipeline_modes.aa { - AaMode::None | AaMode::Fxaa => (upscaled.0, upscaled.1, 1), - AaMode::MsaaX4 => (upscaled.0, upscaled.1, 4), - AaMode::MsaaX8 => (upscaled.0, upscaled.1, 8), - AaMode::MsaaX16 => (upscaled.0, upscaled.1, 16), - }; + let (width, height) = upscaled; + let sample_count = pipeline_modes.aa.samples(); let levels = 1; let color_view = |width, height| { diff --git a/voxygen/src/render/renderer/locals.rs b/voxygen/src/render/renderer/locals.rs index fb3b0301ac..e590396e2c 100644 --- a/voxygen/src/render/renderer/locals.rs +++ b/voxygen/src/render/renderer/locals.rs @@ -47,8 +47,10 @@ impl Locals { let postprocess_bind = layouts.postprocess.bind( device, tgt_color_pp_view, + tgt_depth_view, bloom.as_ref().map(|b| b.final_tgt_view), sampler, + depth_sampler, &postprocess_locals, ); @@ -92,8 +94,10 @@ impl Locals { self.postprocess_bind = layouts.postprocess.bind( device, tgt_color_pp_view, + tgt_depth_view, bloom.as_ref().map(|b| b.final_tgt_view), sampler, + depth_sampler, &self.postprocess, ); self.bloom_binds = bloom.map(|bloom| { diff --git a/voxygen/src/render/renderer/pipeline_creation.rs b/voxygen/src/render/renderer/pipeline_creation.rs index c755caa829..b7d8a00afe 100644 --- a/voxygen/src/render/renderer/pipeline_creation.rs +++ b/voxygen/src/render/renderer/pipeline_creation.rs @@ -247,6 +247,7 @@ impl ShaderModules { AaMode::MsaaX4 => "antialias.msaa-x4", AaMode::MsaaX8 => "antialias.msaa-x8", AaMode::MsaaX16 => "antialias.msaa-x16", + AaMode::Hqx => "antialias.hqx", }) .unwrap(); diff --git a/voxygen/src/render/renderer/shaders.rs b/voxygen/src/render/renderer/shaders.rs index 6bb1b31d54..15cd46a21c 100644 --- a/voxygen/src/render/renderer/shaders.rs +++ b/voxygen/src/render/renderer/shaders.rs @@ -41,6 +41,7 @@ impl assets::Compound for Shaders { "antialias.msaa-x4", "antialias.msaa-x8", "antialias.msaa-x16", + "antialias.hqx", "include.cloud.none", "include.cloud.regular", "figure-vert", From 85a1c06be65ea3cfbabdc0d298d765668de93e4c Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 10 Sep 2022 13:16:47 +0100 Subject: [PATCH 3/5] Better depth-aware HQX --- assets/voxygen/shaders/antialias/hqx.glsl | 52 ++++++++++---------- assets/voxygen/shaders/postprocess-frag.glsl | 2 +- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/assets/voxygen/shaders/antialias/hqx.glsl b/assets/voxygen/shaders/antialias/hqx.glsl index 6e7d9e2139..0eb950877f 100644 --- a/assets/voxygen/shaders/antialias/hqx.glsl +++ b/assets/voxygen/shaders/antialias/hqx.glsl @@ -1,4 +1,4 @@ -const float THRESHOLD = 0.025; +const float THRESHOLD = 0.05; const float DEPTH_THRESHOLD = 0.05; bool diag( @@ -9,21 +9,22 @@ bool diag( vec2 uv, const vec2 p1, const vec2 p2, - const float aa_scale + const float aa_scale, + const uvec2 src_sz ) { - vec4 v1 = texelFetch(sampler2D(tex, smplr), ivec2(uv + vec2(p1.x, p1.y)), 0); - vec4 v2 = texelFetch(sampler2D(tex, smplr), ivec2(uv + vec2(p2.x, p2.y)), 0); + vec4 v1 = texelFetch(sampler2D(tex, smplr), ivec2(uv + p1 * 0.5), 0); + vec4 v2 = texelFetch(sampler2D(tex, smplr), ivec2(uv + p2 * 0.5), 0); float d1 = 1.0 / texelFetch(sampler2D(depth_tex, depth_smplr), ivec2(uv + vec2(p1.x, p1.y)), 0).x; float d2 = 1.0 / texelFetch(sampler2D(depth_tex, depth_smplr), ivec2(uv + vec2(p2.x, p2.y)), 0).x; - if (length((v1 - v2).rb) < THRESHOLD && abs(d1 - d2) < d1 * DEPTH_THRESHOLD + 3.0) { - vec2 dir = p2 - p1; - vec2 lp = uv - (floor(uv + p1) + 0.5); - dir = normalize(vec2(dir.y, -dir.x)); - float l = clamp((line_thickness - dot(lp, dir)) * aa_scale, 0.0, 1.0); - sum = mix(sum, (v1 + v2) * 0.5, l); - return true; + if (length((normalize(v1) - normalize(v2)).rgb) > THRESHOLD || abs(d1 - d2) > d1 * DEPTH_THRESHOLD + 3.0) { + return false; } - return false; + vec2 dir = p2 - p1; + vec2 lp = uv - (floor(uv + p1) + 0.5); + dir = normalize(vec2(dir.y, -dir.x)); + float l = clamp((line_thickness - dot(lp, dir)) * aa_scale, 0.0, 1.0); + sum = mix(sum, (v1 + v2) * 0.5, l); + return true; } vec4 aa_apply( @@ -38,25 +39,26 @@ vec4 aa_apply( vec2 ip = fragCoord / upscale; //start with nearest pixel as 'background' vec4 s = texelFetch(sampler2D(tex, smplr), ivec2(ip), 0); + //vec4 s = texture(sampler2D(tex, smplr), fragCoord / resolution); - float aa_scale = upscale.x * 1.5; + float aa_scale = upscale.x * 0.5; //draw anti aliased diagonal lines of surrounding pixels as 'foreground' - if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(-1, 0), vec2(0, 1), aa_scale)) { - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, 0), vec2(1, 1), aa_scale); - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, -1), vec2(0, 1), aa_scale); + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(-1, 0), vec2(0, 1), aa_scale, src_sz)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, 0), vec2(1, 1), aa_scale, src_sz); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, -1), vec2(0, 1), aa_scale, src_sz); } - if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(0, 1), vec2(1, 0), aa_scale)) { - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(0, 1), vec2(1, -1), aa_scale); - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, 1), vec2(1, 0), aa_scale); + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(0, 1), vec2(1, 0), aa_scale, src_sz)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(0, 1), vec2(1, -1), aa_scale, src_sz); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(-1, 1), vec2(1, 0), aa_scale, src_sz); } - if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(1, 0), vec2(0, -1), aa_scale)) { - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, 0), vec2(-1, -1), aa_scale); - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, 1), vec2(0, -1), aa_scale); + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(1, 0), vec2(0, -1), aa_scale, src_sz)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, 0), vec2(-1, -1), aa_scale, src_sz); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, 1), vec2(0, -1), aa_scale, src_sz); } - if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(0, -1), vec2(-1, 0), aa_scale)) { - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(0, -1), vec2(-1, 1), aa_scale); - diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, -1), vec2(-1, 0), aa_scale); + if (diag(tex, smplr, depth_tex, depth_smplr, 0.4, s, ip, vec2(0, -1), vec2(-1, 0), aa_scale, src_sz)) { + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(0, -1), vec2(-1, 1), aa_scale, src_sz); + diag(tex, smplr, depth_tex, depth_smplr, 0.3, s, ip, vec2(1, -1), vec2(-1, 0), aa_scale, src_sz); } return s; diff --git a/assets/voxygen/shaders/postprocess-frag.glsl b/assets/voxygen/shaders/postprocess-frag.glsl index 18b4086385..c7c7ddaf83 100644 --- a/assets/voxygen/shaders/postprocess-frag.glsl +++ b/assets/voxygen/shaders/postprocess-frag.glsl @@ -43,7 +43,7 @@ uniform u_locals { }; #ifdef BLOOM_FACTOR -layout(set = 1, binding = 3) +layout(set = 1, binding = 5) uniform texture2D t_src_bloom; #endif From b3b2f404e53001f5ed82b004db66a1a7a463d270 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 10 Sep 2022 13:33:38 +0100 Subject: [PATCH 4/5] Fixed FXAA at non-1.0x scales --- assets/voxygen/shaders/antialias/fxaa.glsl | 8 +- assets/voxygen/shaders/postprocess-frag.glsl | 201 +------------------ voxygen/src/hud/settings_window/video.rs | 4 +- voxygen/src/render/mod.rs | 2 - 4 files changed, 4 insertions(+), 211 deletions(-) diff --git a/assets/voxygen/shaders/antialias/fxaa.glsl b/assets/voxygen/shaders/antialias/fxaa.glsl index 6d4c91f80c..0b1a85272b 100644 --- a/assets/voxygen/shaders/antialias/fxaa.glsl +++ b/assets/voxygen/shaders/antialias/fxaa.glsl @@ -1,5 +1,3 @@ -const float FXAA_SCALE = 1.25; - /** Basic FXAA implementation based on the code on geeks3d.com with the modification that the texture2DLod stuff was removed since it's @@ -129,11 +127,7 @@ vec4 aa_apply( mediump vec2 v_rgbSE; mediump vec2 v_rgbM; - #ifdef EXPERIMENTAL_BETTERAA - float fxaa_scale = textureSize(sampler2D(tex, smplr), 0).x / 1000.0; - #else - float fxaa_scale = FXAA_SCALE; - #endif + float fxaa_scale = textureSize(sampler2D(tex, smplr), 0).x * 1.25 / resolution.x; vec2 scaled_fc = fragCoord * fxaa_scale; vec2 scaled_res = resolution * fxaa_scale; diff --git a/assets/voxygen/shaders/postprocess-frag.glsl b/assets/voxygen/shaders/postprocess-frag.glsl index c7c7ddaf83..4276bde368 100644 --- a/assets/voxygen/shaders/postprocess-frag.glsl +++ b/assets/voxygen/shaders/postprocess-frag.glsl @@ -49,201 +49,6 @@ uniform texture2D t_src_bloom; layout(location = 0) out vec4 tgt_color; -#ifdef EXPERIMENTAL_BETTERAA - vec3 wpos_at(vec2 uv) { - float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x - 0.0001; - vec4 clip_space = vec4((uv * 2.0 - 1.0) * vec2(1, -1), buf_depth, 1.0); - mat4 all_mat_inv = view_mat_inv * proj_mat_inv; - vec4 view_space = all_mat_inv * clip_space; - view_space /= view_space.w; - if (buf_depth == 0.0) { - vec3 direction = normalize(view_space.xyz); - return direction.xyz * 524288.0625 + cam_pos.xyz; - } else { - return view_space.xyz; - } - } - - float depth_at(vec2 uv) { - float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x; - return 1.0 / buf_depth; - } - - float weighted_lerp(float x, float a, float b) { - return pow(x, b / a); - /* return x; */ - float xx = b * x - a * (1.0 - x); - return sign(xx) * (1.0 - 1.0 / (1.0 + abs(xx))) * 0.5 + 0.5; - } - - float vmax(vec3 v) { - return max(v.x, max(v.y, v.z)); - } - - float vmax_but_one(vec3 v) { - float m = max(v.x, max(v.y, v.z)); - if (v.x == m) - return max(v.y, v.z); - else if (v.y == m) - return max(v.x, v.z); - else - return max(v.x, v.y); - } - - vec4 better_aa_apply(texture2D tex, sampler smplr, vec2 fragCoord, vec2 resolution) { - uvec2 src_sz = textureSize(sampler2D(tex, smplr), 0).xy; - - vec3 wpos = wpos_at(fragCoord / resolution); - float dist = distance(cam_pos.xyz, wpos); - vec3 dir = normalize(wpos - cam_pos.xyz); - - // vec4 interp = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz), 0); - // vec4 interp = texture(sampler2D(tex, smplr), fragCoord / resolution); - // vec4 interp = textureBicubic(tex, smplr, fragCoord * src_sz / resolution); - vec4 interp = aa_apply(tex, smplr, t_src_depth, s_src_depth, fragCoord, resolution); - vec4 original = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz), 0); - - // GRID - /* if (mod(fragCoord.x, resolution.x / src_sz.x) < 0.9) { return vec4(0.0, 0.0, 0.0, 0.0); } */ - /* if (mod(fragCoord.y, resolution.y / src_sz.y) < 0.9) { return vec4(0.0, 0.0, 0.0, 0.0); } */ - - vec2 pos = fragCoord;// - 0.5 * src_sz; - - // vec4 t00 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(0, 0)), 0); - // vec4 t10 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(1, 0)), 0); - // vec4 t01 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(0, 1)), 0); - // vec4 t11 = texelFetch(sampler2D(tex, smplr), ivec2(pos / resolution * src_sz + ivec2(1, 1)), 0); - vec3 w00 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(0, 0)) / vec2(src_sz)); - vec3 w10 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(1, 0)) / vec2(src_sz)); - vec3 w01 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(0, 1)) / vec2(src_sz)); - vec3 w11 = wpos_at(floor(pos / resolution * vec2(src_sz) + ivec2(1, 1)) / vec2(src_sz)); - float d00 = distance(w00, cam_pos.xyz); - float d10 = distance(w10, cam_pos.xyz); - float d01 = distance(w01, cam_pos.xyz); - float d11 = distance(w11, cam_pos.xyz); - - vec2 px_fact = fract(pos / (resolution / vec2(src_sz))); - // vec4 t0 = mix(t00, t10, weighted_lerp(px_fact.x, d00, d10)); - // vec4 t1 = mix(t01, t11, weighted_lerp(px_fact.x, d01, d11)); - vec3 w0 = (w00 * d00 * (1 - px_fact.x) + w10 * d10 * px_fact.x) / (d00 * (1 - px_fact.x) + d10 * px_fact.x); - vec3 w1 = (w01 * d01 * (1 - px_fact.x) + w11 * d11 * px_fact.x) / (d01 * (1 - px_fact.x) + d11 * px_fact.x); - float d0 = mix(d00, d10, px_fact.x); - float d1 = mix(d01, d11, px_fact.x); - - float d_lerped = mix(d0, d1, px_fact.y); - vec3 wpos_lerped = (w0 * d0 * (1 - px_fact.y) + w1 * d1 * px_fact.y) / (d0 * (1 - px_fact.y) + d1 * px_fact.y) + vec3( - dir.y > 0.0 ? 0.0 : 0.5, - dir.x > 0.0 ? 0.5 : 0.0, - 0.5 - );//mix(w0, w1, weighted_lerp(px_fact.y, 0.1 / d0, 0.1 / d1)) + 0.5; - - // vec4 interp = mix(t0, t1, weighted_lerp(px_fact.y, d0, d1)); - - /* - vec4 closest = vec4(0.0); - float closest_dist = 100000.0; - for (int i = -1; i < 2; i ++) { - for (int j = -1; j < 2; j ++) { - ivec2 rpos = ivec2(i, j); - - //float l = length(normalize(vec2(rpos)) - factor); - - vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz) + rpos, 0); - - float fov = 70.0; - float texel_at_dist = dist / resolution.x * fov; - vec3 diff = mod(wpos * texel_at_dist, vec3(1.0)) - 0.5; - - float dist = distance(interp.rgb, texel.rgb);// * 0.0 + (rpos.y - diff.z) * 1.0;// * (1.0 + l * 0.5); - if (dist < closest_dist) { - closest = texel; - closest_dist = dist; - } - } - } - - return closest;//interp; - */ - /* - ivec2 closest = ivec2(0); - vec3 closest_wpos = vec3(0); - float closest_dist = 100000.0; - for (int i = -1; i < 2; i ++) { - for (int j = -1; j < 2; j ++) { - ivec2 rpos = ivec2(i, j); - vec3 wpos = wpos_at(((fragCoord / resolution * vec2(src_sz)) + rpos) / vec2(src_sz)); - float dist = distance(cam_pos.xyz, wpos); - if (dist < closest_dist) { - closest = rpos; - closest_wpos = wpos; - closest_dist = dist; - } - } - } - - float fov = 70.0; - vec2 texel_at_dist = src_sz / (fov * closest_dist); - vec3 diff = fract(closest_wpos) * 2.0 - 1.0; - - vec2 rpos = vec2(diff.y * dir.x, -diff.z * -abs(dir.x)) - //+ vec2(diff.x * -dir.y, diff.z * abs(dir.y)) - //+ vec2(diff.z * -dir.z * 0, diff.x * abs(dir.z)) - ; - - vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz + closest + rpos), 0); - - return texel; - */ - - float original_dist = dist; - vec4 closest_texel = vec4(0); - vec3 closest_wpos = vec3(0); - float closest_dist = 100000.0; - vec4 weighted_sum = vec4(0.0); - float weighted_total = 0.0; - for (int i = -1; i < 2; i ++) { - for (int j = -1; j < 2; j ++) { - ivec2 rpos = ivec2(i, j); - vec3 wpos = wpos_at(floor(fragCoord / resolution * vec2(src_sz) + rpos - 1) / vec2(src_sz)); - float tdist = distance(cam_pos.xyz, wpos); - - //float fov = 1.2; - //float texel_at_dist = src_sz.x / (fov * tdist); - - vec4 texel = texelFetch(sampler2D(tex, smplr), ivec2(fragCoord / resolution * src_sz) + rpos, 0); - //texel = texture(sampler2D(tex, smplr), floor(fragCoord / resolution * vec2(src_sz) + rpos) / vec2(src_sz)); - - float texel_dist; - if (true && false) { - texel_dist = distance(wpos + fract(wpos_lerped * 2.0) / 2.0, wpos_lerped); - } else if (original_dist < 15.0 || true) { - texel_dist = distance(interp.rgb, texel.rgb); - } else { - texel_dist = length(mod(wpos, vec3(1.0)) - 0.5); - } - - if (texel_dist < closest_dist) { - closest_texel = texel; - closest_wpos = wpos; - closest_dist = texel_dist; - } - - //float weight = 1.0 / distance(interp.rgb, texel.rgb); - float weight = 1.0 / distance(wpos, wpos_lerped); - - weighted_sum += texel * weight; - weighted_total += weight; - } - } - - //return vec4(px_fact.xy, 1.0, 1.0); - //return mod(10.0 * d_lerped, 1.0).xxxx; - //return mod(wpos_lerped, 1.0).xyzx; - //return weighted_sum / weighted_total; - return closest_texel; - } -#endif - vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); @@ -410,11 +215,7 @@ void main() { } #endif - #ifdef EXPERIMENTAL_BETTERAA - vec4 aa_color = better_aa_apply(t_src_color, s_src_color, sample_uv * screen_res.xy, screen_res.xy); - #else - vec4 aa_color = aa_apply(t_src_color, s_src_color, t_src_depth, s_src_depth, sample_uv * screen_res.xy, screen_res.xy); - #endif + vec4 aa_color = aa_apply(t_src_color, s_src_color, t_src_depth, s_src_depth, sample_uv * screen_res.xy, screen_res.xy); #ifdef EXPERIMENTAL_SOBEL diff --git a/voxygen/src/hud/settings_window/video.rs b/voxygen/src/hud/settings_window/video.rs index ef19eeee89..81b7ba116d 100644 --- a/voxygen/src/hud/settings_window/video.rs +++ b/voxygen/src/hud/settings_window/video.rs @@ -943,7 +943,7 @@ impl<'a> Widget for Video<'a> { let upscale_factors = [ // Upscaling - 0.01, 0.025, 0.1, 0.15, 0.2, 0.25, 0.35, 0.5, 0.65, 0.75, 0.85, 1.0, + 0.1, 0.15, 0.2, 0.25, 0.35, 0.5, 0.65, 0.75, 0.85, 1.0, // Downscaling (equivalent to SSAA) 1.25, 1.5, 1.75, 2.0, ]; @@ -956,7 +956,7 @@ impl<'a> Widget for Video<'a> { if let Some(clicked) = DropDownList::new( &upscale_factors .iter() - .map(|factor| format!("{n:.*}", 2, n = factor)) + .map(|factor| format!("{n:.*}", 3, n = factor)) .collect::>(), selected, ) diff --git a/voxygen/src/render/mod.rs b/voxygen/src/render/mod.rs index 8fc065a5df..1d8700c388 100644 --- a/voxygen/src/render/mod.rs +++ b/voxygen/src/render/mod.rs @@ -499,6 +499,4 @@ pub enum ExperimentalShader { NoRainbows, /// Make objects appear wet when appropriate. Wetness, - /// An attempt at better anti-aliasing (requires FXAA). - BetterAA, } From 33b807c2372aad7c3e3a184e73054ba3b7c2dbfe Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 10 Sep 2022 13:36:43 +0100 Subject: [PATCH 5/5] Updated changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc5dc7c8b9..3d7807a2fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,13 +14,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added a setting to influence the gap between music track plays. - Added a Craft All button. - Server: Vacuum database on startup -- SeaChapel, greek/latin inspired dungeon for ocean biome coasts +- SeaChapel, greek/latin inspired dungeon for ocean biome coasts - Entity view distance setting added (shown in graphics and network tabs). This setting controls the distance at which entities are synced to the client and which entities are displayed in. This is clamped to be no more than the current overall view distance setting. - View distance settings that are lowered by the server limit (or other factors) now display an extra ghost slider cursor when set above the limit (instead of snapping back to the limit). Limits on the view distance by the server no longer affect the settings saved on the client. +- HQX upscaling shader for people playing on low internal resolutions ### Changed - Use fluent for translations @@ -49,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 first joining a server and when changing the view distance (previously this required moving to a new chunk for the initial setting or subsequent change to apply). - Moderators and admins are no longer blocked from logging in when there are too many players. +- FXAA now behaves correctly at non-1.0x internal resolutions ## [0.13.0] - 2022-07-23