add some more xbr-related shaders and presets

This commit is contained in:
hunterk 2017-06-30 14:33:49 -05:00
parent d30218fd22
commit fb6cfff937
11 changed files with 1231 additions and 13 deletions

View file

@ -0,0 +1,8 @@
shaders = 2
shader0 = shaders/adaptive-sharpen-pass1.slang
filter_linear0 = false
scale_type_0 = source
shader1 = shaders/adaptive-sharpen-pass2.slang
filter_linear1 = false
scale_type_1 = source

View file

@ -0,0 +1,119 @@
#version 450
/* Ported by Hyllian and hunterk - 2015 / 2017 */
// Copyright (c) 2015-2017, bacondither
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer
// in this position and unchanged.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// First pass, MUST BE PLACED IMMEDIATELY BEFORE THE SECOND PASS IN THE CHAIN
// Adaptive sharpen - version 2017-04-11 - (requires ps >= 3.0)
// Tuned for use post-resize, EXPECTS FULL RANGE GAMMA LIGHT
// Compatibility defines:
#define mul(a,b) (b*a)
#define saturate(c) clamp(c, 0.0, 1.0)
//-------------------------------------------------------------------------------------------------
#define w_offset 1.0 // Edge channel offset, must be the same in all passes
//-------------------------------------------------------------------------------------------------
// Get destination pixel values
#define get(x,y) ( saturate(texture(Source, coord + vec2(x*(px), y*(py))).rgb) )
// Component-wise distance
#define b_diff(pix) ( abs(blur - c[pix]) )
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
} params;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
vec4 frag_op(sampler2D Source, vec2 coord, float px, float py)
{
// Get points and clip out of range values (BTB & WTW)
// [ c9 ]
// [ c1, c2, c3 ]
// [ c10, c4, c0, c5, c11 ]
// [ c6, c7, c8 ]
// [ c12 ]
vec3 c[13] = { get( 0, 0), get(-1,-1), get( 0,-1), get( 1,-1), get(-1, 0),
get( 1, 0), get(-1, 1), get( 0, 1), get( 1, 1), get( 0,-2),
get(-2, 0), get( 2, 0), get( 0, 2) };
// Blur, gauss 3x3
vec3 blur = (2.*(c[2]+c[4]+c[5]+c[7]) + (c[1]+c[3]+c[6]+c[8]) + 4.*c[0])/16.;
float blur_Y = (blur.r/3. + blur.g/3. + blur.b/3.);
// Contrast compression, center = 0.5, scaled to 1/3
float c_comp = saturate(0.266666681 + 0.9*exp2(-7.4*blur_Y));
// Edge detection
// Relative matrix weights
// [ 1, ]
// [ 4, 5, 4 ]
// [ 1, 5, 6, 5, 1 ]
// [ 4, 5, 4 ]
// [ 1 ]
float edge = length( 1.38*(b_diff(0))
+ 1.15*(b_diff(2) + b_diff(4) + b_diff(5) + b_diff(7))
+ 0.92*(b_diff(1) + b_diff(3) + b_diff(6) + b_diff(8))
+ 0.23*(b_diff(9) + b_diff(10) + b_diff(11) + b_diff(12)) );
return vec4( (texture(Source, coord).rgb), (edge*c_comp + w_offset) );
}
void main()
{
vec2 tex = vTexCoord;
float px = 1.0 / params.SourceSize.x;
float py = 1.0 / params.SourceSize.y;
FragColor = vec4(frag_op(Source, tex, px, py));
}

View file

