mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-23 16:11:31 +11:00
119 lines
3.8 KiB
Plaintext
119 lines
3.8 KiB
Plaintext
|
#version 450
|
||
|
|
||
|
layout(push_constant) uniform Push
|
||
|
{
|
||
|
vec4 SourceSize;
|
||
|
vec4 OriginalSize;
|
||
|
vec4 OutputSize;
|
||
|
uint FrameCount;
|
||
|
vec4 encode_passSize;
|
||
|
} params;
|
||
|
|
||
|
#define phase params.FrameCount
|
||
|
|
||
|
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 texCoord;
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
gl_Position = global.MVP * Position;
|
||
|
texCoord = TexCoord;
|
||
|
}
|
||
|
|
||
|
#pragma stage fragment
|
||
|
layout(location = 0) in vec2 texCoord;
|
||
|
layout(location = 0) out vec4 FragColor;
|
||
|
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||
|
layout(set = 0, binding = 3) uniform sampler2D encode_pass;
|
||
|
|
||
|
vec4 decode_sample(vec2 shift) {
|
||
|
const float min = 0.350*0.746;
|
||
|
const float max = 1.962;
|
||
|
const float black = 0.518;
|
||
|
vec2 coord = texCoord + params.encode_passSize.zw*shift;
|
||
|
if (coord.x < 0.0 || coord.x > 1.0 || coord.y < 0.0 || coord.y > 1.0) return vec4(0.0);
|
||
|
return (texture(encode_pass, coord) * vec4(max-min) + vec4(min-black)) / vec4(max-black);
|
||
|
}
|
||
|
|
||
|
vec3 filtsample(vec2 shift) {
|
||
|
vec2 coord = texCoord + params.SourceSize.zw*shift;
|
||
|
if (coord.x < 0.0 || coord.x > 1.0 || coord.y < 0.0 || coord.y > 1.0) return vec3(0.0);
|
||
|
return texture(Source, texCoord + params.SourceSize.zw*shift).xyz-vec3(0,0.5,0.5);
|
||
|
}
|
||
|
|
||
|
void main()
|
||
|
{
|
||
|
vec4 samps[] = vec4[](decode_sample(vec2(-1,0)),
|
||
|
decode_sample(vec2( 0,0)),
|
||
|
decode_sample(vec2( 1,0)));
|
||
|
// quarter-pixel shift between scanlines needed for comb filter
|
||
|
vec4 s1, s2, s3, s4;
|
||
|
s1 = decode_sample(vec2(-2,-1));
|
||
|
s2 = decode_sample(vec2(-1,-1));
|
||
|
s3 = decode_sample(vec2( 0,-1));
|
||
|
s4 = decode_sample(vec2( 1,-1));
|
||
|
vec4 samps_prev[] = vec4[](vec4(s1.zw,s2.xy),
|
||
|
vec4(s2.zw,s3.xy),
|
||
|
vec4(s3.zw,s4.xy));
|
||
|
s1 = decode_sample(vec2(-1,1));
|
||
|
s2 = decode_sample(vec2(-0,1));
|
||
|
s3 = decode_sample(vec2( 1,1));
|
||
|
s4 = decode_sample(vec2( 2,1));
|
||
|
vec4 samps_next[] = vec4[](vec4(s1.zw,s2.xy),
|
||
|
vec4(s2.zw,s3.xy),
|
||
|
vec4(s3.zw,s4.xy));
|
||
|
|
||
|
uint x = uint(floor(texCoord.x*params.SourceSize.x));
|
||
|
uint y = uint(floor(texCoord.y*params.SourceSize.y));
|
||
|
uint p = (x+y+uint(phase)) % 3u;
|
||
|
|
||
|
const vec4 one = vec4(1.0);
|
||
|
const vec4 PI_6 = vec4(3.14159265359/6.0);
|
||
|
const vec4 offs = vec4(-0.0);
|
||
|
const vec4 sins[] = vec4[](sin((vec4(0,1, 2, 3)+offs)*PI_6),
|
||
|
sin((vec4(4,5, 6, 7)+offs)*PI_6),
|
||
|
sin((vec4(8,9,10,11)+offs)*PI_6));
|
||
|
const vec4 coss[] = vec4[](cos((vec4(0,1, 2, 3)+offs)*PI_6),
|
||
|
cos((vec4(4,5, 6, 7)+offs)*PI_6),
|
||
|
cos((vec4(8,9,10,11)+offs)*PI_6));
|
||
|
|
||
|
vec3 filt = filtsample(vec2(0, 0));
|
||
|
vec3 filt_cur = (filt + filtsample(vec2(-1,0))+filtsample(vec2(1,0)))/3.0;
|
||
|
vec3 filt_prev = (filtsample(vec2(0,-1))+filtsample(vec2(-1,-1))+filtsample(vec2(1,-1)))/3.0;
|
||
|
vec3 filt_next = (filtsample(vec2(0, 1))+filtsample(vec2(-1, 1))+filtsample(vec2(1, 1)))/3.0;
|
||
|
vec3 dif1 = filt_cur-filt_prev;
|
||
|
vec3 dif2 = filt_cur-filt_next;
|
||
|
// this formula can be tweaked
|
||
|
float xprev = clamp(0.5-sqrt(dot(dif1,dif1)),0,0.5);
|
||
|
float xnext = clamp(0.5-sqrt(dot(dif2,dif2)),0,0.5);
|
||
|
float xcur = clamp(xprev+xnext,0,0.5);
|
||
|
float scale = (xcur+0.0001)/(xprev+xnext+0.0001);
|
||
|
xprev *= scale;
|
||
|
xnext *= scale;
|
||
|
float xfilt = 1.0 - 2.0*xcur;
|
||
|
|
||
|
vec3 yiq = vec3(0.0);
|
||
|
yiq.x = xcur*dot(samps[1],one) + xprev*dot(samps_prev[1],one) + xnext*dot(samps_next[1],one);
|
||
|
for (uint i = 0u; i < 3u; i++) {
|
||
|
samps[i] = xcur*samps[i] - xprev*samps_prev[i] - xnext*samps_next[i];
|
||
|
yiq.y += dot(samps[i],coss[(i+p+2u)%3u]);
|
||
|
yiq.z += dot(samps[i],sins[(i+p+2u)%3u]);
|
||
|
}
|
||
|
|
||
|
yiq *= vec3(1.0/4.0, 1.0/6.0, 1.0/6.0);
|
||
|
yiq += xfilt*filt;
|
||
|
|
||
|
//FragColor = vec4(dot(yiq, vec3(1.0, 0.946882, 0.623557)),
|
||
|
// dot(yiq, vec3(1.0,-0.274788,-0.635691)),
|
||
|
// dot(yiq, vec3(1.0,-1.108545, 1.709007)),
|
||
|
// 0.0);
|
||
|
FragColor = vec4(yiq+vec3(0,0.5,0.5),0.0);
|
||
|
}
|