Skip to main content
GameDev.net gamedev.net
🔒 Locked

Lighting in object space

Started by My_Mind_Is_Going Jun 3, 2010 at 11:48 AM 4 replies 4.1k views
Original Post
My_Mind_Is_Going
My_Mind_Is_Going
I've got some shaders for doing per-pixel lighting from point, spot and directional light sources. Currently I do all my lighting calculations in world space: light parameters are specified in world-space by the application, and the vertex shader passes along the interpolated world position and normal to the pixel shader. Everything seems to work fine with this approach.

I want to add support for normal maps next though, which I guess will require doing all the lighting in tangent space instead, and will require me to pass interpolated tangent-space light parameters to the pixel shaders. As a warm-up, before actually using normal maps, I thought I would adjust my existing code to do lighting in object space instead: interpolate local positions and normals instead of world space ones, as well as object space light parameters.

I thought this would be as simple as running the global (as in global shader params) light position and direction through the inverse world matrix in the vertex shader and using these in my lighting calculations instead of the global light params like I currently do. Additionally of course I'm passing along the object space position and normal now without transforming by the world matrix.

Perhaps needless to say, this isn't working. What lighting I can still see appears to be coming from the correct locations but the intensity is very low (which I suppose indicates a problem with the directions). I've made sure to normalize the interpolated light dir in the pixel shader so that can't be the cause.

I haven't ruled out simple typos in the code that could be tripping everything up, but before I spend a lot of time debugging I just wanted to share my story and make sure this is a sound approach I'm taking here (and that I'm going about it correctly).

I'm in a bit of a hurry, but I can post code later if anyone wants to take a look. Thanks for any advice anyone can offer.
MJP
MJP
One thing to be careful with is translation vs. rotation. Positions will need to be rotated and translated, which means if you have a float3 you need to convert it to a float4 with w = 1. Like this:
float3 lightPosOS = mul(float4(LightPosWS, 1.0f), InvWorld);


Any direction vectors need to be just rotated, and not translated. This means you can just leave them as a float3.

Also it's not true that you need to do lighting in tangent space for normal mapping. An alternative is to convert the normal map value from tangent space to world space (or view space) in the pixel shader, and then do your lighting calculations.
My_Mind_Is_Going
My_Mind_Is_Going
Quote:
Original post by MJP
One thing to be careful with is translation vs. rotation. Positions will need to be rotated and translated, which means if you have a float3 you need to convert it to a float4 with w = 1. Like this:
float3 lightPosOS = mul(float4(LightPosWS, 1.0f), InvWorld);


Any direction vectors need to be just rotated, and not translated. This means you can just leave them as a float3.

Also it's not true that you need to do lighting in tangent space for normal mapping. An alternative is to convert the normal map value from tangent space to world space (or view space) in the pixel shader, and then do your lighting calculations.


I'm translating the light positions like you mention so I don't think that's the problem. It doesn't sound like there's anything potentially problematic about the way I'm doing this then? My world matrices typically have a translation, rotation, and uniform scale. Is there anything I should be concerned about when it comes to inverting a matrix like this? I'm using XNA so the Matrix class has a built-in invert function. I've verified that for all the inverse I'm getting W * W^-1 = W^-1 * W = Identity.

I'm finding that directional lights are working fine, so the light direction must be getting transformed and interpolated correctly. Point lights appear to be in the correct location but are very faint which suggests something is wrong with the transformed distances right?

rouncED
rouncED
Id work in worldspace if I were you, just convert the model from object space to worldspace in the vertex shader, then its all worldspace after that and its simpler.

Theres such a thing as "object space normal mapping" but programmers often confuse it with "worldspace normal mapping" with this, the tangents are all set as the identity matrix until the model needs to animate, then you just put the identity tangents through the right orientations and it works the same as tangent space normal mapping.

Working with tangent space means you transform the light vector into the tangent space, it hasnt got to do with positions, just orientations, so your bug probably wouldnt even come up cause it sounds translational.

I think maybe your just a little confused, object space and world space are nearly the same thing if you discount model animation, the only difference is you animate the model into worldspace then all the lighting is the same as worldspace.

Thats what I do, takes a confusing sorta subject and makes it easier to think about... I suggest converting to worldspace first off.

The only difference from before and after converting from object space is a little animation.

For example, if in your code I see your transforming the light position into the object space Id say "no" that is the wrong way to do it... you transform the MODEL into worldspace, thats the right vice versa.
My_Mind_Is_Going
My_Mind_Is_Going
I've been doing everything in world space, and it works fine there. To do tangent-space normal mapping though this isn't going to work since I need to interpolate the light vector in tangent space down to the pixel shader. Since spot lights and point lights are position dependent, I need position information in the pixel shader. I assumed this could be done by interpolating a tangent-space light position.

As an intermediate step before doing full blown normal mapping I thought I would just get all my code working doing object-space lighting since it would have the same general form (just missing the extra transformation to go to tangent space in the vertex shader) and then it would be easy to toggle normal mapping on and off with a #define so I can use the same shader for both cases.

At this point though I'm wondering if I'm completely missing something, does the idea of a "tangent-space light position" even make sense?
MJP
MJP
Quote:
Original post by MJP
Also it's not true that you need to do lighting in tangent space for normal mapping. An alternative is to convert the normal map value from tangent space to world space (or view space) in the pixel shader, and then do your lighting calculations.


Topic Locked

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

Sign in to reply to this topic.