Bumpmapping?

I cant get this to work? I was wondering if anyone could give it a look over and see if im doing something wrong.

CALCULATE THE TANGENT, BINORMAL, AND NORMAL
void triangle::calcN(){
vector temp1;
vector temp2;
temp1 = (theTri[0] - theTri[1]);
temp2 = (theTri[0] - theTri[2]);
this->normal = (temp1.cross(temp2));
this->normal.norm();
}

void triangle::calcT(float s0,float t0,float s1,float t1){
vector temp1,temp2,result;
//get tangent X
temp1.set((theTri[1].getX()-theTri[0].getX()),s0,t0);
temp2.set((theTri[2].getX()-theTri[0].getX()),s1,t1);
result = (temp1.cross(temp2));
tangent.setX(-result.getY()(1/result.getX()));
//get tangent Y
temp1.setX((theTri[0].getY()-theTri[1].getY()));
temp2.setX((theTri[0].getY()-theTri[2].getY()));
result = (temp1.cross(temp2));
tangent.setY(-result.getY()
(1/result.getX()));
//get tangent Z
temp1.setX((theTri[0].getZ()-theTri[1].getZ()));
temp2.setX((theTri[0].getZ()-theTri[2].getZ()));
result = (temp1.cross(temp2));
tangent.setZ(-result.getY()*(1/result.getX()));
}

void triangle::calcB(){
this->binormal = (normal.cross(tangent));
}

AM I INPUTING THE MATRIX WRONG SOMEHOW?

// tangent part of matrix
tangentMatrix[0] = tbn->getT().getX();
tangentMatrix[1] = tbn->getT().getY();
tangentMatrix[2] = tbn->getT().getZ();
tangentMatrix[3] = 0.0f;
// binormal part of matrix
tangentMatrix[4] = tbn->getB().getX();
tangentMatrix[5] = tbn->getB().getY();
tangentMatrix[6] = tbn->getB().getZ();
tangentMatrix[7] = 0.0f;
// normal part of matrix
tangentMatrix[8] = tbn->getN().getX();
tangentMatrix[9] = tbn->getN().getY();
tangentMatrix[10] = tbn->getN().getZ();
tangentMatrix[11] = 0.0f;
// filler for 4x4
tangentMatrix[12] = 0.0f;
tangentMatrix[13] = 0.0f;
tangentMatrix[14] = 0.0f;
tangentMatrix[15] = 1.0f;
glMatrixMode(GL_MATRIX0_ARB);
glLoadMatrixf(tangentMatrix);

I am using a fragment shader (ARBfp1.0) to calculate the per pixel dot products and it just doesn’t seem to look per pixel at all!

It might help if we could see your vertex program and fragment program, but I can tell you that your tangent vector calculation doesn’t look right. Take a look at Section 6.8 of Mathematics for 3D Game Programming and Computer Graphics:

http://www.terathon.com/books/mathgames2.html

!!ARBvp1.0
ATTRIB iPosition = vertex.position;
#ATTRIB iNormal = vertex.normal;
ATTRIB iTexCoordA = vertex.texcoord[0];
ATTRIB iTexCoordB = vertex.texcoord[1];

PARAM lPosition = state.light[0].position;
PARAM lHalf = state.light[0].half;
PARAM lAmbient = state.light[0].ambient;
PARAM lDiffuse = state.light[0].diffuse;
PARAM lSpecular = state.light[0].specular;

PARAM mvp[4] = { state.matrix.mvp };
PARAM mvinv[4] = { state.matrix.modelview.invtrans };
PARAM tm[4] = { state.matrix.program[0] };

OUTPUT oPosition = result.position;
OUTPUT oTexCoordA = result.texcoord[0];
OUTPUT oTexCoordB = result.texcoord[1];

TEMP position,eyeNormal,tLight,oLight,tHalf,temp;

DP4 oPosition.x, mvp[0], iPosition;
DP4 oPosition.y, mvp[1], iPosition;
DP4 oPosition.z, mvp[2], iPosition;
DP4 oPosition.w, mvp[3], iPosition;
MOV position,iPosition;

SUB oLight, lPosition, position;

transform from object space to tangent space

DP3 tLight.x, tm[0], oLight;
DP3 tLight.y, tm[1], oLight;
DP3 tLight.z, tm[2], oLight;

transform from object space to tangent space

DP3 tHalf.x, tm[0], lHalf;
DP3 tHalf.y, tm[1], lHalf;
DP3 tHalf.z, tm[2], lHalf;

MOV oTexCoordA, iTexCoordA;
MOV oTexCoordB, iTexCoordB;
MOV result.color.primary, tLight;
MOV result.color.secondary, tHalf;
END

!!ARBfp1.0

ATTRIB tLight = fragment.color.primary;
ATTRIB tHalf = fragment.color.secondary;

