• Advertisement

# lighting problem...

This topic is 4917 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

Hi, I'm trying to get a model lit, but it isn't working. The following pic shows the model in two phases of its rotation, one appears black, the other affected by the light... i guess: this is what I'm doing:
void SetupLights()
{
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
mtrl.Diffuse.r = 1.0f;
mtrl.Diffuse.g = 0.5f;
mtrl.Diffuse.b = 0.0f;
mtrl.Diffuse.a = 1.0f;
g_pd3dDevice->SetMaterial( &mtrl );

D3DLIGHT9 light;
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type       = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r  = 1.0f;
light.Diffuse.g  = 1.0f;
light.Diffuse.b  = 1.0f;
light.Direction.x = 2.0f;
light.Direction.y = 30.0f;
light.Direction.z = -30.0f;
light.Range       = 1000.0f;
g_pd3dDevice->SetLight( 0, &light );
g_pd3dDevice->LightEnable( 0, TRUE );
}

void Render()
{
if(g_pd3dDevice == NULL)
return;

g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(234, 234, 234), 1.0f, 0);

g_pd3dDevice->BeginScene();

SetupLights();
SetupMatrices();

mdx->BuildNormals();

g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(Vertex));
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pd3dDevice->SetIndices(g_pIB);
g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mdx->m_pMeshes[0].m_iNumVerts, 0, mdx->m_pMeshes[0].m_iNumFaces);

g_pd3dDevice->EndScene();
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}


and here is the BuildNormals method:
void CMdx::BuildNormals()
{
for (int i = 0; i < m_iNumMeshes; i++)
{
Mesh &mesh = m_pMeshes;

for (int j = 0; j < mesh.m_iNumVerts; j++)
{
mesh.m_pVert[j].normal.x = 0;
mesh.m_pVert[j].normal.y = 0;
mesh.m_pVert[j].normal.z = 0;
}

for (int j = 0; j < mesh.m_iNumFaces; j++)
{
Face &tri = mesh.m_pFace[j];

Vertex &v0 = mesh.m_pVert[tri.vertIndex[0]];
Vertex &v1 = mesh.m_pVert[tri.vertIndex[1]];
Vertex &v2 = mesh.m_pVert[tri.vertIndex[2]];

float Ax = v1.position.x - v0.position.x;
float Ay = v1.position.y - v0.position.y;
float Az = v1.position.z - v0.position.z;

float Bx = v2.position.x - v0.position.x;
float By = v2.position.y - v0.position.y;
float Bz = v2.position.z - v0.position.z;

float nx = Ay * Bz - By * Az;
float ny = -(Ax * Bz - Bx * Az);
float nz = Ax * By - Bx * Ay;

v0.normal.x += nx;
v0.normal.y += ny;
v0.normal.z += nz;

v1.normal.x += nx;
v1.normal.y += ny;
v1.normal.z += nz;

v2.normal.x += nx;
v2.normal.y += ny;
v2.normal.z += nz;
}

for (int j = 0; j < mesh.m_iNumVerts; j++)
{
Vertex &v = mesh.m_pVert[j];

float len = float(sqrt(v.normal.x * v.normal.x + v.normal.y * v.normal.y + v.normal.z * v.normal.z));

if (len)
{
v.normal.x /= len;
v.normal.y /= len;
v.normal.z /= len;
}
}
}
}


Any help?

#### Share this post

##### Share on other sites
Advertisement
Is the object rotating or are you rotating the view matrix? If you are rotating the view matrix, then the light is staying constant, so on one side you're staring into the light and can't see anything (black figure) and on the other side the light is illuminating, rather crazy-like, the figure.

A couple of comments: Range is not used for directional lights, so you can remove that. I didn't see a SetRenderState to enable D3D Lighting, though I believe you are setting that. Also, add some ambient lighting, by setting the ambient render state. You should only have to calculate the normals once, instead of every frame. Other than these, which aren't really indicative of what you're seeing, I don't see what's wrong...although the normals defined incorrectly will cause this. Are you applying a texture?

Chris

#### Share this post

##### Share on other sites
I'm not very familiar with DirectX but from looking at your code, it seems that your vertex normal calculation is off. You should be calculating a vertex normal based on the face normals of all faces adjacent to a vertex. Your code seems to iterate through all the faces, calculates a face normal (un-normalized) and adds this to a running sum for each of the adjacent verticies.

The problem here is that the normal you calculate has a length that depends on the size of the triangle face. The vertex normal should be the average of all the face normals adjacent to that vertex. You method skews the average by weighing the larger faces more. To fix this, you should normalize each face normal before adding to the running sum for each vertex.

I don't know if this will fix your lighting problem but it is a place to start.

Zeljko Pavic

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement
• ### Popular Tags

• Advertisement
• ### Popular Now

• 9
• 10
• 12
• 10
• 10
• Advertisement