whilst trialing the backwards approach of domemaster to equirectangular approach -- i got this beauty working :)
tested and functional as a shader --- Ubuntu 24 -- OSsia (bleeding edge as of 20 july 2026)
/*{
"DESCRIPTION": "Generates an Equirectangular output by un-projecting a Domemaster (fisheye) input image. Rotations, input FOV, and horizontal flip are controllable.",
"CREDIT": "Edu Meneses + AI Assistant",
"CATEGORIES": [
"GENERATOR",
"3D",
"DOME",
"PANORAMIC"
],
"INPUTS": [
{ "NAME": "domemasterImage", "TYPE": "image", "LABEL": "Domemaster (Fisheye) Input" },
{
"NAME" :"XYZrotate",
"TYPE" : "point3D",
"DEFAULT" : [0.5, 0.5, 0.5],
"MAX" : [1.0, 1.0, 1.0],
"MIN" : [0.0, 0.0, 0.0]
},
{
"NAME": "domemaster_input_fov_degrees",
"LABEL": "Domemaster Input FOV (degrees)",
"TYPE": "float",
"DEFAULT": 180.0,
"MIN": 1.0,
"MAX": 360.0
},
{
"NAME": "flipHorizontal",
"LABEL": "Flip Horizontally (Ext. Surface)",
"TYPE": "bool",
"DEFAULT": false
}
]
}*/
#define M_PI 3.14159265359
mat3 makeRotationMatrix(vec3 a) // a = (yaw, pitch, roll)
{
mat3 my = mat3(cos(a.x), 0, sin(a.x), 0, 1, 0, -sin(a.x), 0, cos(a.x)); // Yaw
mat3 mx = mat3(1, 0, 0, 0, cos(a.y), -sin(a.y), 0, sin(a.y), cos(a.y)); // Pitch
mat3 mz = mat3(cos(a.z), -sin(a.z), 0, sin(a.z), cos(a.z), 0, 0,0,1); // Roll
return my * mx * mz;
}
void main()
{
// Output pixel -> equirectangular longitude/latitude
vec2 p_norm_screen = vv_FragNormCoord; // [0,1]
float u = p_norm_screen.x;
float v = p_norm_screen.y;
float longitude = (u - 0.5) * 2.0 * M_PI;
float latitude = (0.5 - v) * M_PI;
// Longitude/latitude -> world-space ray direction (inverse of atan/asin in the other shader)
vec3 norm_ray_dir_world;
norm_ray_dir_world.x = cos(latitude) * sin(longitude);
norm_ray_dir_world.y = sin(latitude);
norm_ray_dir_world.z = cos(latitude) * cos(longitude);
// Undo the world rotation to get back into "view" space
float roll_angle = (XYZrotate.z - 0.5) * 2.0 * M_PI;
float yaw_angle = XYZrotate.x * 2.0 * M_PI;
float pitch_angle = XYZrotate.y * 2.0 * M_PI;
vec3 rotation_euler_angles = vec3(yaw_angle, pitch_angle, roll_angle);
mat3 camera_to_world_rotation_matrix = makeRotationMatrix(rotation_euler_angles);
mat3 world_to_camera_rotation_matrix = transpose(camera_to_world_rotation_matrix); // rotation matrices are orthogonal
vec3 ray_dir_view = world_to_camera_rotation_matrix * norm_ray_dir_world;
// View-space ray direction -> fisheye polar coords (inverse of the sin/cos build in the other shader)
float ray_polar_angle_view = acos(clamp(ray_dir_view.z, -1.0, 1.0));
float ray_azimuth_angle_view = atan(ray_dir_view.y, ray_dir_view.x);
float fisheye_half_fov_rad = (domemaster_input_fov_degrees / 2.0) * (M_PI / 180.0);
float dist_from_center = ray_polar_angle_view / fisheye_half_fov_rad;
if (dist_from_center > 1.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
return;
}
vec2 p_centered;
p_centered.x = dist_from_center * cos(ray_azimuth_angle_view);
p_centered.y = dist_from_center * sin(ray_azimuth_angle_view);
// Undo the aspect-ratio correction applied in the forward shader
float screen_aspect = RENDERSIZE.x / RENDERSIZE.y;
if (screen_aspect > 1.0) { // Landscape or square
p_centered.x /= screen_aspect;
} else { // Portrait
p_centered.y *= screen_aspect;
}
// Undo the horizontal flip
if (flipHorizontal) {
p_centered.x = -p_centered.x;
}
vec2 fisheye_uv = p_centered * 0.5 + 0.5;
vec4 sampled_color = texture(domemasterImage, fisheye_uv);
gl_FragColor = sampled_color;
}
whilst trialing the backwards approach of domemaster to equirectangular approach -- i got this beauty working :)
tested and functional as a shader --- Ubuntu 24 -- OSsia (bleeding edge as of 20 july 2026)