From f0927ba3b0ce0abe5f560b5f5f32a107091b71cf Mon Sep 17 00:00:00 2001 From: Hyllian Date: Mon, 18 Jul 2022 10:34:31 -0300 Subject: [PATCH] Add CUT and fix DDT shaders - Add CUT shaders. A kind of DDT shaders with some useful params to control interpolation; - Fix DDT shaders (broken when porting from Cg to Slang). Courtesy of guest.r --- ddt/cut.slangp | 4 + ddt/ddt-extended.slangp | 4 + ddt/ddt-sharp.slangp | 4 + ddt/shaders/cut.slang | 190 +++++++++++++++++++++++++++++++ ddt/shaders/ddt-extended.slang | 8 +- ddt/shaders/ddt-sharp.slang | 10 +- ddt/shaders/ddt-waterpaint.slang | 8 +- ddt/shaders/ddt.slang | 6 +- 8 files changed, 218 insertions(+), 16 deletions(-) create mode 100644 ddt/cut.slangp create mode 100644 ddt/ddt-extended.slangp create mode 100644 ddt/ddt-sharp.slangp create mode 100644 ddt/shaders/cut.slang diff --git a/ddt/cut.slangp b/ddt/cut.slangp new file mode 100644 index 0000000..310cf4c --- /dev/null +++ b/ddt/cut.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/cut.slang +filter_linear0 = false diff --git a/ddt/ddt-extended.slangp b/ddt/ddt-extended.slangp new file mode 100644 index 0000000..535941d --- /dev/null +++ b/ddt/ddt-extended.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/ddt-extended.slang +filter_linear0 = false diff --git a/ddt/ddt-sharp.slangp b/ddt/ddt-sharp.slangp new file mode 100644 index 0000000..25acefd --- /dev/null +++ b/ddt/ddt-sharp.slangp @@ -0,0 +1,4 @@ +shaders = 1 + +shader0 = shaders/ddt-sharp.slang +filter_linear0 = false diff --git a/ddt/shaders/cut.slang b/ddt/shaders/cut.slang new file mode 100644 index 0000000..9115266 --- /dev/null +++ b/ddt/shaders/cut.slang @@ -0,0 +1,190 @@ +#version 450 + +/* + MIT License + + Copyright (c) 2022 Filippo Scognamiglio + + 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. +*/ + +/* + Code ported by Hyllian from: + https://github.com/Swordfish90/cheap-upscaling-triangulation +*/ + + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float USE_DYNAMIC_SHARPNESS; + float USE_SHARPENING_BIAS; + float DYNAMIC_SHARPNESS_MIN; + float DYNAMIC_SHARPNESS_MAX; + float STATIC_SHARPNESS; +} params; + +// set to 1.0 to use dynamic sharpening +#pragma parameter USE_DYNAMIC_SHARPNESS "Dynamic Sharpness [ 0FF | ON ]" 1.0 0.0 1.0 1.0 + +// Set to 1.0 to bias the interpolation towards sharpening +#pragma parameter USE_SHARPENING_BIAS "Sharpness Bias [ 0FF | ON ]" 0.0 0.0 1.0 1.0 + +// Minimum amount of sharpening in range [0.0, 1.0] +#pragma parameter DYNAMIC_SHARPNESS_MIN "Dynamic Sharpness Min" 0.0 0.0 1.0 0.1 + +// Maximum amount of sharpening in range [0.0, 1.0] +#pragma parameter DYNAMIC_SHARPNESS_MAX "Dynamic Sharpness Max" 0.8 0.0 1.0 0.1 + +// If USE_DYNAMIC_SHARPNESS is 0 apply this static sharpness +#pragma parameter STATIC_SHARPNESS "Static Sharpness" 0.2 0.0 1.0 0.1 + +#define USE_DYNAMIC_SHARPNESS params.USE_DYNAMIC_SHARPNESS +#define USE_SHARPENING_BIAS params.USE_SHARPENING_BIAS +#define DYNAMIC_SHARPNESS_MIN (params.DYNAMIC_SHARPNESS_MIN * 0.5) +#define DYNAMIC_SHARPNESS_MAX (params.DYNAMIC_SHARPNESS_MAX * 0.5) +#define STATIC_SHARPNESS (params.STATIC_SHARPNESS * 0.5) + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + + +float luma(vec3 v) +{ + return v.g; +} + +float linearStep(float edge0, float edge1, float t) +{ + return clamp((t - edge0) / (edge1 - edge0), 0.0, 1.0); +} + +float sharpSmooth(float t, float sharpness) +{ + return linearStep(sharpness, 1.0 - sharpness, t); +} + +vec3 quadBilinear(vec3 a, vec3 b, vec3 c, vec3 d, vec2 p, float sharpness) +{ + float x = sharpSmooth(p.x, sharpness); + float y = sharpSmooth(p.y, sharpness); + return mix(mix(a, b, x), mix(c, d, x), y); +} + +// Fast computation of barycentric coordinates only in the sub-triangle 1 2 4 +vec3 fastBarycentric(vec2 p, float sharpness) +{ + float l0 = sharpSmooth(1.0 - p.x - p.y, sharpness); + float l1 = sharpSmooth(p.x, sharpness); + return vec3(l0, l1, 1.0 - l0 - l1); +} + +vec3 triangleInterpolate(vec3 t1, vec3 t2, vec3 t3, vec3 t4, vec2 c, float sharpness) +{ + // Alter colors and coordinates to compute the other triangle. + bool altTriangle = 1.0 - c.x < c.y; + vec3 cornerColor = altTriangle ? t3 : t1; + vec2 triangleCoords = altTriangle ? vec2(1.0 - c.y, 1.0 - c.x) : c; + vec3 weights = fastBarycentric(triangleCoords, sharpness); + return weights.x * cornerColor + weights.y * t2 + weights.z * t4; +} + +#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 vec2 screenCoords; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.000001; + + screenCoords = vTexCoord*params.SourceSize.xy - vec2(0.5); +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 1) in vec2 screenCoords; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +void main() +{ + float lmax, lmin, contrast; + float sharpness = STATIC_SHARPNESS; + + vec2 relativeCoords = floor(screenCoords); + vec2 c1 = ((relativeCoords + vec2(0.0, 0.0)) + vec2(0.5)) / params.SourceSize.xy; + vec2 c2 = ((relativeCoords + vec2(1.0, 0.0)) + vec2(0.5)) / params.SourceSize.xy; + vec2 c3 = ((relativeCoords + vec2(1.0, 1.0)) + vec2(0.5)) / params.SourceSize.xy; + vec2 c4 = ((relativeCoords + vec2(0.0, 1.0)) + vec2(0.5)) / params.SourceSize.xy; + + vec3 t1 = texture(Source, c1).rgb; + vec3 t2 = texture(Source, c2).rgb; + vec3 t3 = texture(Source, c3).rgb; + vec3 t4 = texture(Source, c4).rgb; + + float l1 = luma(t1); + float l2 = luma(t2); + float l3 = luma(t3); + float l4 = luma(t4); + + if (USE_DYNAMIC_SHARPNESS == 1.0) + { + lmax = max(max(l1, l2), max(l3, l4)); + lmin = min(min(l1, l2), min(l3, l4)); + contrast = (lmax - lmin) / (lmax + lmin + 0.05); + + if (USE_SHARPENING_BIAS == 1.0) + contrast = sqrt(contrast); + + sharpness = mix(DYNAMIC_SHARPNESS_MIN, DYNAMIC_SHARPNESS_MAX, contrast); + } + + vec2 pxCoords = fract(screenCoords); + + float diagonal1Strength = abs(l1 - l3); + float diagonal2Strength = abs(l2 - l4); + + // Alter colors and coordinates to compute the other triangulation. + bool altTriangulation = diagonal1Strength < diagonal2Strength; + + vec3 cd = triangleInterpolate( + altTriangulation ? t2 : t1, + altTriangulation ? t3 : t2, + altTriangulation ? t4 : t3, + altTriangulation ? t1 : t4, + altTriangulation ? vec2(pxCoords.y, 1.0 - pxCoords.x) : pxCoords, + sharpness + ); + + float minDiagonal = min(diagonal1Strength, diagonal2Strength); + float maxDiagonal = max(diagonal1Strength, diagonal2Strength); + bool diagonal = minDiagonal * 4.0 + 0.05 < maxDiagonal; + + vec3 final = diagonal ? cd : quadBilinear(t1, t2, t4, t3, pxCoords, sharpness); + + FragColor = vec4(final, 1.0); +} diff --git a/ddt/shaders/ddt-extended.slang b/ddt/shaders/ddt-extended.slang index a5b11d8..5186224 100644 --- a/ddt/shaders/ddt-extended.slang +++ b/ddt/shaders/ddt-extended.slang @@ -100,7 +100,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source; void main() { - float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position + float2 pos = frac(loc)-float2(0.5, 0.5); // pos = pixel position float2 dir = sign(pos); // dir = pixel direction float2 g1 = dir*t1.xy; @@ -149,8 +149,8 @@ void main() float p = abs(pos.x); float q = abs(pos.y); - float k = distance(pos,g1); - float l = distance(pos,g2); + float k = distance(pos,g1 * params.SourceSize.xy); + float l = distance(pos,g2 * params.SourceSize.xy); float count1 = 0.0; float count2 = 0.0; @@ -191,4 +191,4 @@ void main() float3 color = bilinear(p, q, A, B, C, D); FragColor = float4(color, 1.0); -} \ No newline at end of file +} diff --git a/ddt/shaders/ddt-sharp.slang b/ddt/shaders/ddt-sharp.slang index 026c9cc..f9991d5 100644 --- a/ddt/shaders/ddt-sharp.slang +++ b/ddt/shaders/ddt-sharp.slang @@ -84,7 +84,7 @@ layout(location = 2) out vec2 loc; void main() { gl_Position = global.MVP * Position; - vTexCoord = TexCoord; + vTexCoord = TexCoord * 1.0001; float2 ps = float2(params.SourceSize.z, params.SourceSize.w); float dx = ps.x; @@ -104,7 +104,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source; void main() { -float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position + float2 pos = frac(loc)-float2(0.5, 0.5); // pos = pixel position float2 dir = sign(pos); // dir = pixel direction float2 g1 = dir*t1.xy; @@ -149,8 +149,8 @@ float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position float p = abs(pos.x); float q = abs(pos.y); - float k = distance(pos,g1); - float l = distance(pos,g2); + float k = distance(pos,g1 * params.SourceSize.xy); + float l = distance(pos,g2 * params.SourceSize.xy); float wd1 = abs(a-d); float wd2 = abs(b-c); @@ -174,4 +174,4 @@ float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position float3 color = bilinear(p, q, A, B, C, D); FragColor = vec4(color, 1.0); -} \ No newline at end of file +} diff --git a/ddt/shaders/ddt-waterpaint.slang b/ddt/shaders/ddt-waterpaint.slang index 58c02bd..659692d 100644 --- a/ddt/shaders/ddt-waterpaint.slang +++ b/ddt/shaders/ddt-waterpaint.slang @@ -100,7 +100,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source; void main() { - float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position + float2 pos = frac(loc)-float2(0.5, 0.5); // pos = pixel position float2 dir = sign(pos); // dir = pixel direction float2 g1 = dir*t1.xy; @@ -119,8 +119,8 @@ void main() float p = abs(pos.x); float q = abs(pos.y); - float k = distance(pos,g1); - float l = distance(pos,g2); + float k = distance(pos,g1 * params.SourceSize.xy); + float l = distance(pos,g2 * params.SourceSize.xy); if (abs(a-d) < abs(b-c)) { @@ -167,4 +167,4 @@ void main() float color = float4(0.28 * (res + mid_horiz + mid_vert) + 4.7 * abs(res - lerp(mid_horiz, mid_vert, 0.5)), 1.0).x; FragColor = float4((color + color_old) / 2.0, 1.0); -} \ No newline at end of file +} diff --git a/ddt/shaders/ddt.slang b/ddt/shaders/ddt.slang index 26a3d29..f25aeb1 100644 --- a/ddt/shaders/ddt.slang +++ b/ddt/shaders/ddt.slang @@ -100,7 +100,7 @@ layout(set = 0, binding = 2) uniform sampler2D Source; void main() { -float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position +float2 pos = frac(loc)-float2(0.5, 0.5); // pos = pixel position float2 dir = sign(pos); // dir = pixel direction float2 g1 = dir*t1.xy; @@ -119,8 +119,8 @@ float2 pos = frac(loc * 1.00001)-float2(0.4999, 0.4999); // pos = pixel position float p = abs(pos.x); float q = abs(pos.y); - float k = distance(pos,g1); - float l = distance(pos,g2); + float k = distance(pos,g1 * params.SourceSize.xy); + float l = distance(pos,g2 * params.SourceSize.xy); float wd1 = abs(a-d); float wd2 = abs(b-c);