Sign in to follow this  
Hawkblood

Help with HLSL normal mapping with multiple lights

Recommended Posts

I'm potentially opening up a can of worms with this topic-- mainly because I'm not sure what or how to ask.....

 

I've been using a normal mapping .fx from http://www.evolved-software.com/ (multipassLighting). It worked ok until I started running into trouble (my fault not the shader's). During my troubleshooting, I decided to have a look at some other multi-light normalmapping shaders. I noticed a very obvious difference: the newer ones all had loops in them for the number of lights. This is unlike the old one where it had a distinct pass for each light (looks messy). I thought "what the heck. Let's try it out."..... I can't get them to work! They show the geometry, but the lighting effect (using a single light for testing) doesn't show properly. There is another difference:

float4x4 worldMatrix;
float4x4 worldInverseTransposeMatrix;
float4x4 worldViewProjectionMatrix;

float3 cameraPos;
float4 globalAmbient;
int numLights;

PointLight lights[MAX_POINT_LIGHTS];
 

The "worldInverseTransposeMatrix" is new (to me). In the example code provided, they set this to identity. They also set the "worldMatrix" to identity. I think they can be set that way because the box you are in is centered around the origin (I think)....

 

Now, with all that said, the question is: What is the "worldInverseTransposeMatrix" and how do I use it? The others seem self-explanatory such as "worldMatrix" is the rendered object's position & rotation relative to the camera.

Share this post


Link to post
Share on other sites

worldInverseTranspose is the transpose of the inverse of your world matrix.  Most of the time, you can use the upper-left 3x3 portion of your world matrix to transform your normals, but there are some cases where you have non-uniform scales or shears as part of the world matrix, in which case the transformed normal is not correct.  I don't have the explanation on hand, but transforming the normals by the inverse-transpose fixes this problem.

 

Some C#/SlimDX code to compute the inverse-transpose (Note that the translation portion of the matrix is zero'd out):

public static Matrix InverseTranspose(Matrix m) {

    var a = m;
    a.M41 = a.M42 = a.M43 = 0;
    a.M44 = 1;

    return Matrix.Transpose(Matrix.Invert(a));
}

Share this post


Link to post
Share on other sites

I'm still doing something wrong. Here the section of code for rendering:

	for (UINT i=0;i<Section[s].Objects.size();i++) {
		tmp=Section[s].Objects[i].matrix;
		tmp(3,0)+=v.x;
		tmp(3,1)+=v.y;
		tmp(3,2)+=v.z;

		FXManager.Effect[NormalMappingFX].FX->SetMatrix("worldMatrix", &tmp);

		D3DXMATRIX wit=tmp;
		wit(3,0)=0;
		wit(3,1)=0;
		wit(3,2)=0;
		wit(3,3)=1;;
		D3DXMatrixInverse(&wit,0,&wit);
		D3DXMatrixTranspose(&wit,&wit);
		FXManager.Effect[NormalMappingFX].FX->SetMatrix("worldInverseTransposeMatrix", &wit);

		tmp*=VP;
		FXManager.Effect[NormalMappingFX].FX->SetMatrix("worldViewProjectionMatrix", &tmp);

		if (SUCCEEDED(FXManager.Effect[NormalMappingFX].FX->Begin(&totalPasses, 0)))
		{
			for (UINT pass = 0; pass < totalPasses; ++pass)
			{
				if (SUCCEEDED(FXManager.Effect[NormalMappingFX].FX->BeginPass(pass)))
				{
					MeshObject[mesh].ppMesh->DrawSubset(Section[s].Objects[i].ObjIndex);
					FXManager.Effect[NormalMappingFX].FX->EndPass();
				}
			}

			FXManager.Effect[NormalMappingFX].FX->End();
		}

	}

Am I missing something?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this