PDA

View Full Version : Bumpmapping?



Lurking
11-16-2003, 10:56 AM
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!

Eric Lengyel
11-17-2003, 08:17 AM
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

Lurking
11-17-2003, 11:59 AM
!!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

Eric Lengyel
11-17-2003, 08:23 PM
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.

Eric Lengyel
11-17-2003, 09:52 PM
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.

Lurking
11-18-2003, 03:33 PM
Thanks for the tips about the shaders guys. Ill have to try that out thanks alot!

Lurking
11-18-2003, 07:42 PM
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!

Eric Lengyel
11-18-2003, 11:31 PM
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