diff options
author | 2017-12-29 20:37:44 -0800 | |
---|---|---|
committer | 2017-12-30 00:16:41 -0800 | |
commit | 6c456a286507d4d0ba1acb4b9015f9933e2351a4 (patch) | |
tree | 8c6cbcc56d154acd3bb4d6ee3123cbce5f3bff4d /src/osd/modules/opengl | |
parent | 1624208a65ab573b85ce72788ec1b2332846eccb (diff) |
Fix Two Issues with the glsl Bilinear Shader
1. Off-by-one pixel coordinates
2. Sampling of wrong pixels at some non-integer stretch factors
First was noticed while comparing screenshots of the software and opengl w/glsl renderers (opengl output was shifted up and to the right). Fixed by subtracting a 1/2 pixel from the texture coordinates when calculating the bottom left pixel to use for interpolation.
Second was apparent when running pac-man fullscreen on a 1920x1080 screen and allowing non-integer stretching. Manifested as irregular horizontal 'steps' in the output. Fixed by sampling from the center of all pixels which should avoid any funny business in regards to pixel coordinate rounding.
Diffstat (limited to 'src/osd/modules/opengl')
-rw-r--r-- | src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh | 10 | ||||
-rw-r--r-- | src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh.c | 63 |
2 files changed, 36 insertions, 37 deletions
diff --git a/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh b/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh index 97278c65df5..cd068f8babe 100644 --- a/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh +++ b/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh @@ -13,8 +13,6 @@ uniform vec4 vid_attributes; // gamma, contrast, brightness void main() { - vec2 xy = gl_TexCoord[0].st; - // mix(x,y,a): x*(1-a) + y*a // // bilinear filtering includes 2 mix: @@ -25,9 +23,11 @@ void main() // // so we can use the build in mix function for these 2 computations ;-) // - vec2 uv_ratio = fract(xy*color_texture_pow2_sz); // xy*color_texture_pow2_sz - floor(xy*color_texture_pow2_sz); - vec2 one = 1.0/color_texture_pow2_sz; - + vec2 pixel = gl_TexCoord[0].st * color_texture_pow2_sz - 0.5; + vec2 uv_ratio = fract(pixel); + vec2 one = 1.0 / color_texture_pow2_sz; + vec2 xy = (floor(pixel) + 0.5) * one; + #if 1 vec4 col, col2; diff --git a/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh.c b/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh.c index 839daf76d5b..21d254e3128 100644 --- a/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh.c +++ b/src/osd/modules/opengl/shader/glsl_bilinear_rgb32_dir.fsh.c @@ -1,7 +1,6 @@ -// license:BSD-3-Clause -// copyright-holders:Sven Gothel const char glsl_bilinear_rgb32_dir_fsh_src[] = -"\n" +"// license:BSD-3-Clause\n" +"// copyright-holders:Sven Gothel\n" "#pragma optimize (on)\n" "#pragma debug (off)\n" "\n" @@ -15,43 +14,43 @@ const char glsl_bilinear_rgb32_dir_fsh_src[] = "\n" "void main()\n" "{\n" -" vec2 xy = gl_TexCoord[0].st;\n" -"\n" -" // mix(x,y,a): x*(1-a) + y*a\n" -" //\n" -" // bilinear filtering includes 2 mix:\n" -" //\n" -" // pix1 = tex[x0][y0] * ( 1 - u_ratio ) + tex[x1][y0] * u_ratio\n" -" // pix2 = tex[x0][y1] * ( 1 - u_ratio ) + tex[x1][y1] * u_ratio\n" -" // fin = pix1 * ( 1 - v_ratio ) + pix2 * v_ratio\n" -" //\n" -" // so we can use the build in mix function for these 2 computations ;-)\n" -" //\n" -" vec2 uv_ratio = fract(xy*color_texture_pow2_sz); // xy*color_texture_pow2_sz - floor(xy*color_texture_pow2_sz);\n" -" vec2 one = 1.0/color_texture_pow2_sz;\n" -"\n" +" // mix(x,y,a): x*(1-a) + y*a\n" +" //\n" +" // bilinear filtering includes 2 mix:\n" +" //\n" +" // pix1 = tex[x0][y0] * ( 1 - u_ratio ) + tex[x1][y0] * u_ratio\n" +" // pix2 = tex[x0][y1] * ( 1 - u_ratio ) + tex[x1][y1] * u_ratio\n" +" // fin = pix1 * ( 1 - v_ratio ) + pix2 * v_ratio\n" +" //\n" +" // so we can use the build in mix function for these 2 computations ;-)\n" +" //\n" +" vec2 pixel = gl_TexCoord[0].st * color_texture_pow2_sz - 0.5;\n" +" vec2 uv_ratio = fract(pixel);\n" +" vec2 one = 1.0 / color_texture_pow2_sz;\n" +" vec2 xy = (floor(pixel) + 0.5) * one;\n" +" \n" "#if 1\n" -" vec4 col, col2;\n" +" vec4 col, col2;\n" "\n" -" col = mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x);\n" -" col2 = mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x);\n" -" col = mix ( col, col2, uv_ratio.y );\n" +" col = mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x);\n" +" col2 = mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x);\n" +" col = mix ( col, col2, uv_ratio.y );\n" "#else\n" -" // doesn't work on MacOSX GLSL engine ..\n" -" //\n" -" vec4 col = mix ( mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x),\n" -" mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x), uv_ratio.y );\n" +" // doesn't work on MacOSX GLSL engine ..\n" +" //\n" +" vec4 col = mix ( mix( TEX2D(xy ), TEX2D(xy + vec2(one.x, 0.0)), uv_ratio.x),\n" +" mix( TEX2D(xy + vec2(0.0, one.y)), TEX2D(xy + one ), uv_ratio.x), uv_ratio.y );\n" "#endif\n" "\n" -" // gamma, contrast, brightness equation from: rendutil.h / apply_brightness_contrast_gamma_fp\n" +" // gamma, contrast, brightness equation from: rendutil.h / apply_brightness_contrast_gamma_fp\n" "\n" "#ifdef DO_GAMMA\n" -" // gamma/contrast/brightness\n" -" vec4 gamma = vec4(1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 0.0);\n" -" gl_FragColor = ( pow ( col, gamma ) * vid_attributes.g) + vid_attributes.b - 1.0;\n" +" // gamma/contrast/brightness\n" +" vec4 gamma = vec4(1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 1.0 / vid_attributes.r, 0.0);\n" +" gl_FragColor = ( pow ( col, gamma ) * vid_attributes.g) + vid_attributes.b - 1.0;\n" "#else\n" -" // contrast/brightness\n" -" gl_FragColor = ( col * vid_attributes.g) + vid_attributes.b - 1.0;\n" +" // contrast/brightness\n" +" gl_FragColor = ( col * vid_attributes.g) + vid_attributes.b - 1.0;\n" "#endif\n" "}\n" "\n" |