The following discusses the transformation of a cubic environment map (90 degree perspective projections onto the face of a cube) into a cylindrical panoramic image. The driver for this was the creation of cylindrical panoramic images from rendering softare that didn't explicitely support panoramic creation. The software was scripted to create the 6 cubic images and this utility created the panoramic.
UsageUsage: cube2cyl [options] filemask filemask can contain %c which will substituted with each of [l,r,t,d,b,f] For example: "blah_%c.tga" or "%c_something.tga" Options -a n sets antialiasing level, default = 2 -v n vertical aperture, default = 90 -w n sets the output image width, default = 3 * cube image widthFile name conventions
The names of the cubic maps are assumed to contain the letters 'f', 'l', 'r', 't', 'b', 'd' that indicate the face (front,left,right,top,back,down). The file mask needs to contain "%c" which specifies the view.
So for example the following cubic maps would be specified as %c_starmap.tga,
l_starmap.tga, r_starmap.tga, f_starmap.tga,
t_starmap.tga, b_starmap.tga, d_starmap.tga.
cube2cyl -a 3 -v 90
Note that in this special case the top of the face should coincide
with the top of the cylindrical panoramic.
cube2cyl -a 3 -v 120
cube2cyl -a 3 -v 150
Geometry
The mapping for each pixel in the destination cylindrical panoramic from the correct location on the appropriate cubic face is relatively straightforward. The horizontal axis maps linearly onto the angle about the cylinder. The vertical axis of the panoramic image maps onto the vertical axis of the cylinder by a tan relationship.
In particular, if (i,j) is the pixel index of the panoramic normalised to (-1,+1) the the direction vector is given as follows.
This direction vector is then used within the texture mapped cubic geometry. The face of the cube it intersects needs to be found and then the pixel the ray passes through is determined (intersection of the direction vector with the plane of the face). Critical to obtaining good quality results is antialiasing, in this implementation a sraightforward constant weighted supersampling is used.
Example 1
Cylindrical panoramic (90 degrees)
Example 2
Cubic map
Cylindrical panoramic (90 degrees)
Notes
Introduction
There are two common methods of representing environment maps, cubic and spherical. In cubic maps the virtual camera is surrounded by a cube the 6 faces of which have an appropriate texture map. These texture maps are often created by imaging the scene with six 90 degree fov cameras giving a left, front, right, back, top, and bottom texture. In a spherical map the camera is surrounded by a sphere with a single spherically distorted texture. This document describes bow to convert 6 cubic maps into a single spherical map.
ExampleAs an illustrative example the following 6 images are the textures placed on the cubic environment, they are arranged as an unfolded cube. Below that is the spherical texture map that would give the same appearance if applied as a texture to a sphere about the camera.
![]() |
|||
![]() |
![]() |
![]() |
![]() |
![]() |
Maps courtesy of Ben Syverson |

The conversion process involves two main stages. The goal is to determine the best estimate of the colour at each pixel in the final spherical image given the 6 cubic texture images. The first stage is to calculate the polar coordinates corresponding to each pixel in the spherical image. The second stage is to use the polar coordinates to form a vector and find which face and which pixel on that face the vector (ray) strikes. In reality this process is repeated a number of times at slightly different positions in each pixel in the spherical image and an average is used in order to avoid aliasing effects.
If the coordinates of the spherical image are (i,j) and the image has width "w" and height "h" then the normalised coordinates (x,y) each ranging from -1 to 1 are given by:
|
x = 2 i / w - 1
y = 2 j / h - 1 or y = 1 - 2 j / h depending on the position of pixel 0 |
The polar coordinates theta and phi are derived from the normalised coordinates (x,y) below. theta ranges from 0 to 2 pi and phi ranges from -pi/2 (south pole) to pi/2 (north pole). Note there are two vertical relationships in common use, linear and spherical. In the former phi is linearly related to y, in the later there is a sine relationship.
|
theta = x pi
phi = y pi / 2 or phi = asin(y) for spherical vertical distortion |
The polar coordinates (theta,phi) are turned into a unit vector (view ray from the camera) as below. This assumes a right hand coordinate system, x to the right, y upwards, and z out of the page. The front view of the cubic map is looking from the origin along the positive z axis.
|
x = cos(phi) cos(theta)
y = sin(phi) z = cos(phi) sin(theta) |
The intersection of this ray is now found with the faces of the cube. Once the intersection point is found the coordinate on the square face specifies the corresponding pixel and therefore colour associated with the ray.
Mapping geometry![]() |
|||
![]() |
![]() |
![]() |
![]() |
![]() |

![]() |
|||
![]() |
![]() |
![]() |
![]() |
![]() |

Usage: cube2sphere [options] filemask filemask should contain %c which will substituted with each of [l,r,t,d,b,f] For example: "blah_%c.tga" or "%c_something.tga" Options -w n sets the output image width, default = 4*inwidth -w1 n sub image position 1, default: 0 -w2 n sub image position 2, default: width -h n sets the output image height, default = width/2 -a n sets antialiasing level, default = 1 (none) -s use sine correction for vertical axis
![]() |
|||
![]() |
![]() |
![]() |
![]() |
![]() |
