Lighting

Started by
5 comments, last by combatc2 17 years, 10 months ago
I'm trying to create a rotating pyramid with a beam of light on one side of it (example in a book I'm reading..) .. I have gotten everything to work besides the light beam .. my pyramid just rotates and is blank white with no shading whatsoever .. I'm trying to use a directional light.
// Set the Color & Material
D3DCOLORVALUE myVal;
myVal.r = 1.0f;
myVal.g = 1.0f;
myVal.b = 1.0f;
myVal.a = 0.0f;
	
D3DMATERIAL9 mtrl;
mtrl.Ambient = myVal;
mtrl.Diffuse = myVal;
mtrl.Specular = myVal;
mtrl.Emissive = myVal;
mtrl.Power = 5.0f;
Device->SetMaterial(&mtrl);


D3DLIGHT9 dir;
::ZeroMemory(&dir, sizeof(dir));
dir.Type = D3DLIGHT_DIRECTIONAL;
dir.Diffuse = myVal;
dir.Specular = myVal;
dir.Ambient = myVal;
dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);

Device->SetLight(0, &dir);
Device->LightEnable(0, true);

Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
Device->SetRenderState(D3DRS_SPECULARENABLE, false);
Thanks in advance, Carl EDIT: Added 'source' tags... [Edited by - jollyjeffers on June 25, 2006 8:56:49 AM]
Advertisement
As a side-note... you should use [source]...[/source] tags for posting code fragments [smile]

Two things you haven't posted that are important:

1. Is D3DRS_LIGHTING set to TRUE?

2. How are your normals defined for your geometry? Have you definitely got the correct vertex format (SetFVF() call and value)?

Whilst you should get a bright AND a dark side - with the colours you've suggested you will end up with a completely white/saturated part [smile]

hth
Jack

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

Sorry about that .. (the no source tags)

So I have my Vertex struct:
struct Vertex {	Vertex() { }	Vertex(float x, float y, float z, float nx, float ny, float nz) {		_x = x; _y = y; _z = z;		_nx = nx; _ny = ny; _nz = nz;	}	float _x, _y, _z;	float _nx, _ny, _nz; // Normals	// D3DCOLOR _color; Using lighting		static const DWORD FVF;};const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL;


And I call the SetFVF function as follows:
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);		Device->BeginScene();Device->SetStreamSource(0, Pyramid, 0, sizeof(Vertex));Device->SetFVF(Vertex::FVF);Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);Device->EndScene();Device->Present(0, 0, 0, 0);


Also D3DRS_LIGHTING is set to true
As for the normals being defined correctly for the geometry, I actually don't really know what you mean .. I'm sorry I'm just pretty new to DirectX

Thanks again,
Carl
Despite what I previously said, I've got a feeling it might be as simple as your ambient lighting value...

Set your mtrl.Ambient and dir.Ambient to be <0,0,0,0>. Ambient acts as the "lower bound" effectively - you wont get any darker than the ambient colour, and with it set to maximum/white it'd result in something similar to your problem [smile]

Just for completeness:

Quote:As for the normals being defined correctly for the geometry, I actually don't really know what you mean .. I'm sorry I'm just pretty new to DirectX
A vertex is essentially just a position (x,y,z) and its the normal that determines which direction its facing - in simple cases this will be aligned with the surface of the corresponding triangle.

The lighting computation uses this normal to determine if the vertex is facing the light source so it can scale the light contribution accordingly. If you get the normals incorrect then this calculation gets thrown out and you get somewhat obscure results.

It can be tricky to debug incorrect normals, so sometimes it just requires you to step through the calculations.

hth
Jack

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

Okay, I have now tried:
// Set the Color & Material	D3DCOLORVALUE myVal;	myVal.r = 1.0f;	myVal.g = 1.0f;	myVal.b = 1.0f;	myVal.a = 0.0f;	D3DCOLORVALUE dark;	dark.r = 0.0f;	dark.g = 0.0f;	dark.b = 0.0f;	dark.a = 0.0f;	D3DMATERIAL9 mtrl;	mtrl.Ambient = dark;	mtrl.Diffuse = myVal;	mtrl.Specular = myVal;	mtrl.Emissive = myVal;	mtrl.Power = 5.0f;	Device->SetMaterial(&mtrl);	D3DLIGHT9 dir;	::ZeroMemory(&dir, sizeof(dir));	dir.Type = D3DLIGHT_DIRECTIONAL;	dir.Diffuse = myVal;	dir.Specular = myVal;	dir.Ambient = dark;	dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);	Device->SetLight(0, &dir);	Device->LightEnable(0, true);	Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);	Device->SetRenderState(D3DRS_SPECULARENABLE, false);


But setting mtrl.Ambient = dark and dir.Ambient = dark didn't give me the shadow either?

Thanks again,
Carl
Set emissive to dark. Emissive is added on at the end of lighting. Adding white means nothing will ever be darker than white.
Thanks alot everyone. I finally got it to work!
If your interested here's what finally ended up working:
D3DCOLORVALUE myVal;	myVal.r = 1.0f;	myVal.g = 1.0f;	myVal.b = 1.0f;	myVal.a = 0.0f;	D3DCOLORVALUE dark;	dark.r = 0.0f;	dark.g = 0.0f;	dark.b = 0.0f;	dark.a = 0.0f;	D3DCOLORVALUE gray;	gray.r = 0.3f;	gray.g = 0.3f;	gray.b = 0.3f;	gray.a = 0.3f;	D3DCOLORVALUE gray2;	gray2.r = 0.6f;	gray2.g = 0.6f;	gray2.b = 0.6f;	gray2.a = 0.6f;	D3DMATERIAL9 mtrl;	mtrl.Ambient = myVal;	mtrl.Diffuse = myVal;	mtrl.Specular = myVal;	mtrl.Emissive = dark;	mtrl.Power = 5.0f;	Device->SetMaterial(&mtrl);	D3DLIGHT9 dir;	::ZeroMemory(&dir, sizeof(dir));	dir.Type = D3DLIGHT_DIRECTIONAL;	dir.Diffuse = myVal;	dir.Specular = gray;	dir.Ambient = gray;	dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);	Device->SetLight(0, &dir);	Device->LightEnable(0, true);	Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);	Device->SetRenderState(D3DRS_SPECULARENABLE, false);



Thanks again,
Carl

This topic is closed to new replies.

Advertisement