Light transformation

Started by
3 comments, last by amtri 16 years, 10 months ago
I have a very simple question regarding the modelview transformation and lights. I haven't been able to figure this out with simple experiments. Suppose I draw primitives in the following order: 1) Set a DIRECTIONAL light 2) Apply a transformation with SetTransform (D3DTS_WORLD,...) 3) DrawPrimitive When I draw my primitives, will the light retain the modelview transformation from when it was first defined (step 1), or will the light direction be transformed by the modelview transformation in step 2? This leads me to my real question, which is how to rotate lights without rotating the rest of the model. My thought was 1) Apply a transformation 2) Set a DIRECTIONAL light 3) Reset the transformation to the value it had before 4) DrawPrimitive If somebody could "shed some light" into this, I would appreciate it. amtri
Advertisement
In the D3D fixed function pipeline, the matrices you set with SetTransform() have no effect on D3D light directions or light positions. They only effect vertex positions, vertex normals, and depending on other state, things like texture coordinates, but never lights.


So how do you transform the direction of your light?

Just manually transform the 'Direction' member in the D3DLIGHT9 structure that contains your light (using D3DXVec3TransformNormal() for example) then call SetLight() to tell D3D that the light direction has changed.

Light positions and directions are in world space. Remember that direction vectors shouldn't recieve any translation, just rotation (thus the suggestion of D3DXVec3TransformNormal() rather than D3DXVec3Transform()).


Of course this is all tons clearer if you use shaders since you get to choose/see what gets transformed and in what way (which also can have performance benefits).

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

S1CA,

You have no idea how helpful your comment was. Thanks a million!

By the way: where did you find this information? I searched everywhere in the documentation for a place that explained how lights are transformed, but couldn't find it. Just for future reference (so I can let you do some useful work of your own in the fugure :-)).

amtri
Quote:Original post by amtri
You have no idea how helpful your comment was. Thanks a million!


Glad to be of assistance [smile]


Quote:By the way: where did you find this information?


I'm not too sure to be honest, but I have been using Direct3D since the dark days of DirectX 3 and doing realtime 3D since around 1991, so where exactly I learnt stuff in the past gets a bit hazy these days [wink]

It may just be that I got so used to D3D's fixed function pipe not using an "everything gets transformed by what's on top of the stack" model (your use of the term ModelView makes me think OpenGL...).


To keep my original post clear I did omit one piece of information: the D3D FFP performs lighting in camera space. So the view matrix is used to transform the light direction, but it has no effect on the light direction relative to the model since the vertex normal is also transformed into [world then] camera space.


Quote:I searched everywhere in the documentation for a place that explained how lights are transformed, but couldn't find it.


Aha!, found it for ya: http://msdn2.microsoft.com/en-us/library/bb172390.aspx (there's a matching page in the offline SDK docs).


Of course, doing it with shaders lets you do it any way you feel like (such as efficiently emulating OpenGL's stack style FFP model if you're more familiar with that)


Quote:(so I can let you do some useful work of your own in the fugure :-)).


That's the stuff I do during in the day. Helping out here is just a hobby.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks for the documentation reference.

Now all I need to do is understand why some things are not looking right. I have a big program that I'm tasked with moving from OpenGL to Direct3D. OpenGL uses a right-handed system, with Z in the negative direction being into the screen. Direct3D uses positive values of Z and a left-handed system.

I'm sure somewhere I have a negative sign incorrect. My specularity is coming out in the back of my body, rather than in front of it :-)!

If you've seen somewhere how to transform your right-handed OpenGL system quickly into a left-handed Direct3D, please let me know.

Thanks again!

-amtri

This topic is closed to new replies.

Advertisement