aboutsummaryrefslogtreecommitdiff
path: root/assets/shaders/rvm.fs
diff options
context:
space:
mode:
authorUneven Prankster <unevenprankster@protonmail.com>2023-11-16 21:12:27 -0300
committerUneven Prankster <unevenprankster@protonmail.com>2023-11-16 21:12:27 -0300
commit2bbf92ad5ae7708bf18ac7ef333e9a979d8d1bde (patch)
treec9d22bb0d73d9cc0c8586e4d31c93a561ea8e910 /assets/shaders/rvm.fs
parent1c0cc775732201f4c4d3ee0d6772be786b3b4aa1 (diff)
Working so hard like a soldiermain
Can't afford a thing on TV
Diffstat (limited to 'assets/shaders/rvm.fs')
-rw-r--r--assets/shaders/rvm.fs208
1 files changed, 208 insertions, 0 deletions
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);
+}