From 030724a9aea346e4a9843d5842fb28c6d6c4cf1a Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Thu, 9 Oct 2025 22:07:52 +0200 Subject: Rearrangement and refactoring and optimizations and more accuracy --- fragment_shader.glsl | 149 --------------------------------------------------- 1 file changed, 149 deletions(-) delete mode 100644 fragment_shader.glsl (limited to 'fragment_shader.glsl') diff --git a/fragment_shader.glsl b/fragment_shader.glsl deleted file mode 100644 index c21b2de..0000000 --- a/fragment_shader.glsl +++ /dev/null @@ -1,149 +0,0 @@ -// Specify default precision for fragment shaders - -out vec4 outcolor; -in vec2 frag_texture_coord; - -uniform vec2 resolution; -uniform vec2 src_image_size; -uniform float brightness; -uniform vec4 tone_data; -uniform bool crt_emulation; -uniform sampler2D iChannel0; - -vec3 CrtsFetch(vec2 uv) { - const float bias = 0.003333333; - return max(texture(iChannel0, uv, -16.0).rgb, vec3(bias)); -} - -#define CrtsRcpF1(x) (1.0 / (x)) -#define CrtsSatF1(x) clamp((x), 0.0, 1.0) -const float PI2 = 6.28318530717958; -const float HALF = 0.5; - -float CrtsMax3F1(float a, float b, float c) { - return max(a, max(b, c)); -} - -vec3 CrtsMask(vec2 pos, float dark) { - #ifdef CRTS_MASK_GRILLE - vec3 m = vec3(dark); - float x = fract(pos.x * (1.0 / 3.0)); - m.r = (x < (1.0 / 3.0)) ? 1.0 : dark; - m.g = (x >= (1.0 / 3.0) && x < (2.0 / 3.0)) ? 1.0 : dark; - m.b = (x >= (2.0 / 3.0)) ? 1.0 : dark; - return m; - #endif - - #ifdef CRTS_MASK_GRILLE_LITE - vec3 m = vec3(1.0); - float x = fract(pos.x * (1.0 / 3.0)); - m.r = (x < (1.0 / 3.0)) ? dark : 1.0; - m.g = (x >= (1.0 / 3.0) && x < (2.0 / 3.0)) ? dark : 1.0; - m.b = (x >= (2.0 / 3.0)) ? dark : 1.0; - return m; - #endif - - #ifdef CRTS_MASK_NONE - return vec3(1.0); - #endif - - #ifdef CRTS_MASK_SHADOW - pos.x += pos.y * 3.0; - vec3 m = vec3(dark); - float x = fract(pos.x * (1.0 / 6.0)); - m.r = (x < (1.0 / 3.0)) ? 1.0 : dark; - m.g = (x >= (1.0 / 3.0) && x < (2.0 / 3.0)) ? 1.0 : dark; - m.b = (x >= (2.0 / 3.0)) ? 1.0 : dark; - return m; - #endif -} - -vec3 CrtsFilter(vec2 ipos, vec2 inputSizeDivOutputSize, vec2 halfInputSize, vec2 rcpInputSize, vec2 rcpOutputSize, vec2 twoDivOutputSize, float inputHeight, vec2 warp, float thin, float blur, float mask, vec4 tone) { - vec2 pos = ipos * twoDivOutputSize - vec2(1.0); - pos *= vec2(1.0 + (pos.y * pos.y) * warp.x, 1.0 + (pos.x * pos.x) * warp.y); - float vin = 1.0 - ((1.0 - CrtsSatF1(pos.x * pos.x)) * (1.0 - CrtsSatF1(pos.y * pos.y))); - vin = CrtsSatF1((-vin) * inputHeight + inputHeight); - pos = pos * halfInputSize + halfInputSize; - - float y0 = floor(pos.y - 0.5) + 0.5; - float x0 = floor(pos.x - 1.5) + 0.5; - vec2 p = vec2(x0 * rcpInputSize.x, y0 * rcpInputSize.y); - - vec3 colA[4], colB[4]; - for (int i = 0; i < 4; i++) { - colA[i] = CrtsFetch(p); - p.x += rcpInputSize.x; - } - p.y += rcpInputSize.y; - for (int i = 3; i >= 0; i--) { - p.x -= rcpInputSize.x; - colB[i] = CrtsFetch(p); - } - - float off = pos.y - y0; - float scanA = cos(min(HALF, off * thin) * PI2) * HALF + HALF; - float scanB = cos(min(HALF, (-off) * thin + thin) * PI2) * HALF + HALF; - - float off0 = pos.x - x0; - float pix[4]; - for (int i = 0; i < 4; i++) { - float diff = off0 - float(i); - pix[i] = exp2(blur * diff * diff); - } - float pixT = CrtsRcpF1(pix[0] + pix[1] + pix[2] + pix[3]); - - #ifdef CRTS_WARP - pixT *= vin; - #endif - - scanA *= pixT; - scanB *= pixT; - - vec3 color = (colA[0] * pix[0] + colA[1] * pix[1] + colA[2] * pix[2] + colA[3] * pix[3]) * scanA + (colB[0] * pix[0] + colB[1] * pix[1] + colB[2] * pix[2] + colB[3] * pix[3]) * scanB; - color *= CrtsMask(ipos, mask); - - #ifdef CRTS_TONE - float peak = max(1.0 / (256.0 * 65536.0), CrtsMax3F1(color.r, color.g, color.b)); - vec3 ratio = color * CrtsRcpF1(peak); - #ifdef CRTS_CONTRAST - peak = pow(peak, tone.x); - #endif - peak = peak * CrtsRcpF1(peak * tone.y + tone.z); - #ifdef CRTS_SATURATION - ratio = pow(ratio, vec3(tone.w)); - #endif - return ratio * peak; - #else - return color; - #endif -} - -vec3 linearToSRGB(vec3 color) { - return pow(color, vec3(1.0 / 2.2)); -} - -void main() { - vec2 fragCoord = vec2(frag_texture_coord.x, 1.0 - frag_texture_coord.y); - if (crt_emulation) { - outcolor.rgb = CrtsFilter( - fragCoord.xy * resolution, - src_image_size / resolution, - src_image_size * vec2(0.5), - 1.0 / src_image_size, - 1.0 / resolution, - 2.0 / resolution, - src_image_size.y, - vec2(1.0 / 24.0, 1.0 / 16.0), // warp value - INPUT_THIN, - INPUT_BLUR, - INPUT_MASK, - tone_data - ); - - outcolor.rgb *= brightness; - outcolor = vec4(outcolor.rgb, 1.0); // Keep original color with alpha set to 1.0 - - } else { - outcolor = texture(iChannel0, fragCoord); - } -} -- cgit v1.2.3