PARAM lAmbient = state.light[0].ambient;
PARAM lDiffuse = state.light[0].diffuse;
PARAM lSpecular = state.light[0].specular;

TEMP nLight, nHalf, nBump, bumpmap, decalmap, dots, specular, temp;

OUTPUT output = result.color;

TEX bumpmap, fragment.texcoord[0], texture[0], 2D;
TEX decalmap, fragment.texcoord[0], texture[1], 2D;

DP3 temp, bumpmap, bumpmap;
RSQ temp, temp.x;
MUL nBump, temp, bumpmap;

DP3 temp, tLight, tLight;
RSQ temp, temp.x;
MUL nLight, temp, tLight;

DP3 temp, tHalf, tHalf;
RSQ temp, temp.x;
MUL nHalf, temp, tHalf;

DP3 dots.x, nLight, bumpmap;
DP3 dots.y, nHalf, bumpmap;

MOV dots.w, 32.0;
LIT dots, dots;
#just attempting diffuse!
MUL output,dots.x,decalmap;
END

These two statements in your vertex program,

MOV result.color.primary, tLight;
MOV result.color.secondary, tHalf;

will clamp the components of your light and halfway vectors to [0,1], completely hosing your directions. Try replacing with

MAD result.color.primary, tLight, 0.5, 0.5;
MAD result.color.secondary, tHalf, 0.5, 0.5;

This compresses the range [-1,1] to [0,1]. In your fragment shader, you’ll have to re-expand these to [-1,1] by multiplying by 2 and subtracting 1 (using a single MAD instruction). This can be done for free if the NV_texture_expand_normal extension is available. You also get it for free in NV_register_combiners by using the EXPAND_NORMAL_NV mapping.

Check the spec for the LIT instruction’s effect. You’ll notice that dots.x is always 1.0. Your N dot L term gets moved to the y component of dots.

Thanks for the tips about the shaders guys. Ill have to try that out thanks alot!

Though it appears i still cant calculate tangent space correctly. If you wouldn’t mind looking over it to check if i have done it right.

CODE CODE CODE
void triangle::calcT(float s0,float t0,float s1,float t1,float s2,float t2){
vector temp1,temp2,temp3,temp4,result,A,B,C,D;
vector tester;
//blar! math! blar!
temp1.set((theTri[0].getX()-theTri[1].getX()),s0-s1,t0-t1);
temp2.set((theTri[0].getX()-theTri[2].getX()),s0-s2,t0-t2);
result = (temp1.cross(temp2));
A.setX(result.getX());
B.setX(result.getY());
C.setX(result.getZ());
temp1.setX((theTri[0].getY()-theTri[1].getY()));
temp2.setX((theTri[0].getY()-theTri[2].getY()));
result = (temp1.cross(temp2));
A.setY(result.getX());
B.setY(result.getY());
C.setY(result.getZ());
temp1.setX((theTri[0].getZ()-theTri[2].getZ()));
temp2.setX((theTri[0].getZ()-theTri[2].getZ()));
result = (temp1.cross(temp2));
A.setZ(result.getX());
B.setZ(result.getY());
C.setZ(result.getZ());
// assign tangent
tangent.setX((-B.getX()/A.getX()));
tangent.setY((-B.getY()/A.getY()));
tangent.setZ((-B.getZ()/A.getZ()));
// assign tester
tester.setX((-C.getX()/A.getX()));
tester.setY((-C.getY()/A.getY()));
tester.setZ((-C.getZ()/A.getZ()));
calcB(tester,s0,t0,s1,t1,s2,t2,A,B,C);

}

Here is some data that i printed out that might help you and me figure out where im going wrong… i print out the first triangle and all the numbers that go with everything.

DATA
Tangent Binormal Normal Test
Position0: 3.108636 24.078770 -5.705012
Position1: 4.607868 22.223236 -3.719416
Position2: 2.983700 20.780043 -5.829112

S0 and T0: 0.863281 -0.218750
S1 and T1: 0.730469 -0.257813
S2 and T2: 0.875000 -0.328125

A = 0.014984 0.014984 0.014984
B = 0.168859 -0.074092 -0.008726
C = 0.000976 -0.459857 -0.017936

Normal: 0.794760 -0.007270 -0.606880
Tangent: -11.269178 4.944729 0.582334
N x T: 2.996624 6.376225 3.847951
dxdt: -0.065141 30.689583 1.197019

Thanks again!

It appears that you’re getting your tangent vector calculation math from one of the old Nvidia bump mapping papers. Unfortunately, that math is not robust. I highly recommend that you read Section 6.8.3 of Mathematics for 3D Game Programming and Computer Graphics. Here’s a link to the first edition:

http://www.terathon.com/books/mathgames.html

The second edition should be out literally any day now:

http://www.terathon.com/books/mathgames2.html