SOLVED - DX8 Bumpmapping

Started by
13 comments, last by Crow-knee 18 years, 6 months ago
I am having trouble with simple, fixed function pipeline bumpmapping in DX8. What is happening is that the texture comes out too dark. Here are some piccies : My Bumpmap and the results. As you can see I am using the tiger.x model (with the texture to go with it) and am setting up my rendering as such :

D3DXVECTOR3 vLight = D3DXVECTOR3(0.0f, -1.0f, -1.0f); // Light direction
D3DXMATRIX mtxWorld; 
m_mshTest->Get_Matrix(&mtxWorld);	// World matrix of mesh
D3DXVec3TransformNormal(&vLight, &vLight, &mtxWorld);
D3DXVec3Normalize( &vLight, &vLight );
			
DWORD r = (DWORD)(127.0f * vLight.x + 128.0f);
DWORD g = (DWORD)(127.0f * vLight.y + 128.0f);
DWORD b = (DWORD)(127.0f * vLight.z + 128.0f);

DWORD dwFactor = D3DCOLOR_XRGB(r, g, b);

d3dd->SetRenderState(D3DRS_TEXTUREFACTOR, dwFactor);
d3dd->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_DOTPRODUCT3 );
d3dd->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dd->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR );
d3dd->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);  
d3dd->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
d3dd->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_MODULATE );
d3dd->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
d3dd->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
d3dd->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);  
d3dd->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); 

d3dd->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);	// Only have 1 set of tex coords

d3dd->SetTexture(0, m_texNormalMap);	// Normal map
d3dd->SetTexture(1, g_Engine->Get_TextureKeeper()->Get_Texture(m_adwTextures[dw])); // The valid texture



I am creating my bumpmap by doing :

if (FAILED(D3DXCreateTexture(d3dd, 128, 128, 1, D3DX_DEFAULT, D3DFMT_A8R8G8B8,
	D3DPOOL_DEFAULT, &m_texNormalMap))) {
	ErrorPrint(false, ("Failed to create bumpmap.\n"));
	return false;
}
if (FAILED(D3DXComputeNormalMap(m_texNormalMap, texBumpMap, NULL, 0, D3DX_CHANNEL_RED, 10.0f))) {
	ErrorPrint(false, ("Failed to compute normal map.\n"));
	return false;
}


Where texBumpMap is the loaded bumpmap texture. Anyone got any ideas of where I am going wrong? The texture only seems to appear in the highlights of the bumpmap and totally black everywhere else. Thanks for any help, Steele. [Edited by - Crow-knee on September 22, 2005 7:11:54 AM]
Advertisement
Have you tried using a different normal map? It seems to me that the problem could be your normal map. Most normal maps I have seen are a bluish hue. I haven't taken a look at the code, but are you using a heightmap and converting it into a normal map?
Try using D3DTOP_MODULATE2X or D3DTOP_MODULATE4X.

GDNet+. It's only $5 a month. You know you want it.

Looks like it's right here:

if (FAILED(D3DXCreateTexture(d3dd, 128, 128, 1, D3DX_DEFAULT, D3DFMT_A8R8G8B8,	D3DPOOL_DEFAULT, &m_texNormalMap))) {	ErrorPrint(false, ("Failed to create bumpmap.\n"));	return false;}if (FAILED(D3DXComputeNormalMap(m_texNormalMap, texBumpMap, NULL, 0, D3DX_CHANNEL_RED, 10.0f))) {	ErrorPrint(false, ("Failed to compute normal map.\n"));	return false;}

You're creating your texture in m_texNormalMap instead of in &texBumpMap like I think you want to. I'm guessing the conversion from heightmap to normal map isn't happening (you're sending the source some junk object, so it's probably leaving the texture (mostly) alone).

