Skip to main content
gamedev.net
🔒 Locked

Normal mapping problem

Started by wizardpc 3 replies 1.3k views
Original Post
wizardpc
wizardpc
Joined: 23 Sep 2006 Posts: 1 PostPosted: Sat Sep 23, 2006 10:00 pm Post subject: Bump Mapping Reply with quote After about the last 4 hours of trying to understand bump maping im getting nothing but a black vertexbuffer. this is in direct x if anyone knows it.


dwTFactor = VectorToRGB(&light);
      m_Graphics.GetDeviceCOM()->SetRenderState(D3DRS_TEXTUREFACTOR, dwTFactor);

      m_Graphics.GetDeviceCOM()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
      m_Graphics.GetDeviceCOM()->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      m_Graphics.GetDeviceCOM()->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
   

      m_Graphics.GetDeviceCOM()->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      m_Graphics.GetDeviceCOM()->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
      m_Graphics.GetDeviceCOM()->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
   
      
        m_Graphics.SetTexture(0, &tBump);
      m_Graphics.SetTexture(1, &tTex);


setting up my light vector is as follows



DWORD VectorToRGB(D3DXVECTOR3* NormalVector)
{
   DWORD dwR = (DWORD) (127 * NormalVector->x +128);
   DWORD dwG = (DWORD) (127 * NormalVector->y +128);
   DWORD dwB = (DWORD) (127 * NormalVector->z +128);

   return (DWORD) (0xff000000 + (dwR << 16) + (dwG << 8) + dwB);
   
}

DWORD dwTFactor;
   D3DXVECTOR3      light(0.0f, 0.0f, 1.0f);




wizardpc
wizardpc
bump


what am i doing wrong?
S1CA
S1CA
From the code snippet posted, that all looks ok to me...


1. A black result using a multitexture setup for DOT3 effects usually means one of the following:

a) the driver/hardware is unhappy with the way you've set up some part of the pipeline (unsupported operation, bad combination of operations, bad combination of texture format and operation, etc).

b) the light vector is pointing away from the normals in your normal map.

c) your normal map is screwed up in some way (such as being in a different space to the one you think they are/pointing the wrong way).

d) D3D is unhappy with something you're asking it to do.


2. As always, the first thing to do (if you aren't already) is enable the Debug Direct3D runtime in the DirectX control panel, turn up the output slider for Direct3D, and take a look at your debuggers output to see if the Direct3D runtime/API has spotted any problems.


3. The code snippet you posted doesn't specify what should happen to the alpha channel. You should specify what happens with alpha, AND it should happen in the same number of stages as colour. Even if all you do for each stage is set ARG2 to current and SELECTARG2 for each stage.


4. Additionally, that code snippet doesn't specify where the blend operation finishes - what value is currently set for COLOROP and ALPHAOP in stage 2 (and 3 and 4 and...) ?
If you set them to something previously, they will still be set to that value. If you relied on D3D to set sensible defaults then they may be sensible (such as TEXTURE MODULATE CURRENT), but as a whole, the operation probably isn't legal on most hardware (very few 8 stage blends are...). If you're on a PURE device with a dodgy driver then the default may be completely random...

To signify the end of your blend operation you should do:
m_Graphics.GetDeviceCOM()->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_Graphics.GetDeviceCOM()->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);


5. If the above still doesn't get you anywhere, try calling IDirect3DDevice::ValidateDevice() immediately before your Draw*Primitive*() [or D3DX mesh draw or whatever] and check the return code (if FAILED(hr)...). ValidateDevice() checks the *whole* of your texture blending operation against all the other state that's currently set (texture formats, etc) and will give you an error for anything bad it finds (in the return code, with more information reported to the output window). NOTE: ValidateDevice() does a *LOT* of work, so it's only something you should call to track down the problem then remove from your main loop afterwards (it's ok to call at initialisation time).


6. Experiment: set your light vector to (1,0,0), and replace your normal map texture with a texture that's pure red (i.e. 255,0,0) - if what you see rendered is completely red, then either your light vector or normal map is at fault.


7. Some old (pre-GeForce256/pre-Permedia3) graphics cards don't support D3DTOP_DOTPRODUCT3, check the D3DCAPS9.TextureOpCaps device cap for D3DTEXOPCAPS_DOTPRODUCT3 with IDirect3DDevice9::GetDeviceCaps or check the caps viewer.
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site
wizardpc
wizardpc
wow some usefull information, ++ for joo, i will test out the red texture experiment when i get home from work
S1CA
S1CA
Ack! complete brain failure, correction to point 6. The result of the red texture and 1,0,0 vector should come out WHITE.
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.