Add xbr-lv2-small-details shaders

- Avoid filtering (and detroying) dithering. Improves IQ on games that uses it (genesis mainly).
This commit is contained in:
Hyllian 2022-07-22 15:23:12 -03:00
parent 9854ebe64e
commit 3dcd44534a
3 changed files with 91 additions and 11 deletions

View file

@ -31,13 +31,16 @@ layout(push_constant) uniform Push
{
float XBR_EQ_THRESHOLD;
float XBR_LV2_COEFFICIENT;
float SMALL_DETAILS;
} params;
#pragma parameter XBR_EQ_THRESHOLD "COLOR DISTINCTION THRESHOLD" 0.32 0.0 1.0 0.01
#pragma parameter XBR_LV2_COEFFICIENT "SMOOTHNESS THRESHOLD" 0.3 0.0 1.0 0.1
#pragma parameter SMALL_DETAILS "SMALL DETAILS" 0.0 0.0 1.0 1.0
#define XBR_EQ_THRESHOLD params.XBR_EQ_THRESHOLD
#define XBR_LV2_COEFFICIENT params.XBR_LV2_COEFFICIENT
#define SMALL_DETAILS params.SMALL_DETAILS
layout(std140, set = 0, binding = 0) uniform UBO
{
@ -58,9 +61,11 @@ layout(std140, set = 0, binding = 0) uniform UBO
const vec3 v2f = vec3( 65536, 256, 1); // vec to float encode
const vec4 zip = vec4( 1.0, 2.0, 4.0, 8.0);
const vec4 zip2 = vec4( 16.0, 32.0, 64.0, 128.0);
const vec4 low = vec4( 0.0, 0.0, 0.0, 0.0);
const vec4 high = vec4(255.0, 255.0, 255.0, 255.0);
const vec3 Y = vec3(0.2627, 0.6780, 0.0593);
const vec3 Ysd = vec3( 0.299, 0.587, 0.114);
#pragma stage vertex
layout(location = 0) in vec4 Position;
@ -141,7 +146,14 @@ vec4 diff(vec4 A, vec4 B)
float dist(vec3 A, vec3 B)
{
return dot(abs(A-B), Y);
if (SMALL_DETAILS < 0.5)
{
return dot(abs(A-B), Y);
}
else
{
return dot(abs(A-B), Ysd);
}
}
@ -166,7 +178,14 @@ vec4 neq(mat4x3 A, mat4x3 B)
// Calculate weighted distance among pixels in some directions.
vec4 weighted_distance(mat4x3 a, mat4x3 b, mat4x3 c, mat4x3 d, mat4x3 e, mat4x3 f, mat4x3 g, mat4x3 h)
{
return (dist4(a,b) + dist4(a,c) + dist4(d,e) + dist4(d,f) + 4.0*dist4(g,h));
if (SMALL_DETAILS < 0.5)
{
return (dist4(a,b) + dist4(a,c) + dist4(d,e) + dist4(d,f) + 4.0*dist4(g,h));
}
else
{
return (dist4(a,b) + dist4(a,c) + dist4(d,e) + dist4(d,f) + 4.0*dist4(g,h) - dist4(b,c) - dist4(e,f));
}
}
@ -250,12 +269,17 @@ void main()
vec4 d_fg = dist4(f, g);
vec4 d_hc = dist4(h, c);
float K = (SMALL_DETAILS < 0.5 ? 1.0 : 3.0);
edri = LTE(wd1, wd2) * irlv0;
edr = LT( wd1, wd2) * irlv1 * NOT(edri.yzwx * edri.wxyz);
edr = LT( K*wd1, wd2) * irlv1 * NOT(edri.yzwx * edri.wxyz);
edr_l = LTE( lv2_cf * d_fg, d_hc ) * irlv2l * edr * (NOT(edri.yzwx) * eq(e, c));
edr_u = LTE( lv2_cf * d_hc, d_fg ) * irlv2u * edr * (NOT(edri.wxyz) * eq(e, g));
vec4 info = zip * mat4(edr, edr_l, edr_u, edri);
vec4 px = LTE(dist4(e,f), dist4(e,h));
vec4 info = zip * mat4( edr, edr_l, edr_u, edri);
info += zip2 * mat4(vec4(0.0), vec4(0.0), px, vec4(0.0));
FragColor = remapTo01(info, low, high);
}

View file

@ -126,6 +126,18 @@ vec4 remapFrom01(vec4 v, vec4 low, vec4 high)
return round(mix(low, high, v));
}
vec4 unpack_info(float i)
{
vec4 info;
info.x = round(modf(i/2.0, i));
info.y = round(modf(i/2.0, i));
info.z = round(modf(i/2.0, i));
info.w = i;
return info;
}
/*
mat4 unpack_info(vec4 i)
{
mat4 info;
@ -135,11 +147,26 @@ mat4 unpack_info(vec4 i)
info[3] = i;
return transpose(info);
}*/
mat2x4 unpack_info2(float i)
{
mat2x4 info;
info[0].x = round(modf(i/2.0, i));
info[0].y = round(modf(i/2.0, i));
info[0].z = round(modf(i/2.0, i));
info[0].w = round(modf(i/2.0, i));
info[1].x = round(modf(i/2.0, i));
info[1].y = round(modf(i/2.0, i));
info[1].z = round(modf(i/2.0, i));
info[1].w = i;
return info;
}
void main()
{
vec4 px; // px = pixel, edr = edge detection rule
vec4 edri, edr, edr_l, edr_u, px; // px = pixel, edr = edge detection rule
vec4 fx, fx_l, fx_u; // inequations of straight lines.
vec3 res1, res2;
vec4 fx45i, fx45, fx30, fx60;
@ -178,14 +205,24 @@ void main()
fx45i = LT( Co + Ci, fx );
}
mat4 edr = unpack_info(remapFrom01(texture(Source, vTexCoord), low, high));
vec4 info = texture(Source, vTexCoord);
fx45 = edr[0] * fx45;
fx30 = edr[1] * fx30;
fx60 = edr[2] * fx60;
fx45i = edr[3] * fx45i;
vec4 i = remapFrom01(info, low, high);
px = LTE(dist4(e,f), dist4(e,h));
mat2x4 edx = unpack_info2(i.x);
mat2x4 edy = unpack_info2(i.y);
mat2x4 edz = unpack_info2(i.z);
edr = edx[0];
edr_l = edy[0];
edr_u = edz[0];
edri = unpack_info(i.w);
px = edz[1];
fx45i = edri * fx45i;
fx45 = edr * fx45;
fx30 = edr_l * fx30;
fx60 = edr_u * fx60;
vec4 maximos = max(max(fx30, fx60), max(fx45, fx45i));

View file

@ -0,0 +1,19 @@
shaders = "3"
shader0 = shaders/xbr-lv2-multipass/xbr-lv2-pass0.slang
scale_type0 = "source"
scale0 = "1.000000"
shader1 = shaders/xbr-lv2-multipass/xbr-lv2-pass1.slang
scale_type1 = "source"
scale1 = "3.000000"
shader2 = "shaders/support/b-spline.slang"
filter_linear2 = false
filter_linear0 = "false"
filter_linear1 = "false"
parameters = "SMALL_DETAILS"
SMALL_DETAILS = "1.0"