@ -0,0 +1,295 @@
#version 450
/* Ported by Hyllian and hunterk - 2015 / 2017 */
// Copyright (c) 2015-2017, bacondither
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer
// in this position and unchanged.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Second pass, MUST BE PLACED IMMEDIATELY AFTER THE FIRST PASS IN THE CHAIN
// Adaptive sharpen - version 2017-04-11 - (requires ps >= 3.0)
// Tuned for use post-resize, EXPECTS FULL RANGE GAMMA LIGHT
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float CURVE_HEIGHT;
float VIDEO_LEVEL_OUT;
} params;
#pragma parameter CURVE_HEIGHT "AS Curve Height" 1.0 0.3 2.0 0.1
#pragma parameter VIDEO_LEVEL_OUT "AS Video Lvl Out" 0.0 0.0 1.0 1.0
#define mul(a,b) (b*a)
#define saturate(c) clamp(c, 0.0, 1.0)
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
//--------------------------------------- Settings ------------------------------------------------
#define curve_height params.CURVE_HEIGHT // Main sharpening strength, POSITIVE VALUES ONLY!
// 0.3 <-> 2.0 is a reasonable range of values
#define video_level_out params.VIDEO_LEVEL_OUT // True to preserve BTB & WTW (minor summation error)
// Normally it should be set to false
//-------------------------------------------------------------------------------------------------
// Defined values under this row are "optimal" DO NOT CHANGE IF YOU DO NOT KNOW WHAT YOU ARE DOING!
#define curveslope 0.4 // Sharpening curve slope, high edge values
#define L_overshoot 0.003 // Max light overshoot before compression [>0.001]
#define L_compr_low 0.169 // Light compression, default (0.169=~9x)
#define L_compr_high 0.337 // Light compression, surrounded by edges (0.337=~4x)
#define D_overshoot 0.009 // Max dark overshoot before compression [>0.001]
#define D_compr_low 0.253 // Dark compression, default (0.253=~6x)
#define D_compr_high 0.504 // Dark compression, surrounded by edges (0.504=~2.5x)
#define scale_lim 0.1 // Abs max change before compression [>0.01]
#define scale_cs 0.056 // Compression slope above scale_lim
#define dW_lothr 0.3 // Start interpolating between W1 and W2
#define dW_hithr 0.8 // When dW is equal to W2
#define lowthr_mxw 0.11 // Edge value for max lowthr weight [>0.01]
#define pm_p 0.75 // Power mean p-value [>0-1.0]
#define alpha_out 1.0 // MPDN requires the alpha channel output to be 1.0
//-------------------------------------------------------------------------------------------------
#define w_offset 1.0 // Edge channel offset, must be the same in all passes
#define bounds_check true // If edge data is outside bounds, make pixels green
//-------------------------------------------------------------------------------------------------
// Soft if, fast approx
#define soft_if(a,b,c) ( saturate((a + b + c - 3*w_offset + 0.06)/(abs(maxedge) + 0.03) - 0.85) )
// Soft limit, modified tanh
#define soft_lim(v,s) ( ((exp(2.*min(abs(v), s*24.)/s) - 1.)/(exp(2*min(abs(v), s*24.)/s) + 1.))*s )
// Weighted power mean
#define wpmean(a,b,w) ( pow((w*pow(abs(a), pm_p) + abs(1-w)*pow(abs(b), pm_p)), (1.0/pm_p)) )
// Get destination pixel values
#define get(x,y) ( texture(Source, coord + vec2(x*(px), y*(py))) )
#define sat(inp) ( vec4(saturate((inp).xyz), (inp).w) )
// Maximum of four values
#define max4(a,b,c,d) ( max(max(a, b), max(c, d)) )
// Colour to luma, fast approx gamma, avg of rec. 709 & 601 luma coeffs
#define CtL(RGB) ( sqrt(dot(vec3(0.2558, 0.6511, 0.0931), saturate((RGB)*abs(RGB)).rgb)) )
// Center pixel diff
#define mdiff(a,b,c,d,e,f,g) ( abs(luma[g]-luma[a]) + abs(luma[g]-luma[b]) \
+ abs(luma[g]-luma[c]) + abs(luma[g]-luma[d]) \
+ 0.5*(abs(luma[g]-luma[e]) + abs(luma[g]-luma[f])) )
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
vec4 frag_op(vec4 orig, vec2 coord, float c_edge, float px, float py)
{
if (bounds_check == true)
{
if (c_edge > 24. || c_edge < -0.5) { return vec4( 0., 1.0, 0., alpha_out ); }
}
// Get points, clip out of range colour data in c[0]
// [ c22 ]
// [ c24, c9, c23 ]
// [ c21, c1, c2, c3, c18 ]
// [ c19, c10, c4, c0, c5, c11, c16 ]
// [ c20, c6, c7, c8, c17 ]
// [ c15, c12, c14 ]
// [ c13 ]
vec4 c[25] = { sat( orig), get(-1,-1), get( 0,-1), get( 1,-1), get(-1, 0),
get( 1, 0), get(-1, 1), get( 0, 1), get( 1, 1), get( 0,-2),
get(-2, 0), get( 2, 0), get( 0, 2), get( 0, 3), get( 1, 2),
get(-1, 2), get( 3, 0), get( 2, 1), get( 2,-1), get(-3, 0),
get(-2, 1), get(-2,-1), get( 0,-3), get( 1,-2), get(-1,-2) };
// Allow for higher overshoot if the current edge pixel is surrounded by similar edge pixels
float maxedge = max4( max4(c[1].w,c[2].w,c[3].w,c[4].w), max4(c[5].w,c[6].w,c[7].w,c[8].w),
max4(c[9].w,c[10].w,c[11].w,c[12].w), c[0].w ) - w_offset;
// [ x ]
// [ z, x, w ]
// [ z, z, x, w, w ]
// [ y, y, y, 0, y, y, y ]
// [ w, w, x, z, z ]
// [ w, x, z ]
// [ x ]
float sbe = soft_if(c[2].w,c[9].w,c[22].w) *soft_if(c[7].w,c[12].w,c[13].w) // x dir
+ soft_if(c[4].w,c[10].w,c[19].w)*soft_if(c[5].w,c[11].w,c[16].w) // y dir
+ soft_if(c[1].w,c[24].w,c[21].w)*soft_if(c[8].w,c[14].w,c[17].w) // z dir
+ soft_if(c[3].w,c[23].w,c[18].w)*soft_if(c[6].w,c[20].w,c[15].w); // w dir
vec2 cs = mix( vec2(L_compr_low, D_compr_low),
vec2(L_compr_high, D_compr_high), smoothstep(2, 3.1, sbe) );
// RGB to luma
float c0_Y = CtL(c[0]);
float luma[25] = { c0_Y, CtL(c[1]), CtL(c[2]), CtL(c[3]), CtL(c[4]), CtL(c[5]), CtL(c[6]),
CtL(c[7]), CtL(c[8]), CtL(c[9]), CtL(c[10]), CtL(c[11]), CtL(c[12]),
CtL(c[13]), CtL(c[14]), CtL(c[15]), CtL(c[16]), CtL(c[17]), CtL(c[18]),
CtL(c[19]), CtL(c[20]), CtL(c[21]), CtL(c[22]), CtL(c[23]), CtL(c[24]) };
// Pre-calculated default squared kernel weights
const vec3 W1 = vec3(0.5, 1.0, 1.41421356237); // 0.25, 1.0, 2.0
const vec3 W2 = vec3(0.86602540378, 1.0, 0.5477225575); // 0.75, 1.0, 0.3
// Transition to a concave kernel if the center edge val is above thr
vec3 dW = pow(mix( W1, W2, smoothstep(dW_lothr, dW_hithr, c_edge) ), vec3(2.0));
float mdiff_c0 = 0.02 + 3*( abs(luma[0]-luma[2]) + abs(luma[0]-luma[4])
+ abs(luma[0]-luma[5]) + abs(luma[0]-luma[7])
+ 0.25*(abs(luma[0]-luma[1]) + abs(luma[0]-luma[3])
+abs(luma[0]-luma[6]) + abs(luma[0]-luma[8])) );
// Use lower weights for pixels in a more active area relative to center pixel area
// This results in narrower and less visible overshoots around sharp edges
float weights[12] = { ( min(mdiff_c0/mdiff(24, 21, 2, 4, 9, 10, 1), dW.y) ), // c1
( dW.x ), // c2
( min(mdiff_c0/mdiff(23, 18, 5, 2, 9, 11, 3), dW.y) ), // c3
( dW.x ), // c4
( dW.x ), // c5
( min(mdiff_c0/mdiff(4, 20, 15, 7, 10, 12, 6), dW.y) ), // c6
( dW.x ), // c7
( min(mdiff_c0/mdiff(5, 7, 17, 14, 12, 11, 8), dW.y) ), // c8
( min(mdiff_c0/mdiff(2, 24, 23, 22, 1, 3, 9), dW.z) ), // c9
( min(mdiff_c0/mdiff(20, 19, 21, 4, 1, 6, 10), dW.z) ), // c10
( min(mdiff_c0/mdiff(17, 5, 18, 16, 3, 8, 11), dW.z) ), // c11
( min(mdiff_c0/mdiff(13, 15, 7, 14, 6, 8, 12), dW.z) ) }; // c12
weights[0] = (max(max((weights[8] + weights[9])/4, weights[0]), 0.25) + weights[0])/2;
weights[2] = (max(max((weights[8] + weights[10])/4, weights[2]), 0.25) + weights[2])/2;
weights[5] = (max(max((weights[9] + weights[11])/4, weights[5]), 0.25) + weights[5])/2;
weights[7] = (max(max((weights[10] + weights[11])/4, weights[7]), 0.25) + weights[7])/2;
// Calculate the negative part of the laplace kernel and the low threshold weight
float lowthrsum = 0.;
float weightsum = 0.;
float neg_laplace = 0.;
//[unroll]
for (int pix = 0; pix < 12; ++pix)
{
float x = saturate((c[pix + 1].w - w_offset - 0.01)/(lowthr_mxw - 0.01));
float lowthr = x*x*(2.97 - 1.98*x) + 0.01; // x*x((3.0-c*3.) - (2.0-c*2.)*x) + c
neg_laplace += pow(luma[pix + 1] + 0.06, 2.4)*(weights[pix]*lowthr);
weightsum += weights[pix]*lowthr;
lowthrsum += lowthr/12.;
}
neg_laplace = pow(abs(neg_laplace/weightsum), (1.0/2.4)) - 0.06;
// Compute sharpening magnitude function
float sharpen_val = curve_height/(curve_height*curveslope*pow(abs(c_edge), 3.5) + 0.5);
// Calculate sharpening diff and scale
float sharpdiff = (c0_Y - neg_laplace)*(lowthrsum*sharpen_val*0.8 + 0.01);
// Calculate local near min & max, partial sort
//[unroll]
for (int i = 0; i < 3; ++i)
{
float temp;
for (int i1 = i; i1 < 24-i; i1 += 2)
{
temp = luma[i1];
luma[i1] = min(luma[i1], luma[i1+1]);
luma[i1+1] = max(temp, luma[i1+1]);
}
for (int i2 = 24-i; i2 > i; i2 -= 2)
{
temp = luma[i];
luma[i] = min(luma[i], luma[i2]);
luma[i2] = max(temp, luma[i2]);
temp = luma[24-i];
luma[24-i] = max(luma[24-i], luma[i2-1]);
luma[i2-1] = min(temp, luma[i2-1]);
}
}
float nmax = (max(luma[22] + luma[23]*2., c0_Y*3.) + luma[24])/4.;
float nmin = (min(luma[2] + luma[1]*2., c0_Y*3.) + luma[0])/4.;
// Calculate tanh scale factor, pos/neg
float nmax_scale = nmax - c0_Y + min(L_overshoot, 1.0001 - nmax);
float nmin_scale = c0_Y - nmin + min(D_overshoot, 0.0001 + nmin);
nmax_scale = min(nmax_scale, scale_lim*(1. - scale_cs) + nmax_scale*scale_cs);
nmin_scale = min(nmin_scale, scale_lim*(1. - scale_cs) + nmin_scale*scale_cs);
// Soft limited anti-ringing with tanh, wpmean to control compression slope
sharpdiff = wpmean( max(sharpdiff, 0.), soft_lim( max(sharpdiff, 0.), nmax_scale ), cs.x )
- wpmean( min(sharpdiff, 0.), soft_lim( min(sharpdiff, 0.), nmin_scale ), cs.y );
// Compensate for saturation loss/gain while making pixels brighter/darker
float sharpdiff_lim = saturate(c0_Y + sharpdiff) - c0_Y;
float satmul = (c0_Y + sharpdiff_lim + 0.03)/(c0_Y + 0.03);
vec3 res = c0_Y + (sharpdiff_lim*3 + sharpdiff)/4 + (c[0].rgb - c0_Y)*satmul;
return vec4( (video_level_out == 1.0 ? orig.rgb + (res - c[0].rgb) : res), alpha_out );
}
void main()
{
vec2 tex = vTexCoord;
float px = 1.0 / params.SourceSize.x;
float py = 1.0 / params.SourceSize.y;
vec4 orig = texture(Source, tex);
float c_edge = orig.w - w_offset;
FragColor = vec4(frag_op(orig, tex, c_edge, px, py));
}

