Lights

Started by
14 comments, last by Tagamoga 21 years, 2 months ago
Hello. I am trying to turn on lights in my scene. Until now I have one triangle - yes for me it is GREAT *g* - With one blue, red and yellow corner and it rotates raound his Y-Axis... Until now I was using, untransformed Vertexes with Color. And the rotation was made by changing the WorldMatrix. Now I added Vertex normals. Still everything was working fine. Then I added one Material for the whole scene... ~g~ yes, it is still only one triangle... Everything was still working fine.. Here my Material Code: D3DMATERIAL8 Material; ZeroMemory(&Material, sizeof(D3DMATERIAL8)); Material.Diffuse.r = 1.0f; Material.Diffuse.g = 1.0f; Material.Diffuse.b = 1.0f; Material.Diffuse.a = 1.0f; Material.Ambient.r = 1.0f; Material.Ambient.g = 1.0f; Material.Ambient.b = 1.0f; Material.Ambient.a = 1.0f; g_pDevice->SetMaterial(&Material); The fact that my triangle has still his great bright colors and is still visible, and still rotates... I added one single Light... My Code: D3DLIGHT8 Light; ZeroMemory(&Light, sizeof(D3DLIGHT8)); Light.Type = D3DLIGHT_POINT; Light.Diffuse.r = 1.0f; Light.Diffuse.g = 1.0f; Light.Diffuse.b = 1.0f; Light.Position = D3DXVECTOR3(0,0,-9); Light.Range = 10.0f; g_pDevice->SetLight(0,&Light); g_pDevice->LightEnable(0,TRUE); g_pDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB( 100, 100, 100 ) ); But now my great triangle is ugly.... sometime it has still a blue corner... but the oder are pale grey... and the blue color ist switching on and off... I thought, that the light would enlight the Middle of my beautifull triangle, but now.... what did I wrong? Can somebody explain me, how to set up lights correct? *g* Yes I know that is much stuff, but a beginning would be great... almost as great as my bright coloured single spinning traingle.... *smile* Taggi
Advertisement
D3DLIGHT8 Light;
ZeroMemory(&Light, sizeof(D3DLIGHT8));
Light.Type = D3DLIGHT_POINT;
Light.Diffuse.r = Light.Ambient.r = 1.0f;
Light.Diffuse.g = Light.Ambient.g = 1.0f;
Light.Diffuse.b = Light.Ambient.b = 1.0f;
Light.Diffuse.a = Light.Ambient.a = 1.0f;
Light.Position = D3DXVECTOR3(0.0f, 0.0f, -9.0f);
Light.Range = 50.0f; // Needs to reach vertices, not plane
Light.Attenuation1 = 1.0f;

See if that works.

With respect to the gray color: By default the diffuse material color comes from the vertex diffuse color. The ambient material, by contrast, comes from the material settings.

So what''s happening right now is that global ambient (100,100,100) is being multiplied by material ambient (1.0, 1.0, 1.0) and added it on to the diffuse lighting -- giving you grayish colors.

What you probably want in this situation is for the material ambient to come from the vertices, so set D3DRS_AMBIENTMATERIALSOURCE to D3DMCS_COLOR1.

I think you''ll find that the material diffuse color that you''re setting has no effect -- because again, by default it comes from the vertex, not the material settings.

And one other point: lighting is calculated only at the vertices and interpolated across the face of the triangle. You''re not going to see the interior of the triangle illuminated as I think you are expecting to. I would start with a sphere (D3DXCreateSphere). That will give you a better lighting than a single triangle can.
Well... no...

now it is all gray - the whole face - and nothing remembers lightning...

Where have my colors gone?

Taggi
Hey, Anonymous...

That is a great hint! Thanks!
I did not really understand your explanatation - my english is horrible -, but it works...

I am almost there... but I have still a little problem... The vertex, that is "backwards" looses always its color... and gains it back, when, another vertex rotates behind it. Then the first vertex gains its Color back and the second one looses it... does somebody know why?

And yes the light reaches all vertices

Taggi
Lighting is complicated. :-) One thing that might help you understand how things work is Rich Thomson''s lighting demo:

http://www.xmission.com/~legalize/book/snippets/index.html#13

another thought:

I have turned my triangle red in all corners... so I recognized, that, though it is rotating, one vertex (this one in front) is totaly red, and the other one (this one in the back) is black. Even though they are spinging araound, this red is not getting darker, when the triangle is rotating... suddenly both vertices are changing colors - that is when both are parallel to the surface -

I though that they are getting darker and brighter, when they are rotating... I though each frame the colors for the vertices are calculated and changing... why are they switching suddently, instead of having nuances of red?

Taggi

P.S.:
I hope you can understand my english .
Are you setting the light range like Jim suggested?
yes.
You must enable colored vertices, and say where the colors come from, ie: material or vertex diffuse or vertex specular.

// Enable vertex colors
m_d3dDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE);
// Diffuse comes from vertex diffuse
m_d3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
// Specular, ambient, and emissive come from material
m_d3dDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
m_d3dDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
m_d3dDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);

You must also ensure the light is attenuated properly. D3Ds lighting sucks. You want a light that fades from full to zero over it''s range, which cannot be done without a shader. The attenuation formula is based on three attenuation values.

Light.Attenuation0 = 1;
Light.Attenuation1 = 1/Light.Range;
Light.Attenuation2 = 1/Light.Range/Light.Range;

A0 - Constant attenuation
A1 - Linear attenuation (times distance)
A2 - Quadratic attenuation (time distance squared)
D - Distance from vertex to light

The light color value is then multiplied by this formula:
A = 1 / (A0 + D*A1 + D^2*A2)

So, at distance 0, you want the light to be full bright:
A = 1 / (1+0+0)
A = 1 / 1

And you want the light to fade with distance. At full range, using the values above, your light will be 1/3 as bright.
A = 1 / (1+1+1)
A = 1 / 3

Change Attenuation2 to 2/Light.Range/Light.Range and you''ll get an attenuation at full range of 1/4.
A = 1 / (1+1+2)
A = 1 / 4

This topic is closed to new replies.

Advertisement