mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-22 07:41:31 +11:00
add some more xbr-related shaders and presets
This commit is contained in:
parent
d30218fd22
commit
fb6cfff937
8
sharpen/adaptive-sharpen-multipass.slangp
Normal file
8
sharpen/adaptive-sharpen-multipass.slangp
Normal 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
|
119
sharpen/shaders/adaptive-sharpen-pass1.slang
Normal file
119
sharpen/shaders/adaptive-sharpen-pass1.slang
Normal 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));
|
||||
}
|
295
sharpen/shaders/adaptive-sharpen-pass2.slang
Normal file
295
sharpen/shaders/adaptive-sharpen-pass2.slang
Normal 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));
|
||||
}
|
71
sharpen/shaders/diff.slang
Normal file
71
sharpen/shaders/diff.slang
Normal 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));
|
||||
}
|
190
sharpen/shaders/super-res-ex.slang
Normal file
190
sharpen/shaders/super-res-ex.slang
Normal 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);
|
||||
}
|
41
sharpen/super-xbr-super-res.slangp
Normal file
41
sharpen/super-xbr-super-res.slangp
Normal 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"
|
||||
|
|
@ -171,7 +171,6 @@ void main()
|
|||
float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
|
||||
float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
|
||||
|
||||
|
||||
/* 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 ));
|
||||
|
||||
|
@ -199,5 +198,5 @@ void main()
|
|||
vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
|
||||
color = clamp(color, min_sample, max_sample);
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
|
@ -116,12 +116,14 @@ layout(set = 0, binding = 3) uniform sampler2D Original;
|
|||
void main()
|
||||
{
|
||||
//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);
|
||||
if ((dir.x*dir.y)>0.0){
|
||||
FragColor = (fp.x>0.5) ? texture(Source, vTexCoord) : texture(Original, vTexCoord);
|
||||
}else{
|
||||
|
||||
if ((dir.x*dir.y)>0.0)
|
||||
{
|
||||
FragColor = (fp.x>0.5) ? texture(Source, vTexCoord) : texture(Original, vTexCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -185,6 +187,6 @@ void main()
|
|||
vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
|
||||
color = clamp(color, min_sample, max_sample);
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
}
|
290
xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang
Normal file
290
xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.slang
Normal 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));
|
||||
}
|
203
xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang
Normal file
203
xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.slang
Normal 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);
|
||||
}
|
|
@ -29,9 +29,9 @@ alias2 = ""
|
|||
float_framebuffer2 = "false"
|
||||
srgb_framebuffer2 = "false"
|
||||
scale_type_x2 = "source"
|
||||
scale_x2 = "2.000000"
|
||||
scale_x2 = "1.000000"
|
||||
scale_type_y2 = "source"
|
||||
scale_y2 = "2.000000"
|
||||
scale_y2 = "1.000000"
|
||||
shader3 = "..\xbr\shaders\super-xbr\super-xbr-pass1.slang"
|
||||
filter_linear3 = "false"
|
||||
wrap_mode3 = "clamp_to_border"
|
||||
|
@ -40,9 +40,9 @@ alias3 = ""
|
|||
float_framebuffer3 = "false"
|
||||
srgb_framebuffer3 = "false"
|
||||
scale_type_x3 = "source"
|
||||
scale_x3 = "1.000000"
|
||||
scale_x3 = "2.000000"
|
||||
scale_type_y3 = "source"
|
||||
scale_y3 = "1.000000"
|
||||
scale_y3 = "2.000000"
|
||||
shader4 = "..\xbr\shaders\super-xbr\super-xbr-pass2.slang"
|
||||
filter_linear4 = "false"
|
||||
wrap_mode4 = "clamp_to_border"
|
||||
|
|
Loading…
Reference in a new issue