RetroArch-Wii-U-Slang-Shaders/quad/shaders/biquad.slang
2020-04-26 18:03:54 -05:00

133 lines
3.8 KiB
Text

#version 450
/*
Hyllian's biquad Shader
Copyright (C) 2011-2015 Hyllian/Jararaca - sergiogdb@gmail.com
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
layout(push_constant) uniform Push
{
vec4 SourceSize;
vec4 OriginalSize;
vec4 OutputSize;
uint FrameCount;
float K;
} params;
#pragma parameter K "Blurring Param" 0.8 0.0 1.0 0.01
#define K params.K
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
} global;
#define saturate(c) clamp(c, 0.0, 1.0)
#define lerp(c) mix(c)
#define mul(a,b) (b*a)
#define fmod(c) mod(c)
#define frac(c) fract(c)
#define tex2D(c,d) texture(c,d)
#define float2 vec2
#define float3 vec3
#define float4 vec4
#define int2 ivec2
#define int3 ivec3
#define int4 ivec4
#define bool2 bvec2
#define bool3 bvec3
#define bool4 bvec4
#define float2x2 mat2x2
#define float3x3 mat3x3
#define float4x4 mat4x4
#define s_p Source
// Calculates the distance between two points
float d(float2 pt1, float2 pt2)
{
float2 v = pt2 - pt1;
return sqrt(dot(v,v));
}
float3 resampler(float3 x)
{
float3 res;
res = lessThanEqual(x,float3(0.5, 0.5, 0.5)) == bvec3(true) ? (-2*K*x*x + 0.5*(K+1)) : (lessThanEqual(x,float3(1.5, 1.5, 1.5)) == bvec3(true) ? (K*x*x + (-2*K - 0.5)*x + 0.75*(K+1)) : float3(0.00001, 0.00001, 0.00001));
return res;
}
#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;
void main()
{
float3 color;
float3x3 weights;
float2 dx = float2(1.0, 0.0);
float2 dy = float2(0.0, 1.0);
float2 pc = vTexCoord*params.SourceSize.xy;
float2 tc = (floor(pc)+float2(0.5,0.5));
weights[0] = resampler(float3(d(pc, tc -dx -dy), d(pc, tc -dy), d(pc, tc +dx -dy)));
weights[1] = resampler(float3(d(pc, tc -dx ), d(pc, tc ), d(pc, tc +dx )));
weights[2] = resampler(float3(d(pc, tc -dx +dy), d(pc, tc +dy), d(pc, tc +dx +dy)));
dx = dx * params.SourceSize.zw;
dy = dy * params.SourceSize.zw;
tc = tc * params.SourceSize.zw;
// reading the texels
float3 c00 = tex2D(s_p, tc -dx -dy).xyz;
float3 c10 = tex2D(s_p, tc -dy).xyz;
float3 c20 = tex2D(s_p, tc +dx -dy).xyz;
float3 c01 = tex2D(s_p, tc -dx ).xyz;
float3 c11 = tex2D(s_p, tc ).xyz;
float3 c21 = tex2D(s_p, tc +dx ).xyz;
float3 c02 = tex2D(s_p, tc -dx +dy).xyz;
float3 c12 = tex2D(s_p, tc +dy).xyz;
float3 c22 = tex2D(s_p, tc +dx +dy).xyz;
color = mul(weights[0], float3x3(c00, c10, c20));
color+= mul(weights[1], float3x3(c01, c11, c21));
color+= mul(weights[2], float3x3(c02, c12, c22));
color = color/(dot(mul(weights, float3(1.0)), float3(1.0)));
// final sum and weight normalization
FragColor = vec4(color, 1.0);
}