diff options
Diffstat (limited to 'assets/shaders')
| -rw-r--r-- | assets/shaders/ntsc.fs | 99 | ||||
| -rw-r--r-- | assets/shaders/ps1frag.fs | 18 | ||||
| -rw-r--r-- | assets/shaders/ps1vert.vs | 26 | ||||
| -rw-r--r-- | assets/shaders/psx_filter.fs | 38 | ||||
| -rw-r--r-- | assets/shaders/rvm.fs | 208 |
5 files changed, 389 insertions, 0 deletions
diff --git a/assets/shaders/ntsc.fs b/assets/shaders/ntsc.fs new file mode 100644 index 0000000..871565b --- /dev/null +++ b/assets/shaders/ntsc.fs @@ -0,0 +1,99 @@ +#version 330 + +in vec2 fragTexCoord; +uniform sampler2D texture0; + +vec3 rgb2yiq(vec3 c){ + return vec3( + (0.2989 * c.x + 0.5959 * c.y + 0.2115 * c.z), + (0.5870 * c.x - 0.2744 * c.y - 0.5229 * c.z), + (0.1140 * c.x - 0.3216 * c.y + 0.3114 * c.z) + ); +} +vec3 yiq2rgb(vec3 c){ + return vec3( + (1.0 * c.x + 1.0 * c.y + 1.0 * c.z), + (0.956 * c.x - 0.2720 * c.y - 1.1060 * c.z), + (0.6210 * c.x - 0.6474 * c.y + 1.7046 * c.z) + ); +} + +vec2 Circle(float Start, float Points, float Point){ + float Rad = (3.141592 * 2.0 * (1.0 / Points)) * (Point + Start); + return vec2(-(.3+Rad), cos(Rad)); +} + +vec3 Blur(vec2 uv, float f, float d, sampler2D iChannel0){ + vec2 PixelOffset = vec2(d, 0); + + float Start = 2.0 / 14.0; + vec2 Scale = 0.66 * 3.0 * 2.0 * PixelOffset.xy; + + vec3 N0 = texture(iChannel0, uv + Circle(Start, 14.0, 0.0) * Scale).rgb; + vec3 N1 = texture(iChannel0, uv + Circle(Start, 14.0, 1.0) * Scale).rgb; + vec3 N2 = texture(iChannel0, uv + Circle(Start, 14.0, 2.0) * Scale).rgb; + vec3 N3 = texture(iChannel0, uv + Circle(Start, 14.0, 3.0) * Scale).rgb; + vec3 N4 = texture(iChannel0, uv + Circle(Start, 14.0, 4.0) * Scale).rgb; + vec3 N5 = texture(iChannel0, uv + Circle(Start, 14.0, 5.0) * Scale).rgb; + vec3 N6 = texture(iChannel0, uv + Circle(Start, 14.0, 6.0) * Scale).rgb; + vec3 N7 = texture(iChannel0, uv + Circle(Start, 14.0, 7.0) * Scale).rgb; + vec3 N8 = texture(iChannel0, uv + Circle(Start, 14.0, 8.0) * Scale).rgb; + vec3 N9 = texture(iChannel0, uv + Circle(Start, 14.0, 9.0) * Scale).rgb; + vec3 N10 = texture(iChannel0, uv + Circle(Start, 14.0, 10.0) * Scale).rgb; + vec3 N11 = texture(iChannel0, uv + Circle(Start, 14.0, 11.0) * Scale).rgb; + vec3 N12 = texture(iChannel0, uv + Circle(Start, 14.0, 12.0) * Scale).rgb; + vec3 N13 = texture(iChannel0, uv + Circle(Start, 14.0, 13.0) * Scale).rgb; + vec3 N14 = texture(iChannel0, uv).rgb; + + vec3 clr = N14; + float W = 1.0 / 15.0; + + clr = + (N0 * W) + + (N1 * W) + + (N2 * W) + + (N3 * W) + + (N4 * W) + + (N5 * W) + + (N6 * W) + + (N7 * W) + + (N8 * W) + + (N9 * W) + + (N10 * W) + + (N11 * W) + + (N12 * W) + + (N13 * W) + + (N14 * W); + + return clr; +} + +out vec4 finalColor; + +void main(){ + vec2 uv = gl_FragCoord.xy / vec2(textureSize(texture0, 0)); + vec3 color; + + // Apply blur + float d = 0.051; + float c = 0.002 * d; + + color.xyz = Blur(uv, 0.0, c + c * (uv.x), texture0); + float y = rgb2yiq(color.xyz).r; + + uv.x += 0.01 * d; + c *= 6.0; + color.xyz = Blur(uv, 0.333, c, texture0); + float i = rgb2yiq(color.xyz).g; + + uv.x += 0.005 * d; + + c *= 2.50; + color.xyz = Blur(uv, 0.666, c + c * (-uv.x), texture0); + float q = rgb2yiq(color.xyz).b; + + color.xyz = yiq2rgb(vec3(y, i, q)); + color.xyz *= smoothstep(1.0, 0.999, uv.x - .1); + + finalColor = vec4(color, 1.0); +}
\ No newline at end of file diff --git a/assets/shaders/ps1frag.fs b/assets/shaders/ps1frag.fs new file mode 100644 index 0000000..efdb0b8 --- /dev/null +++ b/assets/shaders/ps1frag.fs @@ -0,0 +1,18 @@ +#version 330 + +noperspective in vec2 fragTexCoord; +noperspective in vec3 fragColor; + +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +out vec4 finalColor; + +void main() +{ + vec4 texelColor = texture(texture0, fragTexCoord); + if(texelColor.a < 0.8) + discard; + + finalColor = texelColor*colDiffuse*vec4(fragColor, 1.0); +}
\ No newline at end of file diff --git a/assets/shaders/ps1vert.vs b/assets/shaders/ps1vert.vs new file mode 100644 index 0000000..7d8d506 --- /dev/null +++ b/assets/shaders/ps1vert.vs @@ -0,0 +1,26 @@ +#version 330 + +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +uniform mat4 mvp; + +noperspective out vec2 fragTexCoord; +noperspective out vec3 fragColor; + +void main() +{ + vec2 res = vec2(160.0, 120.0); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor.rgb; + + vec4 pop = mvp*vec4(vertexPosition, 1.0); + gl_Position = pop; + gl_Position.xyz = pop.xyz / pop.w; + gl_Position.xy = floor(res * gl_Position.xy) / res; + gl_Position.xyz *= pop.w; + + fragColor = mix(fragColor, vec3(0.0), clamp(smoothstep(20.0, 24.0, length(pop.xyz)), 0.0, 1.0)); +}
\ No newline at end of file diff --git a/assets/shaders/psx_filter.fs b/assets/shaders/psx_filter.fs new file mode 100644 index 0000000..21eaada --- /dev/null +++ b/assets/shaders/psx_filter.fs @@ -0,0 +1,38 @@ +#version 330 + +uniform sampler2D texture0; + +in vec2 fragTexCoord; + +out vec4 finalColor; + +const float neareight = 255.0; +vec3 dither(vec3 col, uvec2 fc) +{ + const int mat[16] = int[16] ( + -4, 0, -3, 1, + 2, -2, 3, -1, + -3, 1, -4, 0, + 3, -1, 2, -2 + ); + + ivec3 uncol = ivec3(col * neareight) + mat[(fc.y & uint(3)) * uint(4) + (fc.x & uint(3))]; + return vec3(uncol) / neareight; +} + +vec3 band_color(vec3 lol) +{ + ivec3 res = ivec3(clamp(lol, 0.0, 1.0) * neareight) & ivec3(0xFF); + ivec3 ires = res >> 3; + ivec3 dres = (ires >> 2) & ivec3(7); + res = (ires << 3) | dres; + return vec3(res) / neareight; +} + +void main() +{ + vec4 texelColor = texture(texture0, fragTexCoord); + texelColor.rgb = band_color(dither(texelColor.rgb, uvec2(gl_FragCoord.xy))); + + finalColor = texelColor; +}
\ No newline at end of file diff --git a/assets/shaders/rvm.fs b/assets/shaders/rvm.fs new file mode 100644 index 0000000..3f94c52 --- /dev/null +++ b/assets/shaders/rvm.fs @@ -0,0 +1,208 @@ +#version 330 + +in vec2 fragTexCoord; + +uniform sampler2D texture0; +uniform vec4 resolution; + +// Horizonal scan blur +// 0.50 := blurry +// 0.75 := default +// 1.00 := blocky +#define INPUT_BLUR 0.5 + +//-------------------------------------------------------------- +// Setup the function which returns gather4 results +// Have to emulate gather4 as ShaderToy doesn't support it +// Gather 4 ordering +// W Z +// X Y +vec4 RvmR4F(sampler2D tex, vec2 uv){ + vec2 px = vec2(1.0) / vec2(textureSize(tex, 0)); + px *= 0.5; + + vec4 sample; + sample.w = texture(tex, uv.xy + vec2(-px.x,-px.y)).r; + sample.z = texture(tex, uv.xy + vec2( px.x,-px.y)).r; + sample.x = texture(tex, uv.xy + vec2(-px.x, px.y)).r; + sample.y = texture(tex, uv.xy + vec2( px.x, px.y)).r; + + return sample; +} +// +vec4 RvmG4F(sampler2D tex, vec2 uv){ + vec2 px = vec2(1.0) / vec2(textureSize(tex, 0)); + px *= 0.5; + + vec4 sample; + sample.w = texture(tex, uv.xy + vec2(-px.x,-px.y)).g; + sample.z = texture(tex, uv.xy + vec2( px.x,-px.y)).g; + sample.x = texture(tex, uv.xy + vec2(-px.x, px.y)).g; + sample.y = texture(tex, uv.xy + vec2( px.x, px.y)).g; + + return sample; +} +// +vec4 RvmB4F(sampler2D tex, vec2 uv){ + vec2 px = vec2(1.0) / vec2(textureSize(tex, 0)); + px *= 0.5; + + vec4 sample; + sample.w = texture(tex, uv.xy + vec2(-px.x,-px.y)).b; + sample.z = texture(tex, uv.xy + vec2( px.x,-px.y)).b; + sample.x = texture(tex, uv.xy + vec2(-px.x, px.y)).b; + sample.y = texture(tex, uv.xy + vec2( px.x, px.y)).b; + + return sample; +} + +#define RVM_DARK 1 +#define RVM_SCAN_DIV 3.0 +#define RVM_SCAN_MAX (8.0/15.0) +#define RVM_SCAN_MIN (RVM_SCAN_DIV*RVM_SCAN_MAX) +#define RVM_SCAN_SIZ (RVM_SCAN_MAX-RVM_SCAN_MIN) + +vec2 RvmPolyF2(vec2 x){ + x=clamp(-x*x+vec2(1.0,1.0), 0.0, 1.0); + return x*x; +} + +vec3 rvm_func( +sampler2D tex, +//-------------------------------------------------------------- + // SV_POSITION, fragCoord.xy, etc + vec2 ipos, +//-------------------------------------------------------------- + // inputSize / outputSize (in pixels) + vec2 inputSizeDivOutputSize, +//-------------------------------------------------------------- + // 0.5 * inputSize (in pixels) + vec2 halfInputSize, +//-------------------------------------------------------------- + // 1.0 / inputSize (in pixels) + vec2 rcpInputSize, +//-------------------------------------------------------------- + // 2.0 / outputSize (in pixels) + vec2 twoDivOutputSize, +//-------------------------------------------------------------- + // inputSize.y + float inputHeight, +//-------------------------------------------------------------- + // Warp scanlines + // 0.0 = no warp + // 1.0/64.0 = light warping + // 1.0/32.0 = more warping + // Want x and y warping to be different (based on aspect) + vec2 warp, +//-------------------------------------------------------------- + // Control horizontal blur + // 0.50 := blurry + // 0.75 := default + // 1.00 := blocky + float blur, + // Derived constant {0.5*blur,-0.5*blur,-1.5*blur,-2.5*blur} + vec4 blur4){ + // Optional apply warp + vec2 pos; + pos=ipos*inputSizeDivOutputSize; + pos -= (halfInputSize * 2.0) / (resolution.zw / resolution.xy); + + // Get to center for first gather 4 + // W Z + // X Y + // W Z + // X Y + vec2 g=floor(pos+vec2(-0.5,-1.5))+vec2(1.0); + vec2 gp=g*rcpInputSize; + g.x-=float(0.5); + + // 2x4 sampled footprint + // W Z |s + // X Y |s + // W Z :t + // X Y :t + vec4 colRS=RvmR4F(tex, gp); + vec4 colGS=RvmG4F(tex, gp); + vec4 colBS=RvmB4F(tex, gp); + gp.y+=float(2.0*rcpInputSize.y); + vec4 colRT=RvmR4F(tex, gp); + vec4 colGT=RvmG4F(tex, gp); + vec4 colBT=RvmB4F(tex, gp); + + // Vertical + float offB=float(pos.y-g.y); + vec2 offS=vec2(offB,offB)*vec2(blur)+blur4.xy; + vec2 offT=vec2(offB,offB)*vec2(blur)+blur4.zw; + + vec2 horS=RvmPolyF2(offS); + vec2 horT=RvmPolyF2(offT); + + // Get kernel totals and then rcp + vec2 hor0=horS+horT; + float horD=1.0 / (hor0.x+hor0.y); + + //horD*=float(vin); + + // Apply vertical filter + vec2 colRL=colRS.wz*horS.xx+colRS.xy*horS.yy+ + colRT.wz*horT.xx+colRT.xy*horT.yy; + vec2 colGL=colGS.wz*horS.xx+colGS.xy*horS.yy+ + colGT.wz*horT.xx+colGT.xy*horT.yy; + vec2 colBL=colBS.wz*horS.xx+colBS.xy*horS.yy+ + colBT.wz*horT.xx+colBT.xy*horT.yy; + + // Normalize by kernel total + colRL*=vec2(horD); + colGL*=vec2(horD); + colBL*=vec2(horD); + + float offX=float(pos.x-g.x); + vec2 scnL=vec2(float(1.0)-offX,offX); + // Apply scan + colRL*=scnL; + colGL*=scnL; + colBL*=scnL; + // Merge contribution from both nearest lines + vec3 col; + col.r=colRL.x+colRL.y; + col.g=colGL.x+colGL.y; + col.b=colBL.x+colBL.y; + + // Slot mask + float lim=float(1.0/((3.0/12.0)+(9.0/12.0)*RVM_DARK)); + if(fract(ipos.x*float(1.0/6.0))>float(0.5)) + ipos.y+=float(2.0); + ipos.y=fract(ipos.y*float(1.0/4.0)); + + vec3 colD=col*col; + + colD*=RVM_DARK; + + vec3 amp= vec3(1.0) / vec3( + vec3(lim*3.0/12.0)+vec3(lim*9.0/12.0)*col); + ipos.x=fract(ipos.x*float(1.0/3.0)); + + col*=amp;colD*=amp; + if(ipos.y>float(1.0/4.0)){ + if( ipos.x<float(1.0/3.0)){colD.r=col.r;} + else if(ipos.x<float(2.0/3.0)){colD.g=col.g;} + else {colD.b=col.b;} + } + return colD; +//-------------------------------------------------------------- + return col; +} + +out vec4 finalColor; + +void main() { + vec2 input_size = vec2(textureSize(texture0, 0)); + vec2 out_size = resolution.zw; + + vec3 color = rvm_func(texture0, + gl_FragCoord.xy, input_size / out_size, + input_size * 0.5, 1.0 / input_size, 2.0 / out_size, input_size.y, vec2(1.0/48.0,1.0/24.0), INPUT_BLUR, + vec4(0.5*INPUT_BLUR,-0.5*INPUT_BLUR,-1.5*INPUT_BLUR,-2.5*INPUT_BLUR)); + + finalColor = vec4(color, 1.0); +} |
