From 7c1b4b3b19fee5c39e6945dfc65e30bbdac12224 Mon Sep 17 00:00:00 2001 From: Hyllian Date: Sat, 16 Jul 2022 21:03:41 -0300 Subject: [PATCH] Add xbr-lv3-multipass and lv3-9x-multipass - Add xbr-lv3-multipass and xbr-lv3-9x-multipass. Much faster than the standalone versions; - Fix some typo on lv2. --- .../xbr-lv2-multipass/xbr-lv2-pass0.slang | 2 +- .../xbr-lv2-multipass/xbr-lv2-pass1.slang | 38 +- .../xbr-lv3-multipass/xbr-lv3-pass0.slang | 355 +++++++++--------- .../xbr-lv3-multipass/xbr-lv3-pass1.slang | 307 +++++++++------ .../xbr-lv3-multipass/xbr-lv3-pass1b.slang | 260 +++++++++++++ xbr/xbr-lv3-9x-multipass.slangp | 29 ++ xbr/xbr-lv3-multipass.slangp | 19 +- 7 files changed, 677 insertions(+), 333 deletions(-) create mode 100644 xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1b.slang create mode 100644 xbr/xbr-lv3-9x-multipass.slangp diff --git a/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass0.slang b/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass0.slang index ea14c7c..430354d 100644 --- a/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass0.slang +++ b/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass0.slang @@ -232,7 +232,7 @@ void main() vec4 f4_ = h5_.yzwx; irlv0 = diff(e_, f_) * diff(e_, h_); - irlv1 = saturate( irlv0 * ( neq(f,b) * neq(f,c) + neq(h,d) * neq(h,g) + eq(e,i) * (neq(f,f4) * neq(f,i4) + neq(h,h5) * neq(h,i5)) + eq(e,g) + eq(e,c)) ); + irlv1 = irlv0; #ifdef CORNER_B irlv1 = saturate(irlv0 * ( neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c) ) ); diff --git a/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass1.slang b/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass1.slang index 84b3b30..bbaace2 100644 --- a/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass1.slang +++ b/xbr/shaders/xbr-lv2-multipass/xbr-lv2-pass1.slang @@ -126,21 +126,20 @@ vec4 remapFrom01(vec4 v, vec4 low, vec4 high) return round(mix(low, high, v)); } -vec4 unpack_info(float i) +mat4 unpack_info(vec4 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; + mat4 info; + info[0] = round(modf(i/2.0, i)); + info[1] = round(modf(i/2.0, i)); + info[2] = round(modf(i/2.0, i)); + info[3] = i; - return info; + return transpose(info); } void main() { vec4 px; // px = pixel, edr = edge detection rule - vec4 edri, edr, edr_l, edr_u; vec4 fx, fx_l, fx_u; // inequations of straight lines. vec3 res1, res2; vec4 fx45i, fx45, fx30, fx60; @@ -153,9 +152,7 @@ void main() vec3 F = texture(Original, t2.zw).rgb; vec3 H = texture(Original, t1.xw).rgb; - mat4x3 b = mat4x3(B, D, H, F); mat4x3 e = mat4x3(E, E, E, E); - mat4x3 d = mat4x3(D, H, F, B); mat4x3 f = mat4x3(F, B, D, H); mat4x3 h = mat4x3(H, F, B, D); @@ -169,31 +166,24 @@ void main() vec4 deltaL = vec4(0.5, 1.0, 0.5, 1.0) * aa_factor; vec4 deltaU = deltaL.yxwz; - fx45i = saturate( 0.5 + (fx - Co - Ci) / delta ); fx45 = saturate( 0.5 + (fx - Co ) / delta ); fx30 = saturate( 0.5 + (fx_l - Cx ) / deltaL ); fx60 = saturate( 0.5 + (fx_u - Cy ) / deltaU ); + fx45i = saturate( 0.5 + (fx - Co - Ci) / delta ); } else { - fx45i = LT( Co + Ci, fx ); fx45 = LT( Co, fx ); fx30 = LT( Cx, fx_l ); fx60 = LT( Cy, fx_u ); + fx45i = LT( Co + Ci, fx ); } - vec4 info = texture(Source, vTexCoord); + mat4 edr = unpack_info(remapFrom01(texture(Source, vTexCoord), low, high)); - vec4 i = remapFrom01(info, low, high); - - edr = unpack_info(i.x); - edr_l = unpack_info(i.y); - edr_u = unpack_info(i.z); - edri = unpack_info(i.w); - - fx45i = edri*fx45i; - fx45 = edr*fx45; - fx30 = edr_l*fx30; - fx60 = edr_u*fx60; + fx45 = edr[0] * fx45; + fx30 = edr[1] * fx30; + fx60 = edr[2] * fx60; + fx45i = edr[3] * fx45i; px = LTE(dist4(e,f), dist4(e,h)); diff --git a/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang b/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang index 388734a..ce1bdab 100644 --- a/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang +++ b/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang @@ -1,9 +1,9 @@ #version 450 /* - Hyllian's xBR level 3 pass0 Shader + Hyllian's xBR-lv3 - pass0 Shader - Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com + Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,19 +29,40 @@ layout(push_constant) uniform Push { - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; + float XBR_EQ_THRESHOLD; + float XBR_LV2_COEFFICIENT; } 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 + +#define XBR_EQ_THRESHOLD params.XBR_EQ_THRESHOLD +#define XBR_LV2_COEFFICIENT params.XBR_LV2_COEFFICIENT + layout(std140, set = 0, binding = 0) uniform UBO { - mat4 MVP; + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; } global; -#define mul(a,b) (b*a) -#define saturate(c) clamp(c, 0.0, 1.0) +// Uncomment just one of the three params below to choose the corner detection +//#define CORNER_A +//#define CORNER_B +#define CORNER_C + +#define XBR_EQ_THRESHOLD2 0.02 +#define lv2_cf (XBR_LV2_COEFFICIENT + 2.0) +#define saturate(c) clamp(c, 0.0, 1.0) +#define round(X) floor((X)+0.5) + +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); #pragma stage vertex layout(location = 0) in vec4 Position; @@ -58,25 +79,25 @@ layout(location = 7) out vec4 t7; void main() { gl_Position = global.MVP * Position; - vTexCoord = TexCoord * 1.0004; +// vTexCoord = TexCoord; + vTexCoord = TexCoord * 1.0001; - vec2 ps = vec2(1.0) / params.SourceSize.xy; - float dx = ps.x; - float dy = ps.y; + float dx = global.SourceSize.z; + float dy = global.SourceSize.w; - // A1 B1 C1 - // A0 A B C C4 - // D0 D E F F4 - // G0 G H I I4 - // G5 H5 I5 + // A1 B1 C1 + // A0 A B C C4 + // D0 D E F F4 + // G0 G H I I4 + // G5 H5 I5 - t1 = vTexCoord.xxxy + vec4( -dx, 0, dx,-2.0*dy); // A1 B1 C1 - t2 = vTexCoord.xxxy + vec4( -dx, 0, dx, -dy); // A B C - t3 = vTexCoord.xxxy + vec4( -dx, 0, dx, 0); // D E F - t4 = vTexCoord.xxxy + vec4( -dx, 0, dx, dy); // G H I - t5 = vTexCoord.xxxy + vec4( -dx, 0, dx, 2.0*dy); // G5 H5 I5 - t6 = vTexCoord.xyyy + vec4(-2.0*dx,-dy, 0, dy); // A0 D0 G0 - t7 = vTexCoord.xyyy + vec4( 2.0*dx,-dy, 0, dy); // C4 F4 I4 + t1 = vTexCoord.xxxy + vec4( -dx, 0, dx,-2.0*dy); // A1 B1 C1 + t2 = vTexCoord.xxxy + vec4( -dx, 0, dx, -dy); // A B C + t3 = vTexCoord.xxxy + vec4( -dx, 0, dx, 0); // D E F + t4 = vTexCoord.xxxy + vec4( -dx, 0, dx, dy); // G H I + t5 = vTexCoord.xxxy + vec4( -dx, 0, dx, 2.0*dy); // G5 H5 I5 + t6 = vTexCoord.xyyy + vec4(-2.0*dx,-dy, 0, dy); // A0 D0 G0 + t7 = vTexCoord.xyyy + vec4( 2.0*dx,-dy, 0, dy); // C4 F4 I4 } #pragma stage fragment @@ -91,200 +112,180 @@ layout(location = 7) in vec4 t7; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; -const float coef = 2.0; -const float cf = 4.0; -const vec4 eq_threshold = vec4(15.0, 15.0, 15.0, 15.0); -const float y_weight = 48.0; -const float u_weight = 7.0; -const float v_weight = 6.0; -const mat3 yuv = mat3(0.299, 0.587, 0.114, -0.169, -0.331, 0.499, 0.499, -0.418, -0.0813); -const mat3 yuv_weighted = mat3(y_weight*yuv[0], u_weight*yuv[1], v_weight*yuv[2]); -const vec4 bin1 = vec4( 1.0, 2.0, 4.0, 8.0); -const vec4 bin2 = vec4(16.0, 32.0, 64.0, 128.0); -const vec4 maximo = vec4(255.0, 255.0, 255.0, 255.0); - -vec4 df(vec4 A, vec4 B) +vec4 remapTo01(vec4 v, vec4 low, vec4 high) { - return vec4(abs(A-B)); + return saturate((v - low)/(high-low)); } -vec4 remapTo01(vec4 v, vec4 high) +// Return if A components are less than or equal B ones. +vec4 LTE(vec4 A, vec4 B) { - return (v/high); + return step(A, B); } -vec4 remapFrom01(vec4 v, vec4 high) +// Return if A components are less than B ones. +vec4 LT(vec4 A, vec4 B) { - return (high*v + vec4(0.5, 0.5, 0.5, 0.5)); + return vec4(lessThan(A, B)); } -bvec4 eq(vec4 A, vec4 B) +// Return logically inverted vector components. BEWARE: Only works with 0.0 or 1.0 components. +vec4 NOT(vec4 A) { - return lessThan(df(A, B) , eq_threshold); + return (vec4(1.0) - A); +} + +// Compare two vectors and return their components are different. +vec4 diff(vec4 A, vec4 B) +{ + return vec4(notEqual(A, B)); +} + +float dist(vec3 A, vec3 B) +{ + return dot(abs(A-B), Y); } -vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) +// Calculate color distance between two vectors of four pixels +vec4 dist4(mat4x3 A, mat4x3 B) { - return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h)); + return vec4(dist(A[0],B[0]), dist(A[1],B[1]), dist(A[2],B[2]), dist(A[3],B[3])); } -bvec4 and(bvec4 A, bvec4 B) +// Tests if color components are under a threshold. In this case they are considered 'equal'. +vec4 eq(mat4x3 A, mat4x3 B) { - return bvec4(A.x && B.x, A.y && B.y, A.z && B.z, A.w && B.w); + return (step(dist4(A, B), vec4(XBR_EQ_THRESHOLD))); } -bvec4 or(bvec4 A, bvec4 B) +vec4 eq2(mat4x3 A, mat4x3 B) { - return bvec4(A.x || B.x, A.y || B.y, A.z || B.z, A.w || B.w); + return (step(dist4(A, B), vec4(XBR_EQ_THRESHOLD2))); +} + +// Determine if two vector components are NOT equal based on a threshold. +vec4 neq(mat4x3 A, mat4x3 B) +{ + return (vec4(1.0, 1.0, 1.0, 1.0) - eq(A, 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)); } -#define FILTRO(EDR0, EDR, LEFT, UP, LEFT3, UP3, PX0, PX3, PX1, LIN0, LIN3, LIN1, PX)\ - if (LEFT && (!UP))\ - {\ - PX0 = bvec2( 0, PX);\ - PX3 = bvec2(PX, 1);\ - if (LEFT3)\ - {\ - LIN0 = bvec4(0, 1, 0, 0);\ - LIN3 = bvec4(1, 0, 0, 0);\ - }\ - else \ - {\ - LIN0 = bvec4(0, 0, 1, 0);\ - LIN3 = bvec4(0, 1, 1, 0);\ - }\ - }\ - else if (UP && (!LEFT))\ - {\ - PX0 = bvec2(false, PX);\ - PX1 = bvec2( !PX, false);\ - if (UP3)\ - {\ - LIN0 = bvec4(0, 1, 0, 1);\ - LIN1 = bvec4(1, 0, 0, 1);\ - }\ - else \ - {\ - LIN0 = bvec4(0, 0, 1, 1);\ - LIN1 = bvec4(0, 1, 1, 1);\ - }\ - }\ - else if (EDR)\ - {\ - LEFT = UP = LEFT3 = UP3 = false;\ - PX0 = bvec2(false, PX);\ - LIN0 = bvec4(0, 0, 0, 1);\ - }\ - else if (EDR0)\ - {\ - LEFT = UP = LEFT3 = UP3 = false;\ - PX0 = bvec2(false, PX);\ - LIN0 = bvec4(0, 0, 0, 0);\ - }\ void main() { - bvec4 edr, edr_left, edr_up, edr3_left, edr3_up, px; // px = pixel, edr = edge detection rule - bvec4 interp_restriction_lv1, interp_restriction_lv2_left, interp_restriction_lv2_up; - bvec4 interp_restriction_lv3_left, interp_restriction_lv3_up; - bvec2 px0, px1, px2, px3; - bvec4 lin0, lin1, lin2, lin3; + vec4 edri, edr, edr_l, edr_u, edr3_l, edr3_u; // edr = edge detection rule, l = left, u = up. + vec4 irlv0, irlv1, irlv2l, irlv2u, irlv3l, irlv3u; // ir = interpolation restriction + vec3 A1 = texture(Source, t1.xw).rgb; + vec3 B1 = texture(Source, t1.yw).rgb; + vec3 C1 = texture(Source, t1.zw).rgb; - vec3 A1 = texture(Source, t1.xw).rgb; - vec3 B1 = texture(Source, t1.yw).rgb; - vec3 C1 = texture(Source, t1.zw).rgb; + vec3 A = texture(Source, t2.xw).rgb; + vec3 B = texture(Source, t2.yw).rgb; + vec3 C = texture(Source, t2.zw).rgb; - vec3 A = texture(Source, t2.xw).rgb; - vec3 B = texture(Source, t2.yw).rgb; - vec3 C = texture(Source, t2.zw).rgb; + vec3 D = texture(Source, t3.xw).rgb; + vec3 E = texture(Source, t3.yw).rgb; + vec3 F = texture(Source, t3.zw).rgb; - vec3 D = texture(Source, t3.xw).rgb; - vec3 E = texture(Source, t3.yw).rgb; - vec3 F = texture(Source, t3.zw).rgb; + vec3 G = texture(Source, t4.xw).rgb; + vec3 H = texture(Source, t4.yw).rgb; + vec3 I = texture(Source, t4.zw).rgb; - vec3 G = texture(Source, t4.xw).rgb; - vec3 H = texture(Source, t4.yw).rgb; - vec3 I = texture(Source, t4.zw).rgb; + vec3 G5 = texture(Source, t5.xw).rgb; + vec3 H5 = texture(Source, t5.yw).rgb; + vec3 I5 = texture(Source, t5.zw).rgb; - vec3 G5 = texture(Source, t5.xw).rgb; - vec3 H5 = texture(Source, t5.yw).rgb; - vec3 I5 = texture(Source, t5.zw).rgb; + vec3 A0 = texture(Source, t6.xy).rgb; + vec3 D0 = texture(Source, t6.xz).rgb; + vec3 G0 = texture(Source, t6.xw).rgb; - vec3 A0 = texture(Source, t6.xy).rgb; - vec3 D0 = texture(Source, t6.xz).rgb; - vec3 G0 = texture(Source, t6.xw).rgb; + vec3 C4 = texture(Source, t7.xy).rgb; + vec3 F4 = texture(Source, t7.xz).rgb; + vec3 I4 = texture(Source, t7.xw).rgb; - vec3 C4 = texture(Source, t7.xy).rgb; - vec3 F4 = texture(Source, t7.xz).rgb; - vec3 I4 = texture(Source, t7.xw).rgb; + mat4x3 b = mat4x3(B, D, H, F); + mat4x3 c = mat4x3(C, A, G, I); + mat4x3 d = mat4x3(D, H, F, B); + mat4x3 e = mat4x3(E, E, E, E); + mat4x3 f = mat4x3(F, B, D, H); + mat4x3 g = mat4x3(G, I, C, A); + mat4x3 h = mat4x3(H, F, B, D); + mat4x3 i = mat4x3(I, C, A, G); - vec4 b = mul( mat4x3(B, D, H, F), yuv_weighted[0] ); - vec4 c = mul( mat4x3(C, A, G, I), yuv_weighted[0] ); - vec4 e = mul( mat4x3(E, E, E, E), yuv_weighted[0] ); - vec4 d = b.yzwx; - vec4 f = b.wxyz; - vec4 g = c.zwxy; - vec4 h = b.zwxy; - vec4 i = c.wxyz; + mat4x3 i4 = mat4x3(I4, C1, A0, G5); + mat4x3 i5 = mat4x3(I5, C4, A1, G0); + mat4x3 h5 = mat4x3(H5, F4, B1, D0); + mat4x3 f4 = mat4x3(F4, B1, D0, H5); - vec4 i4 = mul( mat4x3(I4, C1, A0, G5), yuv_weighted[0] ); - vec4 i5 = mul( mat4x3(I5, C4, A1, G0), yuv_weighted[0] ); - vec4 h5 = mul( mat4x3(H5, F4, B1, D0), yuv_weighted[0] ); - vec4 f4 = h5.yzwx; + mat4x3 c4 = mat4x3(C4, A1, G0, I5); + mat4x3 g5 = mat4x3(G5, I4, C1, A0); - vec4 c1 = i4.yzwx; - vec4 g0 = i5.wxyz; - vec4 b1 = h5.zwxy; - vec4 d0 = h5.wxyz; + mat4x3 c1 = mat4x3(C1, A0, G5, I4); + mat4x3 g0 = mat4x3(G0, I5, C4, A1); + mat4x3 b1 = mat4x3(B1, D0, H5, F4); + mat4x3 d0 = mat4x3(D0, H5, F4, B1); + vec4 b_ = v2f * b; + vec4 c_ = v2f * c; + vec4 d_ = b_.yzwx; + vec4 e_ = v2f * e; + vec4 f_ = b_.wxyz; + vec4 g_ = c_.zwxy; + vec4 h_ = b_.zwxy; + vec4 i_ = c_.wxyz; - bvec4 interp_restriction_lv0 = and(notEqual(e,f) , notEqual(e,h)); - bvec4 comp1 = and(not(eq(h,h5)) , not(eq(h,i5))); - bvec4 comp2 = and(not(eq(h,d)) , not(eq(h,g))); - bvec4 comp3 = and(not(eq(f,f4)) , not(eq(f,i4))); - bvec4 comp4 = and( not(eq(f,b)) , not(eq(f,c)) ); - bvec4 comp5 = and(eq(e,i) , or(comp3 , comp1)); - interp_restriction_lv1 = or( comp4 , or(comp2 , or(comp5 , or(eq(e,g) , eq(e,c))))); - interp_restriction_lv2_left = and(notEqual(e,g) , notEqual(d,g)); - interp_restriction_lv2_up = and(notEqual(e,c) , notEqual(b,c)); - interp_restriction_lv3_left = and(notEqual(e,g0) , notEqual(d0,g0)); - interp_restriction_lv3_up = and(notEqual(e,c1) , notEqual(b1,c1)); + vec4 i4_ = v2f * i4; + vec4 i5_ = v2f * i5; + vec4 h5_ = v2f * h5; + vec4 f4_ = h5_.yzwx; - bvec4 edr0 = and(lessThan(weighted_distance( e, c, g, i, h5, f4, h, f) , weighted_distance( h, d, i5, f, i4, b, e, i)) , interp_restriction_lv0); + vec4 c4_ = i5_.yzwx; + vec4 g5_ = i4_.wxyz; - edr = and(edr0 , interp_restriction_lv1); - edr_left = and(lessThanEqual((coef*df(f,g)) , df(h,c)) , and(interp_restriction_lv2_left , edr)); - edr_up = and(greaterThanEqual(df(f,g) , (coef*df(h,c))) , and(interp_restriction_lv2_up , edr)); - edr3_left = and(lessThanEqual((cf*df(f,g0)) , df(h,c1)) , and(interp_restriction_lv3_left , edr_left)); - edr3_up = and(greaterThanEqual(df(f,g0) , (cf*df(h,c1))) , and(interp_restriction_lv3_up , edr_up)); + vec4 c1_ = i4_.yzwx; + vec4 g0_ = i5_.wxyz; + vec4 b1_ = h5_.zwxy; + vec4 d0_ = h5_.wxyz; - px = lessThanEqual(df(e,f) , df(e,h)); + irlv0 = diff(e_, f_) * diff(e_, h_); + irlv1 = irlv0; - lin0 = lin1 = lin2 = lin3 = bvec4(1, 1, 1, 1); +#ifdef CORNER_B + irlv1 = saturate(irlv0 * ( neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c) ) ); +#endif +#ifdef CORNER_C + irlv1 = saturate(irlv0 * ( neq(f,b) * neq(f,c) + neq(h,d) * neq(h,g) + eq(e,i) * (neq(f,f4) * neq(f,i4) + neq(h,h5) * neq(h,i5)) + eq(e,g) + eq(e,c)) ); +#endif - FILTRO(edr0.x, edr.x, edr_left.x, edr_up.x, edr3_left.x, edr3_up.x, px0, px3, px1, lin0, lin3, lin1, px.x); - FILTRO(edr0.y, edr.y, edr_left.y, edr_up.y, edr3_left.y, edr3_up.y, px1, px0, px2, lin1, lin0, lin2, px.y); - FILTRO(edr0.z, edr.z, edr_left.z, edr_up.z, edr3_left.z, edr3_up.z, px2, px1, px3, lin2, lin1, lin3, px.z); - FILTRO(edr0.w, edr.w, edr_left.w, edr_up.w, edr3_left.w, edr3_up.w, px3, px2, px0, lin3, lin2, lin0, px.w); + irlv2l = diff(e_, g_) * diff(d_, g_); + irlv2u = diff(e_, c_) * diff(b_, c_); + irlv3l = eq2(g,g0) * diff(d0_,g0_) * eq(e,c4); + irlv3u = eq2(c,c1) * diff(b1_,c1_) * eq(e,g5); - vec4 info = mul( - bin1, mat4( - edr3_left, - edr3_up, - px0.x, px1.x, px2.x, px3.x, - px0.y, px1.y, px2.y, px3.y - ) - ); + vec4 wd1 = weighted_distance( e, c, g, i, h5, f4, h, f ); + vec4 wd2 = weighted_distance( h, d, i5, f, i4, b, e, i ); - info += mul(bin2, mat4( - lin0.x, lin1.x, lin2.x, lin3.x, - lin0.y, lin1.y, lin2.y, lin3.y, - lin0.z, lin1.z, lin2.z, lin3.z, - lin0.w, lin1.w, lin2.w, lin3.w - ) - ); - - FragColor = vec4(remapTo01(info, maximo)); -} \ No newline at end of file + vec4 d_fg = dist4(f, g); + vec4 d_hc = dist4(h, c); + + edri = LTE(wd1, wd2) * irlv0; + edr = LT( 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)); + edr3_l = irlv3l * edr_l; + edr3_u = irlv3u * edr_u; + + vec4 px = LTE(dist4(e,f), dist4(e,h)); + + vec4 info = zip * mat4( edr, edr_l, edr_u, edri); + info += zip2 * mat4(edr3_l, edr3_u, px, vec4(0.0)); + + FragColor = remapTo01(info, low, high); +} diff --git a/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang b/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang index 3d1c4df..f44c194 100644 --- a/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang +++ b/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang @@ -1,9 +1,9 @@ #version 450 /* - Hyllian's xBR level 3 pass1 Shader + Hyllian's xBR-lv3 - pass1 Shader - Copyright (C) 2011-2015 Hyllian - sergiogdb@gmail.com + Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,180 +24,237 @@ THE SOFTWARE. */ -#define round(X) floor((X)+0.5) -#define saturate(c) clamp(c, 0.0, 1.0) -#define mul(a,b) (b*a) - layout(push_constant) uniform Push { - vec4 SourceSize; - vec4 OriginalSize; - vec4 OutputSize; - uint FrameCount; + float XBR_BLENDING; } params; +#pragma parameter XBR_BLENDING "BLENDING [ NOBLEND | AA ]" 1.0 0.0 1.0 1.0 + +#define XBR_BLENDING params.XBR_BLENDING + layout(std140, set = 0, binding = 0) uniform UBO { - mat4 MVP; + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; } global; +#define saturate(c) clamp(c, 0.0, 1.0) +#define round(X) floor((X)+0.5) + +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 vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 ); +const vec4 Bo = vec4( 1.0, 1.0, -1.0,-1.0 ); +const vec4 Co = vec4( 1.5, 0.5, -0.5, 0.5 ); +const vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 ); +const vec4 Bx = vec4( 0.5, 2.0, -0.5,-2.0 ); +const vec4 Cx = vec4( 1.0, 1.0, -0.5, 0.0 ); +const vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 ); +const vec4 By = vec4( 2.0, 0.5, -2.0,-0.5 ); +const vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 ); +const vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25); + +const vec4 Az = vec4( 6.0, -2.0, -6.0, 2.0 ); +const vec4 Bz = vec4( 2.0, 6.0, -2.0, -6.0 ); +const vec4 Cz = vec4( 5.0, 3.0, -3.0, -1.0 ); +const vec4 Aw = vec4( 2.0, -6.0, -2.0, 6.0 ); +const vec4 Bw = vec4( 6.0, 2.0, -6.0,-2.0 ); +const vec4 Cw = vec4( 5.0, -1.0, -3.0, 3.0 ); + #pragma stage vertex layout(location = 0) in vec4 Position; layout(location = 1) in vec2 TexCoord; layout(location = 0) out vec2 vTexCoord; layout(location = 1) out vec4 t1; -layout(location = 2) out vec2 delta; +layout(location = 2) out vec4 t2; +layout(location = 3) out float aa_factor; void main() { gl_Position = global.MVP * Position; - vTexCoord = TexCoord * 1.0004; +// vTexCoord = TexCoord; + vTexCoord = TexCoord * 1.0001; - vec2 ps = vec2(1.0/params.OriginalSize.x, 1.0/params.OriginalSize.y); - float dx = ps.x; - float dy = ps.y; + float dx = global.SourceSize.z; + float dy = global.SourceSize.w; - // A3 B3 C3 - // A1 B1 C1 - //A2 A0 A B C C4 C6 - //D2 D0 D E F F4 F6 - //G2 G0 G H I I4 I6 - // G5 H5 I5 - // G7 H7 I7 + // A1 B1 C1 + // A0 A B C C4 + // D0 D E F F4 + // G0 G H I I4 + // G5 H5 I5 - t1 = vec4(dx, 0., 0., dy); // F H - delta = vec2(params.SourceSize.x/params.OutputSize.x, 0.5*params.SourceSize.x/params.OutputSize.x); // Delta is the thickness of interpolation + aa_factor = 2.0*global.OutputSize.z * global.SourceSize.x; + + t1 = vTexCoord.xyyy + vec4( 0, -dy, 0, dy); // B + t2 = vTexCoord.xxxy + vec4( -dx, 0, dx, 0); //D E F + // H } #pragma stage fragment layout(location = 0) in vec2 vTexCoord; layout(location = 1) in vec4 t1; -layout(location = 2) in vec2 delta; +layout(location = 2) in vec4 t2; +layout(location = 3) in float aa_factor; layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; layout(set = 0, binding = 3) uniform sampler2D Original; -const mat2x4 sym_vectors = mat2x4(1., 1., -1., -1., 1., -1., -1., 1.); - -const vec3 lines[12] = { - vec3(1.0, 1.0, 0.75), - vec3(1.0, 1.0, 0.5), - vec3(2.0, 1.0, 0.5), - vec3(1.0, 2.0, 0.5), - vec3(3.0, 1.0, 0.5), - vec3(1.0, 3.0, 0.5), - - vec3(-1.0, 2.0, 0.5), - vec3(2.0, -1.0, 0.5), - vec3(-1.0, 3.0, 0.5), - vec3(3.0, -1.0, 0.5), - - vec3(3.0, 1.0, 1.5), - vec3(1.0, 3.0, 1.5) -}; - - -float remapFrom01(float v, float high) +// Return if A components are less than or equal B ones. +vec4 LTE(vec4 A, vec4 B) { - return (high*v + 0.5); + return step(A, B); } - -vec3 remapFrom01(vec3 v, vec3 low, vec3 high) +// Return if A components are less than B ones. +vec4 LT(vec4 A, vec4 B) { - return round(mix(low, high, v)); + return vec4(lessThan(A, B)); +} + +float dist(vec3 A, vec3 B) +{ + return dot(abs(A-B), Y); +} + +// Calculate color distance between two vectors of four pixels +vec4 dist4(mat4x3 A, mat4x3 B) +{ + return vec4(dist(A[0],B[0]), dist(A[1],B[1]), dist(A[2],B[2]), dist(A[3],B[3])); +} + +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; + 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; + return info; +} + +/* +mat4 unpack_info(vec4 i) +{ + mat4 info; + info[0] = round(modf(i/2.0, i)); + info[1] = round(modf(i/2.0, i)); + info[2] = round(modf(i/2.0, 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() { - vec2 px; // px = pixel to blend - float pxr, pxd, line, edr3_nrl, edr3_ndu; + vec4 edri, edr, edr_l, edr_u, edr3_l, edr3_u, px; // px = pixel, edr = edge detection rule + vec4 fx, fx_l, fx_u, fx3_l, fx3_u; // inequations of straight lines. + vec3 res1, res2; + vec4 fx45i, fx45, fx30, fx60, fx15, fx75; - vec2 pos = fract(vTexCoord*params.SourceSize.xy)-vec2(0.5, 0.5); // pos = pixel position - vec2 dir = sign(pos); // dir = pixel direction + vec2 fp = fract(vTexCoord*global.SourceSize.xy); - vec2 g1 = dir*( saturate(-dir.y*dir.x)*t1.zw + saturate( dir.y*dir.x)*t1.xy); - vec2 g2 = dir*( saturate( dir.y*dir.x)*t1.zw + saturate(-dir.y*dir.x)*t1.xy); + vec3 B = texture(Original, t1.xy).rgb; + vec3 D = texture(Original, t2.xw).rgb; + vec3 E = texture(Original, t2.yw).rgb; + vec3 F = texture(Original, t2.zw).rgb; + vec3 H = texture(Original, t1.xw).rgb; - vec3 F = texture(Original, vTexCoord +g1).xyz; - vec3 B = texture(Original, vTexCoord -g2).xyz; - vec3 D = texture(Original, vTexCoord -g1).xyz; - vec3 H = texture(Original, vTexCoord +g2).xyz; - vec3 E = texture(Original, vTexCoord ).xyz; + mat4x3 e = mat4x3(E, E, E, E); + mat4x3 f = mat4x3(F, B, D, H); + mat4x3 h = mat4x3(H, F, B, D); - vec3 F4 = texture(Original, vTexCoord +2.0*g1).xyz; - vec3 I = texture(Original, vTexCoord +g1+g2).xyz; - vec3 H5 = texture(Original, vTexCoord +2.0*g2).xyz; + // These inequations define the line below which interpolation occurs. + fx = (Ao*fp.y+Bo*fp.x); + fx_l = (Ax*fp.y+Bx*fp.x); + fx_u = (Ay*fp.y+By*fp.x); + fx3_l = ( Az*fp.y + Bz*fp.x ); + fx3_u = ( Aw*fp.y + Bw*fp.x ); - vec4 icomp = round(saturate(mul(dir, sym_vectors))); // choose info component - float info = remapFrom01(dot(texture(Source, vTexCoord ), icomp), 255.0); // retrieve 1st pass info - float info_nr = remapFrom01(dot(texture(Source, vTexCoord+g1), icomp), 255.0); // 1st pass info from neighbor r - float info_nd = remapFrom01(dot(texture(Source, vTexCoord+g2), icomp), 255.0); // 1st pass info from neighbor d + if (XBR_BLENDING == 1.0) { + vec4 delta = vec4(aa_factor); + vec4 deltaL = vec4(0.5, 1.0, 0.5, 1.0) * aa_factor; + vec4 deltaU = deltaL.yxwz; - modf(info/2.0f, info); // discard info - modf(info/2.0f, info); // discard info - px.x = round(modf(info/2.0, info)); - px.y = round(modf(info/2.0, info)); + fx45 = saturate( 0.5 + (fx - Co ) / delta ); + fx30 = saturate( 0.5 + (fx_l - Cx ) / deltaL ); + fx60 = saturate( 0.5 + (fx_u - Cy ) / deltaU ); + fx45i = saturate( 0.5 + (fx - Co - Ci) / delta ); + fx15 = saturate( 0.5 + (fx3_l - Cz ) / deltaL ); + fx75 = saturate( 0.5 + (fx3_u - Cw ) / deltaU ); + } + else { + fx45 = LT( Co, fx ); + fx30 = LT( Cx, fx_l ); + fx60 = LT( Cy, fx_u ); + fx45i = LT( Co + Ci, fx ); + fx15 = LT( Cz, fx3_l ); + fx75 = LT( Cw, fx3_u ); + } - vec4 flags = unpack_info(info); // retrieve 1st pass flags + vec4 info = texture(Source, vTexCoord); - edr3_nrl = round(modf(info_nr/2.0, info_nr)); - modf(info_nr/2.0, info_nr); // discard info_nr - modf(info_nr/2.0, info_nr); // discard info_nr - pxr = round(modf(info_nr/2.0, info_nr)); + vec4 i = remapFrom01(info, low, high); - modf(info_nd/2.0, info_nd); // discard info_nd - edr3_ndu = round(modf(info_nd/2.0, info_nd)); - modf(info_nd/2.0, info_nd); // discard info_nd - pxd = round(modf(info_nd/2.0, info_nd)); + mat2x4 edx = unpack_info2(i.x); + mat2x4 edy = unpack_info2(i.y); + mat2x4 edz = unpack_info2(i.z); - float aux = round(dot(vec4(8.0, 4.0, 2.0, 1.0), flags)); - vec3 slep; + edr = edx[0]; + edr_l = edy[0]; + edr_u = edz[0]; + edri = unpack_info(i.w); + edr3_l = edx[1]; + edr3_u = edy[1]; + px = edz[1]; + + fx45i = edri * fx45i; + fx45 = edr * fx45; + fx30 = edr_l * fx30; + fx60 = edr_u * fx60; + fx15 = edr3_l * fx15; + fx75 = edr3_u * fx75; + + vec4 maximos = max(max(max(fx15, fx30), max(fx60, fx75)), max(fx45, fx45i)); + + res1 = mix(E, mix(H, F, px.x), maximos.x); + res2 = mix(E, mix(B, D, px.z), maximos.z); + + vec3 res1a = mix(res1, res2, step(dist(E, res1), dist(E, res2))); + + res1 = mix(E, mix(F, B, px.y), maximos.y); + res2 = mix(E, mix(D, H, px.w), maximos.w); + + vec3 res1b = mix(res1, res2, step(dist(E, res1), dist(E, res2))); + + vec3 res = mix(res1a, res1b, step(dist(E, res1a), dist(E, res1b))); - if (aux >= 6.0) - { - slep = (aux==6.0 ? lines[6] : (aux==7.0 ? lines[7] : (aux==8.0 ? lines[8] : (aux==9.0 ? lines[9] : (aux==10.0 ? lines[10] : lines[11]))))); - } - else - { - slep = (aux==0.0 ? lines[0] : (aux==1.0 ? lines[1] : (aux==2.0 ? lines[2] : (aux==3.0 ? lines[3] : (aux==4.0 ? lines[4] : lines[5]))))); - } - - - vec2 fp = (dir.x*dir.y) > 0.0 ? abs(pos) : abs(pos.yx); - - vec3 fp1 = vec3(fp.yx, -1); - - vec3 color = E; - float fx; - - if (aux < 10.0) - { - fx = saturate(dot(fp1, slep)/(2.*delta.x)+0.5); - color = mix(E, mix(mix(H, F, px.y), mix(D, B, px.y), px.x), fx); // interpolate if there's edge - } - else if (edr3_nrl == 1.0) - { - fx = saturate(dot(fp1, lines[10])/(2.*delta.x)+0.5); - color = mix(E, mix(I, F4, pxr), fx); // interpolate if there's edge - } - else if (edr3_ndu == 1.0) - { - fx = saturate(dot(fp1, lines[11])/(2.*delta.x)+0.5); - color = mix(E, mix(H5, I, pxd), fx); // interpolate if there's edge - } - - FragColor = vec4(color, 1.0); -} \ No newline at end of file + FragColor = vec4(res, 1.0); +} diff --git a/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1b.slang b/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1b.slang new file mode 100644 index 0000000..bf6fffd --- /dev/null +++ b/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1b.slang @@ -0,0 +1,260 @@ +#version 450 + +/* + Hyllian's xBR-lv3 - pass1b Shader + + Copyright (C) 2011-2022 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +layout(push_constant) uniform Push +{ + float XBR_BLENDING; +} params; + +#pragma parameter XBR_BLENDING "BLENDING [ NOBLEND | AA ]" 1.0 0.0 1.0 1.0 + +#define XBR_BLENDING params.XBR_BLENDING + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; +} global; + +#define saturate(c) clamp(c, 0.0, 1.0) +#define round(X) floor((X)+0.5) + +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 vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 ); +const vec4 Bo = vec4( 1.0, 1.0, -1.0,-1.0 ); +const vec4 Co = vec4( 1.5, 0.5, -0.5, 0.5 ); +const vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 ); +const vec4 Bx = vec4( 0.5, 2.0, -0.5,-2.0 ); +const vec4 Cx = vec4( 1.0, 1.0, -0.5, 0.0 ); +const vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 ); +const vec4 By = vec4( 2.0, 0.5, -2.0,-0.5 ); +const vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 ); +const vec4 Ci = vec4(0.25, 0.25, 0.25, 0.25); + +const vec4 Az = vec4( 6.0, -2.0, -6.0, 2.0 ); +const vec4 Bz = vec4( 2.0, 6.0, -2.0, -6.0 ); +const vec4 Cz = vec4( 5.0, 3.0, -3.0, -1.0 ); +const vec4 Aw = vec4( 2.0, -6.0, -2.0, 6.0 ); +const vec4 Bw = vec4( 6.0, 2.0, -6.0,-2.0 ); +const vec4 Cw = vec4( 5.0, -1.0, -3.0, 3.0 ); + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; +layout(location = 1) out vec4 t1; +layout(location = 2) out vec4 t2; +layout(location = 3) out float aa_factor; + +void main() +{ + gl_Position = global.MVP * Position; +// vTexCoord = TexCoord; + vTexCoord = TexCoord * 1.0001; + + float dx = global.SourceSize.z; + float dy = global.SourceSize.w; + + // A1 B1 C1 + // A0 A B C C4 + // D0 D E F F4 + // G0 G H I I4 + // G5 H5 I5 + + aa_factor = 2.0*global.OutputSize.z * global.SourceSize.x; + + t1 = vTexCoord.xyyy + vec4( 0, -dy, 0, dy); // B + t2 = vTexCoord.xxxy + vec4( -dx, 0, dx, 0); //D E F + // H +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec4 t1; +layout(location = 2) in vec4 t2; +layout(location = 3) in float aa_factor; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D xbr3x; + +// Return if A components are less than or equal B ones. +vec4 LTE(vec4 A, vec4 B) +{ + return step(A, B); +} + +// Return if A components are less than B ones. +vec4 LT(vec4 A, vec4 B) +{ + return vec4(lessThan(A, B)); +} + +float dist(vec3 A, vec3 B) +{ + return dot(abs(A-B), Y); +} + +// Calculate color distance between two vectors of four pixels +vec4 dist4(mat4x3 A, mat4x3 B) +{ + return vec4(dist(A[0],B[0]), dist(A[1],B[1]), dist(A[2],B[2]), dist(A[3],B[3])); +} + +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; + info[0] = round(modf(i/2.0, i)); + info[1] = round(modf(i/2.0, i)); + info[2] = round(modf(i/2.0, 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 edri, edr, edr_l, edr_u, edr3_l, edr3_u, px; // px = pixel, edr = edge detection rule + vec4 fx, fx_l, fx_u, fx3_l, fx3_u; // inequations of straight lines. + vec3 res1, res2; + vec4 fx45i, fx45, fx30, fx60, fx15, fx75; + + vec2 fp = fract(vTexCoord*global.SourceSize.xy); + + vec3 B = texture(xbr3x, t1.xy).rgb; + vec3 D = texture(xbr3x, t2.xw).rgb; + vec3 E = texture(xbr3x, t2.yw).rgb; + vec3 F = texture(xbr3x, t2.zw).rgb; + vec3 H = texture(xbr3x, t1.xw).rgb; + + mat4x3 e = mat4x3(E, E, E, E); + mat4x3 f = mat4x3(F, B, D, H); + mat4x3 h = mat4x3(H, F, B, D); + + // These inequations define the line below which interpolation occurs. + fx = (Ao*fp.y+Bo*fp.x); + fx_l = (Ax*fp.y+Bx*fp.x); + fx_u = (Ay*fp.y+By*fp.x); + fx3_l = ( Az*fp.y + Bz*fp.x ); + fx3_u = ( Aw*fp.y + Bw*fp.x ); + + if (XBR_BLENDING == 1.0) { + vec4 delta = vec4(aa_factor); + vec4 deltaL = vec4(0.5, 1.0, 0.5, 1.0) * aa_factor; + vec4 deltaU = deltaL.yxwz; + + fx45 = saturate( 0.5 + (fx - Co ) / delta ); + fx30 = saturate( 0.5 + (fx_l - Cx ) / deltaL ); + fx60 = saturate( 0.5 + (fx_u - Cy ) / deltaU ); + fx45i = saturate( 0.5 + (fx - Co - Ci) / delta ); + fx15 = saturate( 0.5 + (fx3_l - Cz ) / deltaL ); + fx75 = saturate( 0.5 + (fx3_u - Cw ) / deltaU ); + } + else { + fx45 = LT( Co, fx ); + fx30 = LT( Cx, fx_l ); + fx60 = LT( Cy, fx_u ); + fx45i = LT( Co + Ci, fx ); + fx15 = LT( Cz, fx3_l ); + fx75 = LT( Cw, fx3_u ); + } + + vec4 info = texture(Source, vTexCoord); + + vec4 i = remapFrom01(info, low, high); + + 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); + edr3_l = edx[1]; + edr3_u = edy[1]; + px = edz[1]; + + fx45i = edri * fx45i; + fx45 = edr * fx45; + fx30 = edr_l * fx30; + fx60 = edr_u * fx60; + fx15 = edr3_l * fx15; + fx75 = edr3_u * fx75; + + vec4 maximos = max(max(max(fx15, fx30), max(fx60, fx75)), max(fx45, fx45i)); + + res1 = mix(E, mix(H, F, px.x), maximos.x); + res2 = mix(E, mix(B, D, px.z), maximos.z); + + vec3 res1a = mix(res1, res2, step(dist(E, res1), dist(E, res2))); + + res1 = mix(E, mix(F, B, px.y), maximos.y); + res2 = mix(E, mix(D, H, px.w), maximos.w); + + vec3 res1b = mix(res1, res2, step(dist(E, res1), dist(E, res2))); + + vec3 res = mix(res1a, res1b, step(dist(E, res1a), dist(E, res1b))); + + + FragColor = vec4(res, 1.0); +} diff --git a/xbr/xbr-lv3-9x-multipass.slangp b/xbr/xbr-lv3-9x-multipass.slangp new file mode 100644 index 0000000..b60198f --- /dev/null +++ b/xbr/xbr-lv3-9x-multipass.slangp @@ -0,0 +1,29 @@ +shaders = "5" + +shader0 = shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang +filter_linear0 = "false" +scale_type0 = "source" +scale0 = "1.000000" + +shader1 = shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang +filter_linear1 = "false" +scale_type1 = "source" +scale1 = "3.000000" +alias1 = xbr3x + +shader2 = shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang +filter_linear2 = "false" +scale_type2 = "source" +scale2 = "1.000000" + +shader3 = shaders/xbr-lv3-multipass/xbr-lv3-pass1b.slang +filter_linear3 = "false" +scale_type3 = "source" +scale3 = "3.000000" + +shader4 = "shaders/support/b-spline.slang" +filter_linear4 = false + +parameters = "XBR_BLENDING" + +XBR_BLENDING = "0.0" diff --git a/xbr/xbr-lv3-multipass.slangp b/xbr/xbr-lv3-multipass.slangp index 91e2d11..057f083 100644 --- a/xbr/xbr-lv3-multipass.slangp +++ b/xbr/xbr-lv3-multipass.slangp @@ -1,8 +1,15 @@ -shaders = 2 +shaders = "3" +shader0 = shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang +scale_type0 = "source" +scale0 = "1.000000" -shader0 = "shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang" -filter_linear0 = false -scale_type0 = source +shader1 = shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang +scale_type1 = "source" +scale1 = "3.000000" + +shader2 = "shaders/support/b-spline.slang" +filter_linear2 = false + +filter_linear0 = "false" +filter_linear1 = "false" -shader1 = "shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang" -filter_linear1 = false