Skip to content

Instantly share code, notes, and snippets.

@TheGreatRambler
Created June 8, 2023 00:34
Show Gist options
  • Save TheGreatRambler/44e14946599c93d123a874e5834915b6 to your computer and use it in GitHub Desktop.
Save TheGreatRambler/44e14946599c93d123a874e5834915b6 to your computer and use it in GitHub Desktop.
Shader attempt at equirectangular projection from dual fisheye textures, doesn't handle stitching well
precision mediump float;
varying vec4 vPosition;
#define PI 3.14159265358979
#define APERTURE 180.0
#define INSTA360_Y_BOTTOM 0.02
#define INSTA360_Y_TOP 0.97
#define INSTA360_X_LEFT 0.0
#define INSTA360_X_RIGHT 1.0
uniform sampler2D uVideo1;
uniform sampler2D uVideo2;
float atan2(float y, float x) {
return atan(y, x);
}
float lerp(float x, float input_start, float input_end, float output_start, float output_end) {
return (x - input_start) / (input_end - input_start) * (output_end - output_start)
+ output_start;
}
void main() {
// TODO remove blurry outline
float y_dest_norm = -vPosition.y;
float x_dest_norm = vPosition.x;
if(vPosition.x < 0.0) {
x_dest_norm += 1.0;
}
float longitude = x_dest_norm * PI;
float latitude = y_dest_norm * PI / 2.0;
float p_x = cos(latitude) * cos(longitude);
float p_y = cos(latitude) * sin(longitude);
float p_z = sin(latitude);
float p_xz = sqrt(p_x * p_x + p_z * p_z);
float r = 2.0 * atan2(p_xz, p_y) / (APERTURE * PI / 180.0);
float theta = atan2(p_z, p_x);
float x_src_norm = r * cos(theta);
float y_src_norm = r * sin(theta);
if(vPosition.x < 0.0) {
gl_FragColor = texture2D(
uVideo1, vec2(lerp(x_src_norm, -1.0, 1.0, INSTA360_X_LEFT, INSTA360_X_RIGHT),
lerp(y_src_norm, -1.0, 1.0, INSTA360_Y_BOTTOM, INSTA360_Y_TOP)));
} else {
gl_FragColor = texture2D(
uVideo2, vec2(lerp(x_src_norm, -1.0, 1.0, INSTA360_X_LEFT, INSTA360_X_RIGHT),
lerp(y_src_norm, -1.0, 1.0, INSTA360_Y_BOTTOM, INSTA360_Y_TOP)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment