Diffuse lighting problem

Started by
5 comments, last by ReaVeR-Andrey 18 years, 9 months ago
My terrain doesn't have diffuse lighting on it! My normals are all right (just tested them), my light is all right, my materials are all right. RenderStates seem to be correct, too because the terrain is drawn right after a mesh (tiny.x) is drawn. Without diffuse lighting it looks very dark because of ambient lighting. [Edited by - ReaVeR-Andrey on July 26, 2005 3:55:20 AM]
Advertisement
I'm sure the problem is in the render states or something alike. What can be used to turn diffuse on/off?
I tried it with software lighting ("home-made" diffuse lighting code) and it worked perfectly, which means the normals and light direction are okay. The material and light properties seem to be all right, too. What can be the problem?

Here is the terrain-drawing code:
   D3D::SetFVF ( Vertex3D::FVF );   D3D::lpDev->SetStreamSource ( 0, pVB, 0, sizeof ( Vertex3D ) );   D3D::lpDev->SetIndices ( pIB );   Vertex3D* verts;   pVB->Lock ( 0, 0, (void**) &verts, D3DLOCK_DISCARD );   DWORD num = 0;   WORD lastMat = cells [0].matIndex;   D3D::SetMaterial ( mats [lastMat].mat );   D3D::SetTexture ( 0, mats [lastMat].tex );   D3D::SetNullTexture ( 1 );     for ( int y = 0; y < height-1; y++ )   {      int base = y * width;      float initY = ( y % 2 ? 0.5f : 0 );      for ( int x = 0; x < width-1; x++ )      {         float initX = ( x % 2 ? 0.5f : 0 );         if ( num && cells [x+base].matIndex != lastMat )         {            pVB->Unlock ();            HRESULT res = D3D::lpDev->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, 0, 0, num * 4, 0, num * 2 );            pVB->Lock ( 0, 0, (void**) &verts, D3DLOCK_DISCARD );            WORD lastMat = cells [x+base].matIndex;            D3D::SetMaterial ( mats [lastMat].mat );            D3D::SetTexture ( 0, mats [lastMat].tex );            num = 0;         }         verts [num*4+0].v = Vector3D ( (float) x, (float) cells [x+base].height * step, -(float) y ) + pos;         verts [num*4+0].n = normals [cells [x+base].normal];         verts [num*4+0].t = Vector2D ( initX, initY );         verts [num*4+0].color = 0xffffffff;         verts [num*4+1].v = Vector3D ( (float) x+1, (float) cells [x+1+base].height * step, -(float) y ) + pos;         verts [num*4+1].n = normals [cells [x+1+base].normal];         verts [num*4+1].t = Vector2D ( 0.5f+initX, initY );         verts [num*4+1].color = 0xffffffff;         verts [num*4+2].v = Vector3D ( (float) x, (float) cells [x+width+base].height * step, -(float) y-1 ) + pos;         verts [num*4+2].n = normals [cells [x+width+base].normal];         verts [num*4+2].t = Vector2D ( initX, 0.5f+initY );         verts [num*4+2].color = 0xffffffff;         verts [num*4+3].v = Vector3D ( (float) x+1, (float) cells [x+width+1+base].height * step, -(float) y-1 ) + pos;         verts [num*4+3].n = normals [cells [x+width+1+base].normal];         verts [num*4+3].t = Vector2D ( 0.5f+initX, 0.5f+initY );         verts [num*4+3].color = 0xffffffff;         // this is the home-made lighting         for ( DWORD i = num*4; i < num*4+4; i++ )         {            float dif = -lightDir & verts .n;            Vector3D color = *((Vector3D*)&(mats [lastMat].mat.ambient)) * amby +              *((Vector3D*)&(mats [lastMat].mat.diffuse)) * max( dif, 0 );            DWORD r = (int) ( color.x * 255 );            DWORD g = (int) ( color.y * 255 );            DWORD b = (int) ( color.z * 255 );            verts .color = ((r&0xff)<<16)|((g&0xff)<<8)|(b&0xff)|0xff000000;         }         // end of homemade lighting         num++;         if ( num >= maxVBItems )         {            pVB->Unlock ();            HRESULT res = D3D::lpDev->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, 0, 0, num * 4, 0, num * 2 );            pVB->Lock ( 0, 0, (void**) &verts, D3DLOCK_DISCARD );            num = 0;         }      }   }   pVB->Unlock ();   if ( num )      D3D::lpDev->DrawIndexedPrimitive ( D3DPT_TRIANGLELIST, 0, 0, num * 4, 0, num * 2 );
One thread not enough for you?? [wink]

Your fragment does not show:

• D3DRS_LIGHTING render state. It should be TRUE.
• How you configured your D3DLIGHT9 structure
• If you made SetLight() or LightEnable() calls.
• You haven't shown any other render states or texture stage states

Also, you've wrapped up your device calls in a D3D namespace by the looks of it? No one here will know what those calls do - are you SURE that they do what you think they do?

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

They're not namespace functions, they're class static functions.
They look like this:
bool D3D::X ( ... )
{
return lpDev ? SUCCEEDED ( lpDev->X ( ... ) ) : false;
}

Yes the light structure and everything else is okay.
Here are my renderstates:

   SetRenderState ( D3DRS_ZENABLE, D3DZB_TRUE );   SetRenderState ( D3DRS_LIGHTING, TRUE );   SetRenderState ( D3DRS_AMBIENT, 0xff666666 );   SetRenderState ( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1 );   SetRenderState ( D3DRS_CULLMODE, D3DCULL_NONE );

Is there any scaling in the world transform?

That's a classic that's caught me out a few times... if the geometry is scaled to 10% size, the normals become 1/10th of the length, thus the mathematics makes the lighting 1/10th of what you might be expecting - which could be nearly black [smile]

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Is world matrix applied to normals???

(I scaled it 400 times to make 2 units be as tall as Tiny)

!EDIT!
oops. that was not it too...

This topic is closed to new replies.

Advertisement