Skip to main content
gamedev.net
🔒 Locked

Lights

Started by Tagamoga Jan 19, 2003 at 3:36 PM 14 replies 550+ views
Original Post
Tagamoga
Tagamoga
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
Jim Adams
Jim Adams
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.

Tagamoga
Tagamoga
Well... no...

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

Where have my colors gone?

Taggi
Tagamoga
Tagamoga
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
Tagamoga
Tagamoga
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 .
Tagamoga
Tagamoga
yes.
Namethatnobodyelsetook
Namethatnobodyelsetook
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
CrazedGenius
CrazedGenius
quote:
Original post by Namethatnobodyelsetook
D3Ds lighting sucks. You want a light that fades from full to zero over it''s range, which cannot be done without a shader.


This doesn''t suck - it''s more physically correct. A real light doesn''t have an actual range. There is some (small) amount of light at any distance. AP''s answer is the best - if you want, create values that make it very close to zero at the range.

I''m not sure, but I believe that D3D uses the range parameter for rough optimization. It is not part of the lighting equation.

Author, "Real Time Rendering Tricks and Techniques in DirectX", "Focus on Curves and Surfaces"
Donavon Keithley
Donavon Keithley
quote:
I''m not sure, but I believe that D3D uses the range parameter for rough optimization. It is not part of the lighting equation.


Both, really. If light distance > range, attenuation is 0. In these cases the lighting calculations can bypass ambient, diffuse, and specular and just do emissive. Actually global ambient is added in as well, but not light ambient.

(BTW, I''m the Anonymous Poster in this thread. I decided it''s time I finally registered. :-) )
CrazedGenius
CrazedGenius
Yes, to put it a different way; outside of the range there will be no contribution from that particular light. Other lights and ambient light can still contribute.

Author, "Real Time Rendering Tricks and Techniques in DirectX", "Focus on Curves and Surfaces"
Tagamoga
Tagamoga
Namethatnobodyelsetook now it is great! Now I have what I want, but I have to set
g_pDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,D3DMCS_COLOR1);

instead of

g_pDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

because otherwise my vertexcolors are gone.

Donavon Keithley I have run your Demoprogramm, but there are so many possibilities, that I still need help.
I am still "testing", playing or do experiments with DirectX, so it will take really much time, until I will generate spheres or anything that is more complex than a triangle.. *smile* I need time...

Well... until now, I have got everything worked fine, by myself, but lights are *&@!§$&*. I have to understand them and this can take a long time...

Tanks for all your help. I think some thinks are now clearer. For other I will ask again.. *smile*

Taggi
Donavon Keithley
Donavon Keithley
Taggi,

Like I said, lighting is complicated. :-) You just have to take it a step at a time.

You can create a sphere with something like this:

ID3DXMesh* pMesh;
...
pMesh = D3DXCreateSphere(pDevice, 1, 32, 16, &pMesh, NULL);

And to render it:

pMesh->DrawSubset(0);

It''s not very hard, and if you''re learning lighting I think it''s well worth it.

Good luck!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.