Archived

This topic is now archived and is closed to further replies.

Zeblar Nagrim

Ugly rendering in d3d8, need help!

Recommended Posts

Hi! I have a serius problem with rendering (or light) in Direct 3D8, please help! I´m not a beginner. I have made a wall section with which contains 4x4 quads as a simple test (to fix the same problem in my bigger project). When I render these with DrawPrimitive as either triangle strip or triangle list, I can clearly see the triangels in the wall section. The wall face negative z direction and each quad have these vertices and normal if "sz" is size and are created as triangle strip: {-sz.x,-sz.y, sz.z},{-sz.x, sz.y, sz.z},{ sz.x,-sz.y, sz.z},{ sz.x, sz.y, sz.z},{ 0, 0,-1} I render every quad with a separate call to DrawPrimitive (to enable exchange of textures):
  

    for(int i=0; i<m_iPrimitives/2; i++)
    {
      device->SetTexture(0, CTextureBank::GetTexture(m_piTexture[i]));
      device->DrawPrimitive( d3dprimtype, uiStartVertex, 2 );
      uiStartVertex += 4;
    }

  
When I switch off light and only use ambient light source the triangels stay invisible (as I want to). But I want to use point light! Maybe I have set up my light wrong?
  

void CDirect3DWin::SetLight()
{
  const float MAX_LIGHT = 200;
  const float TIONDEL_DIV_MAX_LIGHT = 0.1f / MAX_LIGHT;

  D3DLIGHT8 m_Light;
  FLOAT m_LightValue = MAX_LIGHT; 

  ZeroMemory(&m_Light, sizeof(m_Light));
  m_Light.Type       = D3DLIGHT_POINT ; 
  m_Light.Diffuse.r  = m_LightValue*1.0f;
  m_Light.Diffuse.g  = m_LightValue*1.0f;
  m_Light.Diffuse.b  = m_LightValue*1.0f;
  m_Light.Range      = m_LightValue/2;
  m_Light.Attenuation2 = 0.55f;
  m_Light.Attenuation1 = 0.55f;
  m_Light.Attenuation0 = 0.55f/2;
  m_Light.Position = m_BeholderPos;
  m_Light.Direction = m_BeholderDir;
  
  m_pd3dDevice->SetLight( 0, &m_Light );
  m_pd3dDevice->LightEnable( 0, TRUE );
  m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
  m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 
    D3DCOLOR_COLORVALUE(0.1f, 0.1f, 0.1f, 1));
  
  m_pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE);
  m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   TRUE );    

  D3DMATERIAL8 mtrl;
  ZeroMemory( &mtrl, sizeof(D3DMATERIAL8) );
  mtrl.Diffuse.r = mtrl.Ambient.r = mtrl.Diffuse.g = mtrl.Ambient.g = 
  mtrl.Diffuse.b = mtrl.Ambient.b = TIONDEL_DIV_MAX_LIGHT*m_LightValue;
  mtrl.Diffuse.a = mtrl.Ambient.a = 0.0f;

  m_pd3dDevice->SetMaterial( &mtrl );
}

  
Please help me solve this problem! I can´t go any further if I not solve this problem! Any help are much-appreciated! Thanks, Zeblar Nagrim, Lord of Chaos

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The only solution i know of to this is to "bake" the lighting into your textures (although i''m sure there are alternatives). The problem is b/c your point light is located at some exact x,y,z coordinate in cartesian space. D3D will be taking this into account when doing the lighting across your wall, and obviously the normals of your 2 wall triangles will form different angles with the light, and thus will be shaded differently. see diagram below.

light |
0-----> <--| tri 1 normal
|
|
<--| tri 2 normal
|

see how the angles would be different from light to tri 1/2 normal? Even though the tri normals are exactly the same (I presume).

another other option is to make the wall out of a whole slew of triangles, but this isn''t really practical. Finally, you can drop the idea of using a point light, and use a directional ight instead.

Either that or get per-pixel lighting going on. :-)


Share this post


Link to post
Share on other sites
Guest Anonymous Poster
damn sorry the drawing came out wrong. The 2 tri''s are supposed to be aligned vertically.

Share this post


Link to post
Share on other sites
You gotta use vertex normals. For each vertex the vertex normal is the average of the normals of all the faces which share that vertex. That will give you a very nice and creamy look.

Share this post


Link to post
Share on other sites
I think your problem is that D3D automatically averages out the normals at each vertex when you use triangle-strips (to produce smooth shading). So although the normal you supply is 0,0,-1, this isn''t what D3D is using. Try switching to triangle-lists instead, since D3D will actually use the normals supplied then.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Thanks for all replys!

simon_brown75 : I have already tried to switch to triangle-lists. It looks the same .

Poya : I don´t really understand what you mean. The averange is -1 (-1*4/4 = -1). Maybe you can show me exactly what you mean by changing this function:

  

HRESULT CreateNegZQuad(D3DXVECTOR3 sz, D3DXVECTOR3 pos,
CUSTOMVERTEX *pVertices, DWORD *dwOffset,
float tex_x, float tex_y)
{
struct vertices
{
D3DVECTOR p0;
D3DVECTOR p1;
D3DVECTOR p2;
D3DVECTOR p3;
D3DVECTOR n;
};

vertices VERTICES[1] =
{
{
{-sz.x,-sz.y, sz.z},
{-sz.x, sz.y, sz.z},
{ sz.x,-sz.y, sz.z},
{ sz.x, sz.y, sz.z},
{ 0, 0,-1}
}
};

// Translate to position

VERTICES[0].p0.x += pos.x; VERTICES[0].p0.y += pos.y; VERTICES[0].p0.z += pos.z;
VERTICES[0].p1.x += pos.x; VERTICES[0].p1.y += pos.y; VERTICES[0].p1.z += pos.z;
VERTICES[0].p2.x += pos.x; VERTICES[0].p2.y += pos.y; VERTICES[0].p2.z += pos.z;
VERTICES[0].p3.x += pos.x; VERTICES[0].p3.y += pos.y; VERTICES[0].p3.z += pos.z;

pVertices[*dwOffset+0].pos = VERTICES[0].p0;
pVertices[*dwOffset+1].pos = VERTICES[0].p1;
pVertices[*dwOffset+2].pos = VERTICES[0].p2;
pVertices[*dwOffset+3].pos = VERTICES[0].p3;

pVertices[*dwOffset+0].n = pVertices[1].n =
pVertices[*dwOffset+2].n = pVertices[3].n = VERTICES[0].n;

float tu, tv;

tu = sz.x; tv = sz.y;

pVertices[*dwOffset+1].tu = tex_x; pVertices[*dwOffset+1].tv = tex_y;
pVertices[*dwOffset+0].tu = tex_x; pVertices[*dwOffset+0].tv = tex_y+tv;
pVertices[*dwOffset+3].tu = tex_x+tu; pVertices[*dwOffset+3].tv = tex_y;
pVertices[*dwOffset+2].tu = tex_x+tu; pVertices[*dwOffset+2].tv = tex_y+tv;

*dwOffset+=4;

return S_OK;
}


Anonymous Poster : Thanks for the explanation ! Maybe I should try to use directional light yet...

More information are appreciated.








Zeblar Nagrim, Lord of Chaos

Share this post


Link to post
Share on other sites
I have found the problem. It was the light. When I set the ambient color value to same value as the diffuse color the triangle stay invisible. YES! Greeeeat!

Thanks anyway,



Zeblar Nagrim, Lord of Chaos

Share this post


Link to post
Share on other sites