dot3 bumpmapping woes...

Started by
7 comments, last by wxb1 19 years, 10 months ago
I''m sorry for double posting but I''m somewhat desperate... I put together my dot3 code and it works but is faulty... I put together a demo that shows a spinning vase with bumpmaps applied. One of the problem is that as the vase spins so does light? argh!!! I checked the code that creates the tangent space light vector and it looks correct... So now I''m leaning toward the tangent space array but... it looks correct too... My other problem is the bumps show up offset from the location they should be at... Now I computed the tangent space from the information I found at: http://tfpsly.planet-d.net/english/3d/pplight_bump.html I computed the tanget space light vector from some information I found on the powervr site: http://www.prdev.com I''m using dx7 and transforming/lighting the verts myself... Can someone give me some hints on what might be the problem?
Advertisement
Spinning light: Maybe you''ve forgotten to transform the light in object coordinates? Usually, the light is specified (at least in OpenGL, I don''t know DX) in world space. The dot3-bumpmap code I know, however, assumes the light being in object space. It then transforms it in tangent space and does the lighting. If you don''t transform the light vector into object space yourself, the light will rotate, since the object rotates. (The dot3-routine "thinks" the light is always in the same position in OBJECT space!). Try applying the inverse modelview matrix to the light vector first (rotation/translation backwards).

I don''t know why you get an offset. Could be something with the texture coordinates.
I''m using the rotating object''s inverse transform (the transpose) to move the light into object space?
Here''s the psuedo-code...

//1. Compute model space light vector

// a. Compute model space transform...
ModelSpaceBoneMatrix = Inverse(WorldSpaceBoneMatrixArray[BoneIndex]);

ModelSpaceLightPosition = WorldSpaceLightPosition * ModelSpaceBoneMatrix

// c. multiply model space by the vertex
ModelSpaceLightVector = ModelSpaceLightPosition - ModelSpaceVertexArray[VertexIndex];
ModelSpaceLightVector = Normalize(ModelSpaceLightVector);

//2. Compute tangent space light vector
TangetSpaceLightVector = ModelSpaceLightVector * TangentSpaceMatrixArray[VertexIndex];

//3. Convert light vector to color
ColorR = TangetSpaceLightVector.X * 127.5f + 127.5f;
ColorG = TangetSpaceLightVector.Y * 127.5f + 127.5f;
ColorB = TangetSpaceLightVector.Z * 127.5f + 127.5f;
ColorA = 0;
Hmmm, looks very clear and precise to me and you can tell from the variable names which space the vector/position is just in. Thats a good style and it looks correct to me. What happens if you DON''T transform the light vector to model space?
If I don''t use the inverse world matrix then everything is static... as the vase moves toward the light source the bumpmap on the vase doesn''t change... Do you think it''s my calculation of tangent space? Or possibly using the transpose of the matrix as the inverse (I understand if the matrix is orthonormal that you can use the transpose as the inverse of the matrix)? I''m still learning all this so I only barely know what these things mean...
Ok... replaced the createtangent() and inverse() routines with new routines but the problem remains... At least I know the problem are not those routines.... must be something else...
Here''s the real code...