Change that around to
if (FAILED(D3DXCreateTexture(d3dd, 128, 128, 1, D3DX_DEFAULT, D3DFMT_A8R8G8B8,	D3DPOOL_DEFAULT, &texBumpMap))) {	ErrorPrint(false, ("Failed to create bumpmap.\n"));	return false;}if (FAILED(D3DXComputeNormalMap(m_texNormalMap, texBumpMap, NULL, 0, D3DX_CHANNEL_RED, 10.0f))) {	ErrorPrint(false, ("Failed to compute normal map.\n"));	return false;}

(right?) and you'll probably be fine. Btw, you can probably change that multiplier from 10.0f to 1.0f and it'll show up better in the end.

-Michael g.

ps. I haven't coded in forever, so don't trust anything beyond the theoretical application that I suggest ;-)
Thanks guys for the help. I will give them a go when I get home from work.
I have tried different bumpmaps and still get the same results.
I know this is an old technique, but I am stuck with DX8 for now (too much involved in converting my skinned animation system to DX9). I am having trouble finding information on DX8 and using bumpmaps (either fixed function pipeline or shaders), so if anyone has links to this kind of thing (I only have the DX9 SDK - PC rebuild), please let me know! Even where I could download the bumpearth example would be great (google didn't help me).
I will be trying out shaders, so any DX8 resources on how to use/implement them would also be helpful.
I will let you know how I go.
Thanks,
Steele.
Checking out my code again, the issue doesn't seem to be in the order of my texture calls.
texBumpMap is filled in with the bumpmap texture (the My Bumpmap link in the first post), the code for which I did not post. From what I have been able to scrape together from around the place, I have to load in the grayscale image and then run D3DXComputeNormalMap to create a texture that can be used by the texture stage D3DTOP_DOTPRODUCT3. Is this correct?
Steele.
Just a couple of screenshots that should clear up what I am getting.
Without Bumpmap
With Bumpmap

And the full code of loading the bumpmap into the normal map :
		sprintf(sDirFile, "%s%s", ResourceDir, "bumpmap.png");		LPDIRECT3DTEXTURE8 texBumpMap;				if (FAILED(D3DXCreateTextureFromFile(d3dd, sDirFile, &texBumpMap))) {			ErrorPrint(false, ("Failed to load bump map.\n"));			return false;		}		if (FAILED(D3DXCreateTexture(d3dd, 128, 128, 0, D3DX_DEFAULT, D3DFMT_A8R8G8B8,			D3DPOOL_DEFAULT, &m_texNormalMap))) {			ErrorPrint(false, ("Failed to create bumpmap.\n"));			return false;		}		if (FAILED(D3DXComputeNormalMap(m_texNormalMap, texBumpMap, NULL, 0, D3DX_CHANNEL_RED, 1.0f))) {			ErrorPrint(false, ("Failed to compute normal map.\n"));			return false;		}

m_texNormalMap is what I use to plug into texture stage 1 (as per previous code listing).
Any hints?
Steele.
Without Bumpmap
With Bumpmap
(fixed links for ya)

It looks like your normal map is backwards. Instead of this:

D3DXVec3TransformNormal(&vLight, &vLight, &mtxWorld);

try this:
FLOAT tx = vLight.x;FLOAT ty = vLight.y;vLight.x = (tx * mtxWorld._11) + (ty * mtxWorld._12) + (vLight.z * mtxWorld._13);vLight.y = (tx * mtxWorld._21) + (ty * mtxWorld._22) + (vLight.z * mtxWorld._23);vLight.z = (tx * mtxWorld._31) + (ty * mtxWorld._32) + (vLight.z * mtxWorld._33);
Ok, I'll give this a go Kest.
Can you tell me what the difference is from the D3DXVec3TransformNormal function and the lines you have given me? I thought they meant the same thing, though I haven't done the matrix multiply thing for a while. :-)

Off-topic:

Converting FFP skinning to vertex shader is rather simple matter and will even save some memory (instead of storing 1-3 floats per vertex for vertex weights you can store 4 weights in 1 dword). Matrix palette skinning isn't any harder :)

This topic is closed to new replies.

Advertisement