edit: source shader code tested, updated and works...
there is also video...
Once you use a 3D coord instead 2D to sample cube, it is possible (but not parametric :)).
Use normalize(GL_Vertex - cubeOrigin) as sampling vector.
You have to know to which face of cube vertex belongs. It is the biggest componnent in sampling vector.
Once you have face, you can specify face normal. Than compute angle between face normal and sampling vector. Use Law of sines to get distance of point in space from cube origin(in middle). Multiply this distance with normal and you got it :)
// this code sucks for shader ... it would be slow it is written to be clear not optimal.
uniform int timer;
//return face's ID based on sampling vector
int face(vec3 coord)
if((abs(coord.x) > abs(coord.y)) && (abs(coord.x) > abs(coord.z)))
if (coord.x > 0)
if( abs(coord.y) > abs(coord.z))
if (coord.y > 0)
if (coord.z > 0)
vec3 cube(vec3 position,vec3 cubeOrigin)
int CUBE_SIZE = 2;
vec3 coord = normalize(position - cubeOrigin);
int face = face(coord);
vec3 faceNormal = vec3(0);
case 0: faceNormal = vec3(1,0,0); break;
case 1: faceNormal = vec3(-1,0,0); break;
case 2: faceNormal = vec3(0,1,0); break;
case 3: faceNormal = vec3(0,-1,0); break;
case 4: faceNormal = vec3(0,0,1); break;
case 5: faceNormal = vec3(0,0,-1); break;
float gamma = acos (dot(faceNormal,coord));
float alfa = 3.14 - 1.57 - gamma; //there is no PI or HALF_PI in glsl you have to define it on your own.
//this is little hard stuff. You want to know length from origin to place on cube. It is simple triangle and can be solved by law of sines.
//It should be multiplied with sin(HALF_PI) but it is 1.
float posFactor = (CUBE_SIZE/2.0)/sin(alfa) ;
return (cubeOrigin + coord * posFactor);
vec3 transformed = cube(gl_Vertex.xyz,vec3(0.0,0.0,0.0));
vec4 cubetrans = vec4 (transformed,1.0);
gl_Position = mix(gl_ModelViewProjectionMatrix * cubetrans,gl_ModelViewProjectionMatrix * gl_Vertex,timer/200.0);
gl_FrontColor = gl_Color;