[SOLVED] Scale in World matrix messing with GBuffer rendering

Hi :slight_smile: ! I’m currently struggling with a strange problem in my deferred renderer.

To set a little bit of context : I am rendering each of my 3D models in some GBuffer render-targets. For that, each model has its World matrix created by multiply the model rotation and position.

Everything was working fine, so I decided to add the scale (which is a float value) of the model, to be able to control it at runtime :

Matrix world = Matrix.CreateScale(myModel.Scale) * Matrix.CreateFromQuaternion(myModel.RotationQuaternion) * Matrix.CreateTranslation(myModel.Position)

My problem appears there. These 3 little fox fellows have 3 differents scales (4, 1 and 0.25).
The middle one (scale=1) is correctly lit but the others are not : the big fellow is too dark, the little one too bright. Everything is the same (same lighting, same model …), only the scale value is different.

By looking into my different render-targets, it seems that the scale is somehow messing with the normal values :

The normal render-target is not supposed to have bright and dark colors like this.
I suspect this line to cause the problem in the pixel shader :

output.Normal = mul(input.Normal, WorldViewIT);

Now I’ve seen this line in many examples of GBuffer shaders but I don’t fully understand what it does, tbh (I’m quite new to shaders).

The WorldViewInvertTranspose variable is calculated like this :

_gBufferEffect.Parameters["WorldViewIT"].SetValue(Matrix.Transpose(Matrix.Invert(myModel.WorldMatrix * viewMatrix)));

We can also note that if I remove the scale component in the world matrix before calculting the WorldViewIT matrix (by multiply by its inverse like below), everything works just fine. But it seems a ugly way to solve my problem, isn’t it ?

_gBufferEffect.Parameters[“WorldViewIT”].SetValue(Matrix.Transpose(Matrix.Invert(Matrix.Invert(myModel.Scale) * myModel.WorldMatrix * viewMatrix)));`

Is that a common behaviour of GBuffer shaders ? Has anyone trying to add a scale component in its World matrix ?

You only need to use the inverse transpose matrix for the normals, if you use non-uniform scale. Have a look here:

https://paroj.github.io/gltut/Illumination/Tut09%20Normal%20Transformation.html

2 Likes

You’re right ! I don’t actually need the WorldViewIT variable.
I managed to solve my problem by replace the pixel shader line by this one :

output.Normal = normalize(mul(input.Normal, mul(World,View)));

Everything works just fine now ! Thanks =)

1 Like