Lighting

Started by
6 comments, last by Albert001 15 years, 3 months ago
I am using DirectX and I have a problem in setting up my lighting. I render two arrays of vertices with PositionColor and Texture and the second one a set of points (point cloud). Meanwhile I set up a couple of directional lights and I set material for the PositionColor and Texture vertices. However the pointcloud as opposed to PositionColor and Texture vertices get colored and still the PositionColor and Texture vertices appear in black. I have checked all the normals and I am sure they have values. Does anyone know how I can fix this issue? Thanks
Advertisement
There can be a number of problems without seeing a screenshot or some code.

Which way is the directional light facing and which way is your primitive facing?

<-------
| <-------
| <-------
| <------- (Directional light that should be facing the primitive)
| <-------
| <-------
<-------

Also, make sure that you have assigned the materials.

I hope this helps!

[Edited by - Armadon on January 21, 2009 9:06:00 AM]
Sounds like MDX fixed-function to me. My initial guess is that PositionColor is equivalent to D3DFVF_XYZ|D3DFVF_DIFFUSE which specifies per-vertex lighting values rather than actual computed ones. Change to just Position and you should be ok. If you need both colour and lighting then you need to look into the render states for materials (and possibly the texture cascade), but I'm rusty on my FF states so can't remember what these are off the top of my head...


hth
Jack

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

Thanks for both of the replies. I also added an ambient light, but again only the PositionColor vertices ( D3DFVF_XYZ|D3DFVF_DIFFUSE) get the light. The problem is I am rendering these vertices as a PointList and I am not for sure if it makes sense for me to define separate materials for each.

However the PositionNormal Vertices ( D3DFVF_XYZ|D3DFVF_NORMAL) are still rendered in black though there is a good ambient light in the scene.

How can I set the material to only get applied to the PositionNormal vertices and not to affect the PositionColor ones? or is this possible at all? or do I need to define a single material for each PositionColor vertex?


Thanks


Quote:..only the PositionColor vertices ( D3DFVF_XYZ|D3DFVF_DIFFUSE) get the light
this isn't what I'd expect to be honest.

Having a play with PIX will be a good idea. This allows you to investigate the pipeline state at the time your geometry was rendered - what material, lights and normals were actually used. It's easier than you think to "leak" pipeline states and get very bizare results!

Failing that, posting a summary of the pipeline configuration and the data you're sending in (not just a big code dump please [wink]). Maybe one of us can spot what you're doing wrong!

Quote:How can I set the material to only get applied to the PositionNormal vertices and not to affect the PositionColor ones? or is this possible at all? or do I need to define a single material for each PositionColor vertex?
A material is valid for an entire ::Draw**() call. You can change the material as many times as you like, but whatever is set when you draw your geometry is the one that'll be used.

If you want to render lots of geometry with different materials then you'll have to split that geometry up into multiple draw calls (one per material).

You should never need to create a material for each vertex.

hth
Jack

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

Hi Jack

The structure of a vertex for 3D model is defined as follows:

struct a_customvertex {
float x, y, z;
float nx,ny,nz;
};

Also for the pointcloud is defined as follows:

typedef struct PositionColor
{
public:
PositionColor() : X(0), Y(0), Z(0), Color(0) {}
PositionColor( float x, float y, float z, DWORD color )
: X(x), Y(y), Z(z), Color(color) {}
float X, Y, Z;
DWORD Color;
} PositionColor;


I have set the FVF for the a_customvertex based model as D3DFVF_XYZ | D3DFVF_NORMAL and for PositionColor used for point cloud as D3DFVF_XYZ | D3DFVF_DIFFUSE.


Here is how I use lighting on my OnRenderFrame class:

pDevice->BeginScene();
SetUpLights( pDevice );
...
pDevice->SetStreamSource(0, m_aplannedB, 0, sizeof(a_customvertex));

//Render the 3d model
STRUCT_INSTANCES * instance = first_instance;
while (instance) {
pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, instance->startIndex, instance->primitiveCount);
}
instance = instance->next;
}


