summaryrefslogtreecommitdiff
path: root/shaders/gl_upscale_warp_fragment.glsl
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
committerPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
commit030724a9aea346e4a9843d5842fb28c6d6c4cf1a (patch)
treef06fb84aaef64b2f4e2d81b3d2d3eef71bad83ec /shaders/gl_upscale_warp_fragment.glsl
parent412b2ef851516c1de8ba5006ddd284192cbcaf9b (diff)
Rearrangement and refactoring and optimizations and more accuracy
Diffstat (limited to 'shaders/gl_upscale_warp_fragment.glsl')
-rw-r--r--shaders/gl_upscale_warp_fragment.glsl36
1 files changed, 36 insertions, 0 deletions
diff --git a/shaders/gl_upscale_warp_fragment.glsl b/shaders/gl_upscale_warp_fragment.glsl
new file mode 100644
index 0000000..26f0202
--- /dev/null
+++ b/shaders/gl_upscale_warp_fragment.glsl
@@ -0,0 +1,36 @@
+out vec4 outcolor;
+in vec2 frag_texture_coord;
+
+uniform sampler2D source;
+uniform vec2 resolution;
+uniform vec2 src_image_size;
+
+void main() {
+ // Match CRT shader coordinate system exactly
+ vec2 half_pixel = 0.5 / src_image_size;
+ vec2 fragCoord = vec2(frag_texture_coord.x, 1.0 - frag_texture_coord.y) + half_pixel;
+
+ // Convert to pixel coordinates and add pixel centering offset
+ vec2 ipos = fragCoord * resolution + vec2(0.5);
+
+ // Convert to normalized device coordinates [-1, 1]
+ vec2 pos = ipos * (2.0 / resolution) - vec2(1.0);
+
+ // Apply barrel distortion (match CRT warp)
+ vec2 warp = vec2(1.0 / 24.0, 1.0 / 16.0);
+ pos *= vec2(
+ 1.0 + (pos.y * pos.y) * warp.x,
+ 1.0 + (pos.x * pos.x) * warp.y
+ );
+
+ // Convert back to UV coordinates
+ vec2 uv = (pos + vec2(1.0)) * 0.5;
+
+ // Sample from source with boundary check
+ if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
+ outcolor = vec4(0.0, 0.0, 0.0, 1.0);
+ } else {
+ // Sample directly (Y-flip already applied at line 11)
+ outcolor = texture(source, uv, -16.0);
+ }
+}