// RozK // Fisheye removal for GoPro 11+, 8:7 ratio, without hypersmooth #extension GL_ARB_texture_rectangle: enable // TODO: investigate // precision highp float; // #define debug_borders // uniforms uniform sampler2DRect myTextureY; uniform sampler2DRect myTextureU; uniform sampler2DRect myTextureV; uniform vec2 myResolution; uniform float pts; // parameters const vec2 sensor_dimensions = vec2(5.949440, 5.205760); const float fisheye_focal_length = 2.92; const float rectilinear_focal_length = 2.102263; const int subsampling = 4; // constants const float subsampling_step = 1.0 / float(subsampling); const float subsampling_start = subsampling_step * 0.5 - 0.5; const float subsampling_denominator = 1.0 / float(subsampling * subsampling); // variables vec2 texture_center; vec2 texture_to_sensor; vec2 sensor_to_texture; void initialize() { texture_center = myResolution * 0.5; texture_to_sensor = (sensor_dimensions / myResolution); sensor_to_texture = (myResolution / sensor_dimensions); } vec2 unfish_coord(const in vec2 coord) { float rectilinear_distance = length(coord); float rectilinear_angle = atan(rectilinear_distance / rectilinear_focal_length); float fisheye_distance = rectilinear_angle * fisheye_focal_length; return coord * (fisheye_distance / rectilinear_distance); } vec4 unfish_pixel(const in vec2 coord) { vec2 unfished = unfish_coord((coord - texture_center) * texture_to_sensor); vec2 y_coord = texture_center + unfished * sensor_to_texture; #ifdef debug_borders if (y_coord.x < 0.0 || y_coord.y < 0.0 || y_coord.x > myResolution.x || y_coord.y > myResolution.y) { return vec4(1.0, 1.0, 1.0, 1.0); } #endif vec2 uv_coord = y_coord * 0.5; return vec4( texture2DRect(myTextureY, y_coord).r, texture2DRect(myTextureU, uv_coord).r, texture2DRect(myTextureV, uv_coord).r, 1.0 ); } void main() { initialize(); vec2 coord = gl_TexCoord[0].xy; vec4 pixel = vec4(0.0, 0.0, 0.0, 0.0); float x, y = subsampling_start; for (int column = 0; column < subsampling; column++, y += subsampling_step) { x = subsampling_start; for (int row = 0; row < subsampling; row++, x += subsampling_step) { pixel += unfish_pixel(coord + vec2(x, y)); } } gl_FragColor = pixel * subsampling_denominator; }