D3DMATERIAL9 mtrl;
mtrl.Diffuse.r = mtrl.Ambient.r = mtrl.Specular.r = 1.0f;
mtrl.Diffuse.g = mtrl.Ambient.g = mtrl.Specular.g = 1.0f;
mtrl.Diffuse.b = mtrl.Ambient.b = mtrl.Specular.b = 1.0f;
mtrl.Diffuse.a = mtrl.Ambient.a = mtrl.Specular.a = 0.5f;

mtrl.Emissive.r = 0.1f;
mtrl.Emissive.g = 0.1f;
mtrl.Emissive.b = 0.1f;
mtrl.Emissive.a = 0.5f;

pDevice->SetMaterial(&mtrl);

...

pDevice->EndScene();
pDevice->Present( 0, 0, 0, 0 );


Here is my light class:

void CApp::SetUpLights( LPDIRECT3DDEVICE9 pDevice )
{
float max = 1;
D3DXVECTOR3 vecDir;
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(D3DLIGHT9));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = 0.5f;
light.Diffuse.g = 0.5f;
light.Diffuse.b = 0.5f;
light.Diffuse.a = 1.0f;
light.Specular.r = 0.0f;
light.Specular.g = 0.0f;
light.Specular.b = 0.0f;
light.Specular.a = 0.0f;
light.Ambient.r = 0.0f;
light.Ambient.g = 0.0f;
light.Ambient.b = 0.0f;
light.Ambient.a = 0.0f;
light.Position.x = (float) -2.0f;
light.Position.y = (float) -2.0f;
light.Position.z = (float) -2.0f;
vecDir.x = -2.0f;
vecDir.y = -6.0f;
vecDir.z = -1.0f;
D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction, &vecDir);
light.Range = 5.0f;

pDevice->SetLight( 0, &light );
pDevice->LightEnable ( 0, true ) ;

D3DLIGHT9 light1;
ZeroMemory(&light1, sizeof(D3DLIGHT9));
light1.Type = D3DLIGHT_DIRECTIONAL;
light1.Diffuse.r = 0.5f;
light1.Diffuse.g = 0.5f;
light1.Diffuse.b = 0.5f;
light1.Diffuse.a = 1.0f;
light1.Specular.r = 0.0f;
light1.Specular.g = 0.0f;
light1.Specular.b = 0.0f;
light1.Specular.a = 0.0f;
light1.Ambient.r = 0.0f;
light1.Ambient.g = 0.0f;
light1.Ambient.b = 0.0f;
light1.Ambient.a = 0.0f;
light1.Position.x = (float) 2.0f;
light1.Position.y = (float) 2.0f;
light1.Position.z = (float) 2.0f;
vecDir.x = 2.0f;
vecDir.y = 6.0f;
vecDir.z = 1.0f;
D3DXVec3Normalize((D3DXVECTOR3*)&light1.Direction, &vecDir);
light1.Range = 5.0f;


pDevice->SetLight( 1, &light1 );
pDevice->LightEnable ( 1, true ) ;

// Finally, turn on some ambient light.
pDevice->SetRenderState(D3DRS_AMBIENT, 0x00707070 );

}


Unfortunately the 3d model appears in black (as if the normals are not parsed in). I have traced the parsing and I am for sure the normals are in, however the model still appears in black and the pointcloud gets colored!!!


Is there anyway that I can figure out what's going wrong with the material and/or lighting setup for the 3D model and why instead of lighting the model, it lights the point cloud?

Thanks,
Albert
Have you enabled lighting on the device?
device−>SetRenderState (D3DRS LIGHTING , TRUE) ;
Also, when using a directional light, you don't need to set the position. You only need to setup the direction and off you go.

I hope this helps.
Yes, the lighting is enabled, but unfortunately it only associates the colors with the pointcloud as opposed to the 3D model vertices.


This topic is closed to new replies.

Advertisement