# Compute fragment's ray direction (world's coordinates)

Hello !

I try to make a sky shader using a fullscreen quad and an equirectangular texture (Equirectangular Projection - PanoTools.org Wiki ). So for each fragment I need the “raytracing direction” in (polar) spherical coordinates. I need to someone check if the following method seems good …

Send vertices :

I send directly to the vertex shader the fullscreen quad’s clip coordinates :

``````
glVertex2i(-1,-1);
glVertex2i(1,-1);
glVertex2i(1, 1);
glVertex2i(-1,1);
glEnd();

``````

The vertex shaders :

I compute de ray direction for each (four) vertex using clip coordinates. First I make inverse projection and next inverse modelview but without translation.

``````
/*****************/
/* VERTEX SHADER */
/*****************/

varying vec3 rayDirection;

void main()
{
vec4 reverseVec;

/* inverse perspective projection */
reverseVec = vec4(gl_Vertex.xy, 0.0, 1.0);
reverseVec *= gl_ProjectionMatrixInverse;

/* inverse modelview, without translation */
reverseVec.w = 0.0;
reverseVec *= gl_ModelViewMatrixInverse;

/* send */
rayDirection = vec3(reverseVec);
gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);

}

``````

I’am not sure that I set the z and w coordinates to good values …

The fragment shaders :

The rayDirection vector is interpolated, so I get the ray direction in world’s coordinates. So I just need to compute the spherical direction (s, t).

``````
/*******************/
/* FRAGMENT SHADER */
/*******************/

varying vec3 rayDirection;

const float PI = 3.14159265358979323846264;

void main()
{
vec3 normalizedDirection;
vec2 polarDirection;

/* T computation */
normalizedDirection  = normalize(rayDirection);
polarDirection.t = acos(normalizedDirection.y);

/* S computation */
rayDirection.y = 0.0;
normalizedDirection  = normalize(rayDirection);

if(normalizedDirection.x >= 0)
polarDirection.s = acos(-normalizedDirection.z);
else
polarDirection.s = acos(normalizedDirection.z) + PI;

.....

}

``````

It seems good ??

I finally found the error !! The problem is that

``````reverseVec *= gl_ProjectionMatrixInverse;
``````

is equivalent to

``````reverseVec = reverseVec * gl_ProjectionMatrixInverse;
``````

but not to

``````reverseVec = gl_ProjectionMatrixInverse * reverseVec ;
``````

The shader now works ! It display an equirectangular panoramic image with :

Opengl side :

``````

glVertex2i(-1, -1);
glVertex2i(1, -1);
glVertex2i(1, 1);
glVertex2i(-1, 1);

glEnd();

``````

``````
/*****************/
/* VERTEX SHADER */
/*****************/

varying vec3 rayDirection;

void main()
{
vec4 reverseVec;

/* inverse perspective projection */
reverseVec = vec4(gl_Vertex.xy, 0.0, 1.0);
reverseVec = gl_ProjectionMatrixInverse * reverseVec;

/* inverse modelview, without translation */
reverseVec.w = 0.0;
reverseVec = gl_ModelViewMatrixInverse * reverseVec;

/* send */
rayDirection = vec3(reverseVec);
gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);
}

``````

``````
/*******************/
/* FRAGMENT SHADER */
/*******************/

uniform sampler2D equiTex;
varying vec3 rayDirection;

const float PI = 3.14159265358979323846264;

void main()
{
vec3 normalizedDirection;
vec2 polarDirection;

/* T computation */
normalizedDirection  = normalize(rayDirection);
polarDirection.t = acos(normalizedDirection.y)/PI;

/* S computation */
rayDirection.y = 0.0;
normalizedDirection  = normalize(rayDirection);

if(normalizedDirection.x >= 0)
polarDirection.s = acos(-normalizedDirection.z)/(2*PI);
else
polarDirection.s = (acos(normalizedDirection.z) + PI)/(2*PI);

/* color */
gl_FragColor = texture2D(equiTex, polarDirection.st);

}

``````

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.