View file

@ -0,0 +1,71 @@
#version 450
/*
Super-res shader - Shiandow
Ported from Shiandow's code by Hyllian, 2016.
This file is a part of MPDN Extensions.
https://github.com/zachsaw/MPDN_Extensions
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
} params;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D Original;
const vec3 Y = vec3(.2126, .7152, .0722);
float RGBtoYUV(vec3 color)
{
return dot(color, Y);
}
void main()
{
vec2 tex = vTexCoord;
vec4 c0 = texture(Source, tex);
vec4 c1 = texture(Original, tex);
FragColor = vec4(c0.xyz - c1.xyz, RGBtoYUV(c0.rgb));
}

View file

@ -0,0 +1,190 @@
#version 450
/*
Super-res shader - Shiandow
Ported from Shiandow's code by Hyllian, 2016.
This file is a part of MPDN Extensions.
https://github.com/zachsaw/MPDN_Extensions
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 REFSize;
vec4 OutputSize;
uint FrameCount;
} params;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
// -- Edge detection options --
#define strength 0.8
#define softness 0.3
#define acuity 100.0
#define radius 1.0
#define power 2.0
#define originalSize vec2(params.REFSize.xy)
#define dxdy (1.0 / vec2(params.SourceSize.xy))
#define ddxddy (1.0 / originalSize)
#define sqr(x) dot(x,x)
// -- Input processing --
//Current high res value
#define Get(x,y) (texture(REF,ddxddy*(pos+ivec2(x,y)+0.5)).xyz)
#define GetY(x,y) (texture(Source,ddxddy*(pos+ivec2(x,y)+0.5)).a)
//Downsampled result
#define Diff(x,y) (texture(Source,ddxddy*(pos+ivec2(x,y)+0.5)).xyz)
#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord;
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;
layout(set = 0, binding = 3) uniform sampler2D REF;
const vec3 Y = vec3(.2126, .7152, .0722);
float RGBtoYUV(vec3 color)
{
return dot(color, Y);
}
void main()
{
vec2 tex = vTexCoord;
vec4 c0 = texture(REF, tex);
// Calculate position
vec2 pos = tex * params.REFSize.xy - 0.5;
vec2 offset = pos - round(pos);
pos -= offset;
// Calculate faithfulness force
float W = 0.;
vec3 diff = vec3(0.0);
vec3 stab = vec3(0.0);
float var = 0.;
float c0y = RGBtoYUV(c0.rgb);
// Loop unrolled for better compatibility.
float dI2 = sqr(acuity*(c0y - GetY(-1,-1)));
float dXY2 = sqr(vec2(-1,-1) - offset);
float w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff(-1,-1);
stab += w*(c0.rgb - Get(-1,-1));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY(-1, 0)));
dXY2 = sqr(vec2(-1, 0) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff(-1, 0);
stab += w*(c0.rgb - Get(-1, 0));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY(-1, 1)));
dXY2 = sqr(vec2(-1, 1) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff(-1, 1);
stab += w*(c0.rgb - Get(-1, 1));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY( 0,-1)));
dXY2 = sqr(vec2( 0,-1) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff( 0,-1);
stab += w*(c0.rgb - Get( 0,-1));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY( 0, 0)));
dXY2 = sqr(vec2( 0, 0) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff( 0, 0);
stab += w*(c0.rgb - Get( 0, 0));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY( 0, 1)));
dXY2 = sqr(vec2( 0, 1) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff( 0, 1);
stab += w*(c0.rgb - Get( 0, 1));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY( 1,-1)));
dXY2 = sqr(vec2( 1,-1) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff( 1,-1);
stab += w*(c0.rgb - Get( 1,-1));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY( 1, 0)));
dXY2 = sqr(vec2( 1, 0) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff( 1, 0);
stab += w*(c0.rgb - Get( 1, 0));
var += w*dI2;
W += w;
dI2 = sqr(acuity*(c0y - GetY( 1, 1)));
dXY2 = sqr(vec2( 1, 1) - offset);
w = exp(-dXY2/(2.*radius*radius))*pow(1. + dI2/power, - power);
diff += w*Diff( 1, 1);
stab += w*(c0.rgb - Get( 1, 1));
var += w*dI2;
W += w;
diff /= W;
stab /= W;
var = (var / W) - sqr(acuity*stab);
// Calculate edge statistics
float varD = softness * sqr(acuity*stab);
float varS = (1. - softness) * var;
// Apply force
c0.xyz -= strength*mix(diff, stab, softness);
FragColor = vec4(c0);
}

View file

@ -0,0 +1,41 @@
shaders = "9"
shader0 = "../xbr/shaders/super-xbr/super-xbr-pass0.slang"
filter_linear0 = "false"
scale_type0 = "source"
scale0 = "1.000000"
shader1 = "../xbr/shaders/super-xbr/super-xbr-pass1.slang"
filter_linear1 = "false"
scale_type1 = "source"
scale1 = "2.000000"
shader2 = "../xbr/shaders/super-xbr/super-xbr-pass2.slang"
filter_linear2 = "false"
scale_type2 = "source"
scale2 = "1.000000"
alias2 = "REF"
shader3 = "../cubic/shaders/cubic.slang"
filter_linear3 = "false"
scale_type3 = "source"
scale3 = "0.500000"
shader4 = "shaders/diff.slang"
filter_linear4 = "false"
scale_type4 = "source"
scale4 = "1.000000"
shader5 = "shaders/super-res-ex.slang"
filter_linear5 = "true"
scale_type5 = "source"
scale5 = "2.000000"
shader6 = "../misc/deposterize-pass0.slang"
filter_linear6 = "false"
scale_type6 = "source"
scale6 = "1.000000"
shader7 = "../misc/deposterize-pass1.slang"
filter_linear7 = "false"
scale_type7 = "source"
scale7 = "1.000000"
shader8 = "../xbr/shaders/super-xbr/custom-jinc2-sharper.slang"
filter_linear8 = "false"

View file

@ -171,7 +171,6 @@ void main()
float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 ); float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 ); float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
/* Calc edgeness in diagonal directions. */ /* Calc edgeness in diagonal directions. */
float d_edge = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 )); float d_edge = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));