void GENESISCC geBody_SetVertexColorDot3( geVec3d LightPosition, const geXForm3d *Mdl2WldXFA, const geBody *B, int16 VertexIndex, geFloat *ColorDot3,const geCamera *Camera )
{
geBoolean NewLightPosition = GE_FALSE;
geBoolean NewMsLightPosition = GE_FALSE;
geBoolean NewMdl2Wld = GE_FALSE;
geBoolean NewV = GE_FALSE;
geBoolean NewTgt2Mdl = GE_FALSE;
geBoolean NewB = GE_FALSE;
static geBody_Index BoneIndex;
static geVec3d Position;
static geVec3d msLightPosition;
static geVec3d tsLightPosition;
static geVec3d tempv;
static geVec3d v;
static geXForm3d Mdl2Wld;
static geXForm3d Mdl2Tgt;
static geXForm3d invWld2Mdl;
static const geBody *tempB;
const geBody_TangentSpace *Mdl2TgtTS;
const geBody_XSkinVertex *XVA;

if ( !B->XSkinTangentSpace ) return;

Mdl2TgtTS = B->XSkinTangentSpace;

XVA = B->XSkinVertexArray;

NewB = ( B != tempB );

{
BoneIndex = -1;
geVec3d_Clear(&Position);
geVec3d_Clear(&msLightPosition);
geVec3d_Clear(&tsLightPosition);
geVec3d_Clear(&tempv);
geVec3d_Clear(&v);
geXForm3d_SetIdentity(&Mdl2Wld);
geXForm3d_SetIdentity(&Mdl2Tgt);
geXForm3d_SetIdentity(&invWld2Mdl);
tempB = B;
}

//1. Compute model space light vector

// a. Get light position
NewLightPosition = (!geVec3d_Compare(&Position,&LightPosition,0.05f));

geVec3d_Set(&Position,LightPosition.X, LightPosition.Y,LightPosition.Z);

// b. Compute model space
NewMdl2Wld = ( BoneIndex != XVA[VertexIndex].BoneIndex );

{
BoneIndex = XVA[VertexIndex].BoneIndex;
geXForm3d_Copy(&Mdl2WldXFA[BoneIndex],&Mdl2Wld);
geXForm3d_GetTranspose (&Mdl2Wld,&invWld2Mdl);
}

NewMsLightPosition = ( NewLightPosition || NewMdl2Wld );

{
geXForm3d_Transform (&invWld2Mdl, &Position, &msLightPosition);
}

// c. multiply model space by the vertex
NewV = ( !geVec3d_Compare(&tempv,&XVA[VertexIndex].XPoint,0.05f) );

{
geVec3d_Set(&tempv,XVA[VertexIndex].XPoint.X, XVA[VertexIndex].XPoint.Y,XVA[VertexIndex].XPoint.Z);
geVec3d_Set(&v,tempv.X, tempv.Y,tempv.Z);
geVec3d_Subtract(&msLightPosition,&v,&msLightPosition);
geVec3d_Normalize(&msLightPosition);
}

NewTgt2Mdl = ( NewV );

{
Mdl2Tgt.AX = Mdl2TgtTS[VertexIndex].T.X;
Mdl2Tgt.AY = Mdl2TgtTS[VertexIndex].T.Y;
Mdl2Tgt.AZ = Mdl2TgtTS[VertexIndex].T.Z;

Mdl2Tgt.BX = Mdl2TgtTS[VertexIndex].N.X;
Mdl2Tgt.BY = Mdl2TgtTS[VertexIndex].N.Y;
Mdl2Tgt.BZ = Mdl2TgtTS[VertexIndex].N.Z;

Mdl2Tgt.CX = Mdl2TgtTS[VertexIndex].B.X;
Mdl2Tgt.CY = Mdl2TgtTS[VertexIndex].B.Y;
Mdl2Tgt.CZ = Mdl2TgtTS[VertexIndex].B.Z;
}

//2. Compute tangent space light vector
{
// TODO: Does the matrix have to be orthogonal?
geXForm3d_TransformNoOrthogonal (&Mdl2Tgt, &msLightPosition, &tsLightPosition);

}

//3. Convert light vector to color
ColorDot3[0] = tsLightPosition.X * 127.5f + 127.5f;
ColorDot3[1] = tsLightPosition.Y * 127.5f + 127.5f;
ColorDot3[2] = tsLightPosition.Z * 127.5f + 127.5f;
ColorDot3[3] = 0;
}

I''m now convinced that it''s the creation of the light vector that''s the problem some how... I mean d3d does a dot product with the light vector and the normal stored in normal map textur so the variable in question must be the light vector... I''ve checked everything else replaced the tangent and inverse creation routines and still get the same problem... I guess I''ll go do so some reading maybe I''ll find the answer...
OK... my damn normal map was upside down which made things look weird... so one problem fixed! still the light seems to rotate with the spinning object... anybody? anybody?

This topic is closed to new replies.

Advertisement