From 69a1a661b6f999e51e728e6d53f37f971effdce6 Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 30 Aug 2022 03:02:12 -0400 Subject: [PATCH] fixes and tweaks (various minor changes related to UI image scaling on GPU) --- assets/voxygen/shaders/ui-frag.glsl | 26 +++++++++++++++++--------- voxygen/src/ui/graphic/mod.rs | 3 +-- voxygen/src/ui/graphic/pixel_art.rs | 9 ++++++--- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/assets/voxygen/shaders/ui-frag.glsl b/assets/voxygen/shaders/ui-frag.glsl index c1f7721580..088e1bbb6a 100644 --- a/assets/voxygen/shaders/ui-frag.glsl +++ b/assets/voxygen/shaders/ui-frag.glsl @@ -71,9 +71,10 @@ void downscale_params(float pos, float scale, out vec2 weights, out vec2 offsets // 4 pixels (within a single dimension) in the sampled texture. So we can't // perfectly compute the contribution of each covered pixel in the sampled // texture with only 2 samples (along each dimension). Thus, we fallback to - // an imperfect technique of of just sampling a 1 pixel length from the - // center on each side. An alternative would be to pre-compute mipmap - // levels that could be sampled from. + // an imperfect technique of just sampling a 1 pixel length from the center + // on each side of the nearest pixel edge. An alternative might be to + // pre-compute mipmap levels that could be sampled from, although this + // could interact poorly with the atlas. if (scale > (1.0 / 3.0)) { // Width of the fragment in terms of pixels in the sampled texture. float width = 1.0 / scale; @@ -87,7 +88,7 @@ void downscale_params(float pos, float scale, out vec2 weights, out vec2 offsets offsets = vec2(split) + vec2(-right_sample_offset, left_sample_offset); weights = vec2(right_len, left_len) / width; } else { - offsets = pos + vec2(-1.0, 1.0); + offsets = round(pos) + vec2(-1.0, 1.0); // We split in the middle so weights for both sides are the same. weights = vec2(0.5); } @@ -140,10 +141,6 @@ vec4 downscale_xy(vec2 uv_pixel, vec2 scale) { vec2 uv1 = vec2(offsets_x[1], offsets_y[0]) / texture_size; vec2 uv2 = vec2(offsets_x[0], offsets_y[1]) / texture_size; vec2 uv3 = vec2(offsets_x[1], offsets_y[1]) / texture_size; - uv0 = uv_pixel / texture_size; - uv1 = uv_pixel / texture_size; - uv2 = uv_pixel / texture_size; - uv3 = uv_pixel / texture_size; vec4 s0 = textureLod(sampler2D(t_tex, s_tex), uv0, 0); vec4 s1 = textureLod(sampler2D(t_tex, s_tex), uv1, 0); vec4 s2 = textureLod(sampler2D(t_tex, s_tex), uv2, 0); @@ -189,7 +186,7 @@ void main() { // Convert to sampled pixel coordinates. vec2 uv_pixel = f_uv * texture_size; - vec4 image_color = vec4(1.0, 0, 0, 1); + vec4 image_color; #ifdef EXPERIMENTAL_UINEARESTSCALING vec2 uv = (floor(uv_pixel) + 0.5) / texture_size; image_color = textureLod(sampler2D(t_tex, s_tex), uv, 0); @@ -209,6 +206,17 @@ void main() { } #endif + // un-premultiply alpha (TODO: we pretend all input images are + // premultiplied for now although they aren't all necessarily) + if (image_color.a > 0.001) { + image_color.rgb /= image_color.a; + } + + // TEMP: Use this to make map a solid color + if (texture_size.x != 1600) { + //image_color = vec4(0, 0, 1, 1); + } + tgt_color = f_color * image_color; // 2D Geometry } else if (f_mode == uint(2)) { diff --git a/voxygen/src/ui/graphic/mod.rs b/voxygen/src/ui/graphic/mod.rs index 859c81b084..6a9dbfd1b6 100644 --- a/voxygen/src/ui/graphic/mod.rs +++ b/voxygen/src/ui/graphic/mod.rs @@ -11,7 +11,6 @@ use common::{figure::Segment, slowjob::SlowJobPool}; use guillotiere::{size2, SimpleAtlasAllocator}; use hashbrown::{hash_map::Entry, HashMap}; use image::{DynamicImage, RgbaImage}; -use pixel_art::resize_pixel_art; use slab::Slab; use std::{hash::Hash, sync::Arc}; use tracing::warn; @@ -184,7 +183,7 @@ impl GraphicCache { // Remove from caches // Maybe make this more efficient if replace graphic is used more often - self.cache_map.retain(|&(key_id, _key_dims), details| { + self.cache_map.retain(|&key_id, details| { // If the entry does not reference id, or it does but we can successfully // invalidate, retain the entry; otherwise, discard this entry completely. key_id != id diff --git a/voxygen/src/ui/graphic/pixel_art.rs b/voxygen/src/ui/graphic/pixel_art.rs index 6ced1a620c..a94034648a 100644 --- a/voxygen/src/ui/graphic/pixel_art.rs +++ b/voxygen/src/ui/graphic/pixel_art.rs @@ -11,10 +11,13 @@ const EPSILON: f32 = 0.0001; // Averaging colors with alpha such that when blending with the background color // the same color will be produced as when the individual colors were blended -// with the background and then averaged +// with the background and then averaged. +// // Say we have two areas that we are combining to form a single pixel // A1 and A2 where these are the fraction of the area of the pixel each color -// contributes to Then if the colors were opaque we would say that the final +// contributes to. +// +// Then if the colors were opaque we would say that the final // color output color o3 is // E1: o3 = A1 * o1 + A2 * o2 // where o1 and o2 are the opaque colors of the two areas @@ -30,7 +33,7 @@ const EPSILON: f32 = 0.0001; // E6: c3 * a3 = A1 * c1 * a1 + A2 * c2 * a2 // E7: b * (1 - a3) = A1 * b * (1 - a1) + A2 * b * (1 - a2) // dropping b from E7 and solving for a3 -// E8: a3 = 1 - A1 * (1 - a1) + A2 * (1 - a2) +// E8: a3 = 1 - A1 * (1 - a1) - A2 * (1 - a2) // we can now calculate the combined alpha value // and E6 can then be solved for c3 // E9: c3 = (A1 * c1 * a1 + A2 * c2 * a2) / a3