View file

@ -116,12 +116,14 @@ layout(set = 0, binding = 3) uniform sampler2D Original;
void main() void main()
{ {
//Skip pixels on wrong grid //Skip pixels on wrong grid
vec2 fp = fract(vTexCoord*params.SourceSize.xy); vec2 fp = fract(vTexCoord.xy * params.SourceSize.xy);
vec2 dir = fp - vec2(0.5,0.5); vec2 dir = fp - vec2(0.5,0.5);
if ((dir.x*dir.y)>0.0){ if ((dir.x*dir.y)>0.0)
{
FragColor = (fp.x>0.5) ? texture(Source, vTexCoord) : texture(Original, vTexCoord); FragColor = (fp.x>0.5) ? texture(Source, vTexCoord) : texture(Original, vTexCoord);
}else{ }
else
{
vec2 g1 = (fp.x>0.5) ? vec2(0.5/params.SourceSize.x, 0.0) : vec2(0.0, 0.5/params.SourceSize.y); vec2 g1 = (fp.x>0.5) ? vec2(0.5/params.SourceSize.x, 0.0) : vec2(0.0, 0.5/params.SourceSize.y);
vec2 g2 = (fp.x>0.5) ? vec2(0.0, 0.5/params.SourceSize.y) : vec2(0.5/params.SourceSize.x, 0.0); vec2 g2 = (fp.x>0.5) ? vec2(0.0, 0.5/params.SourceSize.y) : vec2(0.5/params.SourceSize.x, 0.0);

View file

@ -0,0 +1,290 @@
#version 450
/*
Hyllian's xBR level 3 pass0 Shader
Copyright (C) 2011-2015 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.
Incorporates some of the ideas from SABR shader. Thanks to Joshua Street.
*/
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
} params;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#define mul(a,b) (b*a)
#define saturate(c) clamp(c, 0.0, 1.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 vec4 t3;
layout(location = 4) out vec4 t4;
layout(location = 5) out vec4 t5;
layout(location = 6) out vec4 t6;
layout(location = 7) out vec4 t7;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord * 1.0004;
vec2 ps = vec2(1.0) / params.SourceSize.xy;
float dx = ps.x;
float dy = ps.y;
// 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
}
#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 vec4 t3;
layout(location = 4) in vec4 t4;
layout(location = 5) in vec4 t5;
layout(location = 6) in vec4 t6;
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)
{
return vec4(abs(A-B));
}
vec4 remapTo01(vec4 v, vec4 high)
{
return (v/high);
}
vec4 remapFrom01(vec4 v, vec4 high)
{
return (high*v + vec4(0.5, 0.5, 0.5, 0.5));
}
bvec4 eq(vec4 A, vec4 B)
{
return lessThan(df(A, B) , eq_threshold);
}
vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h)
{
return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
}
bvec4 and(bvec4 A, bvec4 B)
{
return bvec4(A.x && B.x, A.y && B.y, A.z && B.z, A.w && B.w);
}
bvec4 or(bvec4 A, bvec4 B)
{
return bvec4(A.x || B.x, A.y || B.y, A.z || B.z, A.w || B.w);
}
#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;
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 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 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 C4 = texture(Source, t7.xy).rgb;
vec3 F4 = texture(Source, t7.xz).rgb;
vec3 I4 = texture(Source, t7.xw).rgb;
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;
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;
vec4 c1 = i4.yzwx;
vec4 g0 = i5.wxyz;
vec4 b1 = h5.zwxy;
vec4 d0 = h5.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));
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);
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));
px = lessThanEqual(df(e,f) , df(e,h));
lin0 = lin1 = lin2 = lin3 = bvec4(1, 1, 1, 1);
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);
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
)
);
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));
}

