Mercurial > repos > blastem
comparison shaders/crt.f.glsl @ 1977:f3cca4b3f17a
Allow use of NPOT textures as a config option. Useful for some mobile GPUs
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 09 May 2020 21:15:33 -0700 |
parents | 7da675d0c512 |
children |
comparison
equal
deleted
inserted
replaced
1976:3dd9c68472fb | 1977:f3cca4b3f17a |
---|---|
1 #version 110 | |
2 | |
3 /* Subtle CRT shader usable in fullscreen - Anaël Seghezzi [anael(at)maratis3d.com] | 1 /* Subtle CRT shader usable in fullscreen - Anaël Seghezzi [anael(at)maratis3d.com] |
4 This shader is free software distributed under the terms of the GNU General Public | 2 This shader is free software distributed under the terms of the GNU General Public |
5 License version 3 or higher. This gives you the right to redistribute and/or | 3 License version 3 or higher. This gives you the right to redistribute and/or |
6 modify the program as long as you follow the terms of the license. See the file | 4 modify the program as long as you follow the terms of the license. See the file |
7 COPYING for full license details. | 5 COPYING for full license details. |
8 */ | 6 */ |
9 | 7 |
10 #define M_PI 3.14159265358979323846 | 8 #define M_PI 3.14159265358979323846 |
11 | 9 |
12 uniform sampler2D textures[2]; | 10 uniform sampler2D textures[2]; |
13 uniform float width, height; | 11 uniform mediump float width, height; |
14 varying vec2 texcoord; | 12 uniform mediump vec2 texsize; |
15 varying vec2 screencoord; | 13 varying mediump vec2 texcoord; |
14 varying mediump vec2 screencoord; | |
16 | 15 |
17 | 16 |
18 float nrand(vec2 n) { | 17 mediump float nrand(vec2 n) { |
19 return fract(sin(dot(n.xy, vec2(12.9898, 78.233))) * 43758.5453); | 18 return fract(sin(dot(n.xy, vec2(12.9898, 78.233))) * 43758.5453); |
20 } | 19 } |
21 | 20 |
22 float scanline(vec2 texco) | 21 mediump float scanline(vec2 texco) |
23 { | 22 { |
24 return (1.0 - abs(cos(texco.y * 512.0 * M_PI))); | 23 return (1.0 - abs(cos(texco.y * texsize.y * M_PI))); |
25 } | 24 } |
26 | 25 |
27 vec2 sharp_coord(vec2 texco, vec2 dim, vec2 sharpness) | 26 mediump vec2 sharp_coord(mediump vec2 texco, mediump vec2 dim, mediump vec2 sharpness) |
28 { | 27 { |
29 vec2 texcoif = texco * dim; | 28 mediump vec2 texcoif = texco * dim; |
30 vec2 texcoi = floor(texcoif); | 29 mediump vec2 texcoi = floor(texcoif); |
31 vec2 mu = (texcoif - 0.5) - texcoi; | 30 mediump vec2 mu = (texcoif - 0.5) - texcoi; |
32 vec2 mub = pow(abs(mu) * 2.0, sharpness) * sign(mu) * 0.5; | 31 mediump vec2 mub = pow(abs(mu) * 2.0, sharpness) * sign(mu) * 0.5; |
33 return (texcoi + mub + 0.5) / dim; | 32 return (texcoi + mub + 0.5) / dim; |
34 } | 33 } |
35 | 34 |
36 void main() | 35 void main() |
37 { | 36 { |
38 float v = 1.0 / 512.0; | 37 mediump float v = 1.0 / texsize.y; |
39 float yforce = 0.175; | 38 mediump float yforce = 0.175; |
40 float vign = length(screencoord); | 39 mediump float vign = length(screencoord); |
41 | 40 |
42 // monitor deformation | 41 // monitor deformation |
43 vec2 monitorcoord = (screencoord + screencoord * vign * 0.025); | 42 mediump vec2 monitorcoord = (screencoord + screencoord * vign * 0.025); |
44 | 43 |
45 if (monitorcoord.x < -1.0 || monitorcoord.y < -1.0 || monitorcoord.x > 1.0 || monitorcoord.y > 1.0) { | 44 if (monitorcoord.x < -1.0 || monitorcoord.y < -1.0 || monitorcoord.x > 1.0 || monitorcoord.y > 1.0) { |
46 gl_FragColor = vec4(0.0); | 45 gl_FragColor = vec4(0.0); |
47 return; | 46 return; |
48 } | 47 } |
49 | 48 |
50 vec2 texco = monitorcoord * vec2(width/1024.0, height/-1024.0) + vec2(width/1024.0, height/1024.0); | 49 mediump vec2 texco = monitorcoord * vec2(0.5*width/texsize.x, -0.5 * height/texsize.y) + vec2(0.5*width/texsize.x, 0.5*height/texsize.y); |
51 | 50 |
52 // mask | 51 // mask |
53 float maskx = 1.0 - pow(abs(monitorcoord.x), 200.0); | 52 mediump float maskx = 1.0 - pow(abs(monitorcoord.x), 200.0); |
54 float masky = 1.0 - pow(abs(-monitorcoord.y), 200.0); | 53 mediump float masky = 1.0 - pow(abs(-monitorcoord.y), 200.0); |
55 float mask = clamp(maskx * masky, 0.0, 1.0); | 54 mediump float mask = clamp(maskx * masky, 0.0, 1.0); |
56 | 55 |
57 // sharp texcoord | 56 // sharp texcoord |
58 vec2 texco_sharp0 = sharp_coord(texco, vec2(512.0, 512.0), vec2(4.0, 8.0)); | 57 mediump vec2 texco_sharp0 = sharp_coord(texco, texsize, vec2(4.0, 8.0)); |
59 vec2 texco_sharp1 = sharp_coord(texco - vec2(0.0, 1.0 / 1024.0), vec2(512.0, 512.0), vec2(4.0, 8.0)); | 58 mediump vec2 texco_sharp1 = sharp_coord(texco - vec2(0.0, 0.5 / texsize.y), texsize, vec2(4.0, 8.0)); |
60 | 59 |
61 vec4 src0 = texture2D(textures[0], texco_sharp0); | 60 mediump vec4 src0 = texture2D(textures[0], texco_sharp0); |
62 vec4 src1 = texture2D(textures[1], texco_sharp1); | 61 mediump vec4 src1 = texture2D(textures[1], texco_sharp1); |
63 | 62 |
64 // interlace mix | 63 // interlace mix |
65 float interlace = cos((texco.y * 1024.0) * M_PI); | 64 mediump float interlace = cos((texco.y * 2.0 * texsize.y) * M_PI); |
66 vec4 src_mix = mix(src0, src1, interlace * 0.5 + 0.5); | 65 mediump vec4 src_mix = mix(src0, src1, interlace * 0.5 + 0.5); |
67 | 66 |
68 // blur | 67 // blur |
69 vec4 src_blur = mix(texture2D(textures[0], texco), texture2D(textures[1], texco), 0.5); | 68 mediump vec4 src_blur = mix(texture2D(textures[0], texco), texture2D(textures[1], texco), 0.5); |
70 | 69 |
71 #ifdef NO_SCANLINE | 70 #ifdef NO_SCANLINE |
72 | 71 |
73 gl_FragColor = (src_mix * 0.95 + (src_blur * (1.6 - vign * 0.4) * 0.1)) * mask; | 72 gl_FragColor = (src_mix * 0.95 + (src_blur * (1.6 - vign * 0.4) * 0.1)) * mask; |
74 | 73 |
75 #else | 74 #else |
76 // multisample scanline with grain | 75 // multisample scanline with grain |
77 // TODO: offset grain with time (needs a "frame" uniform) | 76 // TODO: offset grain with time (needs a "frame" uniform) |
78 float cosy; | 77 mediump float cosy; |
79 cosy = scanline(texco + vec2(0.125, v * (nrand(texcoord + vec2(0.0, 1.0)) * 0.25) + 0.3333)); | 78 cosy = scanline(texco + vec2(0.125, v * (nrand(texcoord + vec2(0.0, 512.0/texsize.y)) * 0.25) + 512.0*0.3333/texsize.y)); |
80 cosy += scanline(texco + vec2(0.25, v * (nrand(texcoord + vec2(0.0, 2.0)) * 0.25) + 0.25)); | 79 cosy += scanline(texco + vec2(0.25, v * (nrand(texcoord + vec2(0.0, 1024.0/texsize.y)) * 0.25) + 512.0*0.25/texsize.y)); |
81 cosy += scanline(texco + vec2(0.50, v * (nrand(texcoord + vec2(0.0, 3.0)) * 0.25) + 0.6666)); | 80 cosy += scanline(texco + vec2(0.50, v * (nrand(texcoord + vec2(0.0, 1536.0/texsize.y)) * 0.25) + 512.0*0.6666/texsize.y)); |
82 cosy += scanline(texco + vec2(0.75, v * (nrand(texcoord + vec2(0.0, 4.0)) * 0.25) + 0.75)); | 81 cosy += scanline(texco + vec2(0.75, v * (nrand(texcoord + vec2(0.0, 2048.0/texsize.y)) * 0.25) + 512.0*0.75/texsize.y)); |
83 cosy *= 0.25; | 82 cosy *= 0.25; |
84 | 83 |
85 // final scanline + burn | 84 // final scanline + burn |
86 gl_FragColor = ((src_mix * ((1.0 - yforce) + cosy * yforce)) + (src_blur * (1.6 - vign * 0.4) * 0.1)) * mask; | 85 gl_FragColor = ((src_mix * ((1.0 - yforce) + cosy * yforce)) + (src_blur * (1.6 - vign * 0.4) * 0.1)) * mask; |
87 | 86 |