comparison shaders/ntsc.f.glsl @ 2343:49bd818ec9d8

Updated NTSC shader from Sik
author Michael Pavone <pavone@retrodev.com>
date Sun, 01 Oct 2023 23:41:19 -0700
parents 06d5e9b08bdb
children f1574b22d5d9
comparison
equal deleted inserted replaced
2342:9f0c67e5c50a 2343:49bd818ec9d8
1 //****************************************************************************** 1 //******************************************************************************
2 // NTSC composite simulator for BlastEm 2 // NTSC composite simulator for BlastEm
3 // Shader by Sik, based on BlastEm's default shader 3 // Shader by Sik, based on BlastEm's default shader
4 //
5 // Now with gamma correction (NTSC = 2.5 gamma, sRGB = 2.2 gamma)
4 // 6 //
5 // It works by converting from RGB to YIQ and then encoding it into NTSC, then 7 // It works by converting from RGB to YIQ and then encoding it into NTSC, then
6 // trying to decode it back. The lossy nature of the encoding process results in 8 // trying to decode it back. The lossy nature of the encoding process results in
7 // the rainbow effect. It also accounts for the differences between H40 and H32 9 // the rainbow effect. It also accounts for the differences between H40 and H32
8 // mode as it computes the exact colorburst cycle length. 10 // mode as it computes the exact colorburst cycle length.
60 // handles interlaced mode (nothing to do with composite) 62 // handles interlaced mode (nothing to do with composite)
61 mediump float factorY = (sin(texcoord.y * texsize.y * 6.283185307) + 1.0) * 0.5; 63 mediump float factorY = (sin(texcoord.y * texsize.y * 6.283185307) + 1.0) * 0.5;
62 64
63 // Horizontal distance of half a colorburst cycle 65 // Horizontal distance of half a colorburst cycle
64 mediump float factorX = (1.0 / texsize.x) / 170.667 * 0.5 * (width - 27.0); 66 mediump float factorX = (1.0 / texsize.x) / 170.667 * 0.5 * (width - 27.0);
67
68 // sRGB has a gamma of 2.2 while NTSC has a gamma of 2.5
69 // Use this value to do gamma correction of every RGB value
70 mediump float gamma = 2.5 / 2.2;
65 71
66 // Where we store the sampled pixels. 72 // Where we store the sampled pixels.
67 // [0] = current pixel 73 // [0] = current pixel
68 // [1] = 1/4 colorburst cycles earlier 74 // [1] = 1/4 colorburst cycles earlier
69 // [2] = 2/4 colorburst cycles earlier 75 // [2] = 2/4 colorburst cycles earlier
140 0.375 * raw[4] * cos(phase[4]) + 146 0.375 * raw[4] * cos(phase[4]) +
141 0.25 * raw[5] * cos(phase[5]) + 147 0.25 * raw[5] * cos(phase[5]) +
142 0.125 * raw[6] * cos(phase[6]); 148 0.125 * raw[6] * cos(phase[6]);
143 149
144 // Convert YIQ back to RGB and output it 150 // Convert YIQ back to RGB and output it
145 gl_FragColor = yiq2rgba(vec3(y_mix, i_mix, q_mix)); 151 gl_FragColor = pow(yiq2rgba(vec3(y_mix, i_mix, q_mix)),
152 vec4(gamma, gamma, gamma, 1.0));
146 153
147 // If you're curious to see what the raw composite signal looks like, 154 // If you're curious to see what the raw composite signal looks like,
148 // comment out the above and uncomment the line below instead 155 // comment out the above and uncomment the line below instead
149 //gl_FragColor = vec4(raw[0], raw[0], raw[0], 1.0); 156 //gl_FragColor = vec4(raw[0], raw[0], raw[0], 1.0);
150 } 157 }