View file

@ -0,0 +1,203 @@
#version 450
/*
Hyllian's xBR level 3 pass1 Shader
Copyright (C) 2011-2015 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.
*/
#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;
} params;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#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;
void main()
{
gl_Position = global.MVP * Position;
vTexCoord = TexCoord * 1.0004;
vec2 ps = vec2(1.0/params.OriginalSize.x, 1.0/params.OriginalSize.y);
float dx = ps.x;
float dy = ps.y;
// 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
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
}
#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 1) in vec4 t1;
layout(location = 2) in vec2 delta;
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 (high*v + 0.5);
}
vec3 remapFrom01(vec3 v, vec3 low, vec3 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;
}
void main()
{
vec2 px; // px = pixel to blend
float pxr, pxd, line, edr3_nrl, edr3_ndu;
vec2 pos = fract(vTexCoord*params.SourceSize.xy)-vec2(0.5, 0.5); // pos = pixel position
vec2 dir = sign(pos); // dir = pixel direction
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 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;
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;
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
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));
vec4 flags = unpack_info(info); // retrieve 1st pass flags
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));
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));
float aux = round(dot(vec4(8.0, 4.0, 2.0, 1.0), flags));
vec3 slep;
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);
}

View file

@ -29,9 +29,9 @@ alias2 = ""
float_framebuffer2 = "false" float_framebuffer2 = "false"
srgb_framebuffer2 = "false" srgb_framebuffer2 = "false"
scale_type_x2 = "source" scale_type_x2 = "source"
scale_x2 = "2.000000" scale_x2 = "1.000000"
scale_type_y2 = "source" scale_type_y2 = "source"
scale_y2 = "2.000000" scale_y2 = "1.000000"
shader3 = "..\xbr\shaders\super-xbr\super-xbr-pass1.slang" shader3 = "..\xbr\shaders\super-xbr\super-xbr-pass1.slang"
filter_linear3 = "false" filter_linear3 = "false"
wrap_mode3 = "clamp_to_border" wrap_mode3 = "clamp_to_border"
@ -40,9 +40,9 @@ alias3 = ""
float_framebuffer3 = "false" float_framebuffer3 = "false"
srgb_framebuffer3 = "false" srgb_framebuffer3 = "false"
scale_type_x3 = "source" scale_type_x3 = "source"
scale_x3 = "1.000000" scale_x3 = "2.000000"
scale_type_y3 = "source" scale_type_y3 = "source"
scale_y3 = "1.000000" scale_y3 = "2.000000"
shader4 = "..\xbr\shaders\super-xbr\super-xbr-pass2.slang" shader4 = "..\xbr\shaders\super-xbr\super-xbr-pass2.slang"
filter_linear4 = "false" filter_linear4 = "false"
wrap_mode4 = "clamp_to_border" wrap_mode4 = "clamp_to_border"