Skip to content

Instantly share code, notes, and snippets.

@tesu
Last active December 14, 2023 22:38
Show Gist options
  • Save tesu/196db5421559de3e9555d4f9da9d847d to your computer and use it in GitHub Desktop.
Save tesu/196db5421559de3e9555d4f9da9d847d to your computer and use it in GitHub Desktop.
mpv opengl shader for viewing 360 video
//!HOOK MAINPRESUB
//!BIND HOOKED
//!DESC un360
#define M_PI 3.1415926535897932384626433832795
const float fov = M_PI/2; // [0 to M_PI] horizontal field of view, range is exclusive
const float yaw = M_PI*1; // [any float] polar angle, one full revolution is 2*M_PI
const float pitch = M_PI*0; // [any float] vertical tilt, positive is up
const float roll = M_PI*0; // [any float] view rotation, positive is clockwise
const bool cubemap = false; // either cubemap or equirectangular
const float t = tan(fov/2);
const float c = cos(pitch);
const float s = sin(pitch);
float r = target_size.y/target_size.x;
const float sR = sin(roll);
const float cR = cos(roll);
mat3 m = mat3( 2*t*cR, 2*sR*t*r, -t*(cR+sR*r),
-2*sR*t*c, 2*cR*t*c*r, t*c*(sR-cR*r)-s,
-2*sR*t*s, 2*cR*t*s*r, t*s*(sR-cR*r)+c);
vec4 hook() {
vec3 p = vec3(HOOKED_pos, 1.0) * m;
float theta = atan(p.x, p.z) + yaw;
float phi = atan(p.y, length(p.xz)) + M_PI/2;
float x, y;
if (!cubemap) {
// equirectangular
x = fract(theta / (2*M_PI));
y = phi / M_PI;
} else {
// cubemap
float offset = mod(theta, M_PI/2)-M_PI/4;
float quadrant = mod(floor(theta*2/M_PI), 4);
float h = tan(phi)*cos(offset);
if (abs(h) > 1) { // side
if (quadrant == 3) { // back
x = .5/(tan(phi)*cos(offset))+.5;
y = .5*tan(offset)+.5;
x *= 1.0/3;
y *= 1.0/2;
x += 1.0/3;
y += 1.0/2;
} else {
x = .5*tan(offset)+.5;
y = -.5/(tan(phi)*cos(offset))+.5;
x *= 1.0/3;
y *= 1.0/2;
x += quadrant/3;
}
} else if (h > 0) { // top
x = .5*tan(M_PI-phi)*cos(theta+M_PI/4)+.5;
y = -.5*tan(M_PI-phi)*sin(theta+M_PI/4)+.5;
x *= 1.0/3;
y *= 1.0/2;
x += 2.0/3;
y += 1.0/2;
} else { // bottom
x = .5*tan(M_PI-phi)*cos(theta+M_PI/4)+.5;
y = .5*tan(M_PI-phi)*sin(theta+M_PI/4)+.5;
x *= 1.0/3;
y *= 1.0/2;
y += 1.0/2;
}
}
return HOOKED_tex(vec2(x,y));
}
@diimdeep
Copy link

To use add glsl-shaders-append="~/.config/mpv/un360.glsl" to ~/.config/mpv/mpv.conf and tweak parameters for video.

@haasn
Copy link

haasn commented Dec 22, 2022

With the recent addition of --glsl-shader-opts you could make this at least a bit more adjustable at runtime (maybe with an accompanying lua script to allow e.g. mouse dragging the view).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment