CubeMap using PS and VS

Well first of all hi yall :slight_smile:
Next I’m gonna try exposing my problem with hope of finding someone with the right solution to it.
I’m trying to make a reflective shiny object as seen in some of Nvidia’s cubemaping demos, problem is, I’m using an ATi Radeon 9700 Pro which lacks support for some proprietary extensions necessary to produce the mentioned effect.
So I turned to PS and VS programming thinking it’d be pretty straight forward to compute the reflection vector in eye space, based on normals fetched from a normal map, and then use it to look up into my texture cube map loaded in the second texture unit.
Well all I can say is that the result obtained by following code is partilally right since the texturecubemap seems to go upsides down as I rotate the reflective object around.
Can anybody look at my code and attempt to point out the flaws in it?
Thanks in advance



Coder : Abdul Bezrati



OPTION ARB_position_invariant;

PARAM modelViewTranspose[4] = { state.matrix.modelview.transpose};
PARAM cameraPosition = {0,0,9,0};

TEMP cameraPosObjSpace, viewVector, temp;
TEMP tangent, binormal;

MOV tangent , vertex.texcoord[1];
MOV binormal, vertex.texcoord[2];

DP3 cameraPosObjSpace.x, modelViewTranspose[0], cameraPosition;
DP3 cameraPosObjSpace.y, modelViewTranspose[1], cameraPosition;
DP3 cameraPosObjSpace.z, modelViewTranspose[2], cameraPosition;

SUB temp, cameraPosObjSpace, vertex.position;

DP3 viewVector.x, temp, tangent;
DP3 viewVector.y, temp, binormal;
DP3 viewVector.z, temp, vertex.normal;

MOV result.texcoord[0], vertex.texcoord[0];
MOV result.texcoord[1], viewVector;


#Author:Abdul Bezrati “Java Cool Dude” #

TEMP normalVector, reflectionVector, viewVector;
TEMP temp;

TEX normalVector, fragment.texcoord[0], texture[0], 2D;

MAD normalVector, normalVector , 2.0, -1.0;

MOV viewVector , fragment.texcoord[1];
DP3 viewVector.w, viewVector, viewVector;
RSQ viewVector.w, viewVector.w;
MUL viewVector , viewVector, viewVector.w;

DP3 temp , normalVector , viewVector;
MUL temp , temp , -2;
MAD reflectionVector , temp , normalVector, viewVector;

DP3 reflectionVector.w, reflectionVector, reflectionVector;
RSQ reflectionVector.w, reflectionVector.w;
MUL reflectionVector, reflectionVector, reflectionVector.w;

TEX result.color, reflectionVector, texture[1], CUBE;


Cube environment mapping is not proprietary. I think it’s even part of the core these days. That’s what you usually use to make “shiny, reflective” objects.

Look at GL_NORMAL_MAP and GL_REFLECTION_MAP texgen modes, and the GL_TEXTURE_CUBE texture target (if memory serves).

I’m sorry I should’ve explained myself a bit better.
I’m very aware of the fact that the TEXTURE_CUBE_MAP extension as well as the REFLECTION_MAP and NORMAL_MAP that oftenly goes along with it are not proprietary, however my goal was to generate the same effect using VS and FS, with a normal map to have the bumpy look.
Here’s a screenshot that might help you understand what words failed to (and I’m again aware that what I said was a bit ambiguious)
Thanks for replying though

Originally posted by Java Cool Dude:
So I turned to PS and VS programming thinking it’d be pretty straight forward to compute the reflection vector in eye space, based on normals fetched from a normal map, and then use it to look up into my texture cube map loaded in the second texture unit.
Well all I can say is that the result obtained by following code is partilally right since the texturecubemap seems to go upsides down as I rotate the reflective object around.

You are computing a reflection vector in tangent space, and your cube map is in a unknown space, probably world space.
You have to compute your reflection vector in object or world space.


Edit :
Actually, your cube map must be in eye space, so you have to compute your reflection vector in eye space. To do this, pass to the fragment program the refelction vector in eye space (and not in tangent space), pass your binormal and tangent vectors to the framgent program as well, fetch the normal, and pass it to eye space. Then compute your reflection vector in eye space and lookup the correct texel.

[This message has been edited by SeskaPeel (edited 02-26-2004).]

Let me see if I get this right:
First I compute the view vector in eye space, meaning I have to substract the vertex vector position from the camera’s location and then normalize it.
Of course the vertex position was already transformed in eye space using the ModelView matrix, am I correct on this one?
Second comes the fragment shader part where I already passed the tangent and binormals as the secondary and third texture coordinates keeping in mind that the first unit will remain untouched as it fetchs the apropriate normal from the normalmap.

At this point things seem to acquire a new level of complexity as I’m wondering if it’s the newly fetched normal map that has to be transformed using the tangent space component (where did the vertex normal go?), or the reflection vector computed as R = viewVector - 2*(Normal.viewVector)*viewVector?

I’m defintely in need of bit more help before I can put it all together

Here’s how I do it:

Fragment program:


ATTRIB TexCoord=fragment.texcoord[0];
ATTRIB Vertex=fragment.texcoord[1];
ATTRIB TangentX=fragment.texcoord[2];
ATTRIB TangentY=fragment.texcoord[3];
ATTRIB TangentZ=fragment.texcoord[4];

OUTPUT Output=result.color;

TEMP Normal, View, Reflect, Temp;

Sample the normal map

TEX Normal, TexCoord, texture[0], 2D;

Expand the normal ([0,1] -> [-1,1])

MAD Temp, Normal, 2.0, -1.0;

Transform the normal from tangent space into object space

DP3 Normal.x, TangentX, Temp;
DP3 Normal.y, TangentY, Temp;
DP3 Normal.z, TangentZ, Temp;

Normalize it

DP3 Temp.x, Normal, Normal;
RSQ Temp.w, Temp.x;
MUL Normal, Normal, Temp.w;

View is in w of tangent matrix

MOV View.x, TangentX.w;
MOV View.y, TangentY.w;
MOV View.z, TangentZ.w;

“surface” space?

SUB View, View, Vertex;

Normalize it

DP3 Temp.x, View, View;
RSQ Temp.w, Temp.x;
MUL View, View, Temp.w;


DP3 Temp.x, View, Normal;
ADD Temp.w, Temp.x, Temp.x;
MAD Reflect, Temp.w, Normal, -View;

Sample the cube map

TEX Output, Reflect, texture[1], CUBE;


Vertex program:


PARAM mvp[4]={ state.matrix.mvp };
PARAM mvit[4]={ state.matrix.modelview.invtrans };

Vertex transform

DP4 result.position.x, mvp[0], vertex.position;
DP4 result.position.y, mvp[1], vertex.position;
DP4 result.position.z, mvp[2], vertex.position;
DP4 result.position.w, mvp[3], vertex.position;

Pass the vertex color

MOV result.color, vertex.color;

Pass the texture coords

MOV result.texcoord[0], vertex.texcoord[0];

Pass the vertex (untransformed)

MOV result.texcoord[1], vertex.position;

Pass the Tangent matrix (transpose)

With View vector

Tangent X

MOV result.texcoord[2].x, vertex.texcoord[1].x;

Binormal X

MOV result.texcoord[2].y, vertex.texcoord[2].x;

Normal X

MOV result.texcoord[2].z, vertex.texcoord[3].x;

View X

MOV result.texcoord[2].w, mvit[3].x;

Tangent Y

MOV result.texcoord[3].x, vertex.texcoord[1].y;

Binormal Y

MOV result.texcoord[3].y, vertex.texcoord[2].y;

Normal Y

MOV result.texcoord[3].z, vertex.texcoord[3].y;

View Y

MOV result.texcoord[3].w, mvit[3].y;

Tangent Z

MOV result.texcoord[4].x, vertex.texcoord[1].z;

Binormal Z

MOV result.texcoord[4].y, vertex.texcoord[2].z;

Normal Z

MOV result.texcoord[4].z, vertex.texcoord[3].z;

View Z

MOV result.texcoord[4].w, mvit[3].z;


[This message has been edited by NitroGL (edited 02-28-2004).]

Sup Matt, haven’t seen ya around r3d a lot lately :slight_smile:

Yeah, I haven’t been posting a whole lot, but I’ve been lurking a bit.

I’ve been working on an update to my Tetris game, trying to get better music, with out too much luck unfortuantly (MP3 or OGG). And updating the various shaders and GL code.

Well I figured out an easier way to do the reflective bumpy-cubemap effect:


#Author:Abdul Bezrati “Java Cool Dude” #

TEMP normalVector, reflectionVector, viewVector;
TEMP usefulTemp;

TEX usefulTemp, fragment.texcoord[0], texture[0], 2D;

MAD usefulTemp, usefulTemp, 2.0, -1.0;

DP3 normalVector.x, usefulTemp, fragment.texcoord[1];
DP3 normalVector.y, usefulTemp, fragment.texcoord[2];
DP3 normalVector.z, usefulTemp, fragment.texcoord[3];

DP3 normalVector.w, normalVector, normalVector;
RSQ normalVector.w, normalVector.w;
MUL normalVector, normalVector, normalVector.w;

MOV viewVector.x , fragment.texcoord[1].w;
MOV viewVector.y , fragment.texcoord[2].w;
MOV viewVector.z , fragment.texcoord[3].w;

DP3 usefulTemp , normalVector, viewVector;
ADD usefulTemp , usefulTemp , usefulTemp;

MAD reflectionVector, usefulTemp, normalVector, -viewVector;

TEX result.color, reflectionVector, texture[1], CUBE;




Coder : Abdul Bezrati


Info : Texture Coordinates = vertex.texcoord[0]

Tangent Vector = vertex.texcoord[1]

Binoraml Vector = vertex.texcoord[2]


OPTION ARB_position_invariant;

PARAM modelViewInvTrans[4] = { state.matrix.modelview.invtrans};
PARAM modelView[4] = { state.matrix.modelview};

TEMP eyeVector;

DP4 eyeVector.x, modelView[0], vertex.position;
DP4 eyeVector.y, modelView[1], vertex.position;
DP4 eyeVector.z, modelView[2], vertex.position;
DP4 eyeVector.w, modelView[3], vertex.position;

MOV eyeVector, -eyeVector;

MOV result.texcoord[0], vertex.texcoord[0];

DP3 result.texcoord[1].x, modelViewInvTrans[0], vertex.texcoord[1];
DP3 result.texcoord[1].y, modelViewInvTrans[0], vertex.texcoord[2];
DP3 result.texcoord[1].z, modelViewInvTrans[0], vertex.normal;

DP3 result.texcoord[2].x, modelViewInvTrans[1], vertex.texcoord[1];
DP3 result.texcoord[2].y, modelViewInvTrans[1], vertex.texcoord[2];
DP3 result.texcoord[2].z, modelViewInvTrans[1], vertex.normal;

DP3 result.texcoord[3].x, modelViewInvTrans[2], vertex.texcoord[1];
DP3 result.texcoord[3].y, modelViewInvTrans[2], vertex.texcoord[2];
DP3 result.texcoord[3].z, modelViewInvTrans[2], vertex.normal;

MOV result.texcoord[1].w, eyeVector.x;
MOV result.texcoord[2].w, eyeVector.y;
MOV result.texcoord[3].w, eyeVector.z;

Yay :slight_smile:
A sample :slight_smile:

[This message has been edited by Java Cool Dude (edited 02-28-2004).]