Normals & WorldMatrixInverseTranspose

Hey all,



I’m working on 3089 using the nightly SVN, and I’m not sure if I am doing something wrong or if WorldMatrixInverseTranspose isn’t working as I expect… I’m working with my custom lighting system & I want lights to illuminate normals pointed toward the light, regardless of the model’s rotation. If I don’t rotate the model, the correct faces / normals are lit. However, when my objects rotate, the same faces light up as if the object wasn’t rotated at all. I thought WorldMatrixInverseTranspose in the vertex shader was suppose to convert the model’s normals to the “world” normals, which would account for the model’s rotation…?



This is how I calculate the normal in the vert shader:



[java] vNormal = normalize(inNormal * g_WorldMatrixInverseTranspose); [/java]



If I try to do it like this:



[java] vNormal = inNormal; [/java]



… nothing visually changes. I have this in my WorldParamters:



[java] WorldParameters {

WorldMatrix

WorldViewProjectionMatrix

WorldMatrixInverseTranspose

}[/java]



Any suggestions? :confused:

It should work,

The code setting this matrix had been commented and was reintroduced in this commit http://code.google.com/p/jmonkeyengine/source/detail?r=9603

So if you use nightly…it should be ok.



Only thing I can see is that something is wrong after that in your code.

Are you sure you want normals in worldspace? usually for light calculation you use normals in viewspace.

If you want them in viewspace you can use the NormalMatrix global uniform.

Thank you for the reply.



I’m not sure how to work with NormalMatrix, because those normal values change when my view changes (e.g. looking around). The light location & object are not changing, so what faces on that object are lit shouldn’t change just because I’m looking at it from a different angle… ???



What I’ve been doing is getting vNormal = normalize(inNormal * g_WorldMatrixInverseTranspose);, and then later determining how bright the lighting should be via:



[java]lightVector = m_Light1Pos.xyz - inpos;

brightness = max(0.0, dot(lightVector, vNormal));[/java]



…but as I was saying, when the object rotates, the faces that are lit rotate with it (instead of the faces pointing toward the light being lit). I’m assuming the normal values will rotate with the object rotating, but that doesn’t seem to be the case…? ???

My shader knowledge is quite poor, but if WorldMatrixInverseTranspose gets you from local to global, and inNormal is local, then shouldn’t it be this way round:



[java]g_WorldMatrixInverseTranspose * inNormal[/java]

4 Likes
@wezrule said:
My shader knowledge is quite poor, but if WorldMatrixInverseTranspose gets you from local to global, and inNormal is local, then shouldn't it be this way round:

[java]g_WorldMatrixInverseTranspose * inNormal[/java]

oh nice catch! you're right about that!
@wezrule said:
My shader knowledge is quite poor, but if WorldMatrixInverseTranspose gets you from local to global, and inNormal is local, then shouldn't it be this way round:

[java]g_WorldMatrixInverseTranspose * inNormal[/java]


http://who-is-awesome.com/who-is-awesome.jpg

This totally works! Unfortunately, even though I hit the "thumbs up" button 23 times, it only gave you +1 :/