# Incorrect Normal Matrix

| | August 4, 2015

In my game engine I’m passing a normal matrix to my shaders like so:

``````Matrix3f normalMatrix = modelMatrix.invert().transpose();
``````

However this is causing lighting to rotate with my object, producing a weird effect.

As I’m not performing any non-uniform scaling, I tried substituting `normalMatrix` for `mat3(modelMatrix)`, and that worked fine.

Also doing the transpose inverse on the GPU using `transpose(inverse(modelMatrix))` worked fine.

This has lead me to believe there is a bug in my `invert()` and `transpose()` functions.

According to some math websites, when the `modelMatrix` lacks any non-uniform scaling, calling `inverse().transpose()` on it will produce the exact same matrix.

However in my code the output is far from the same:

``````modelMatrix

0.25    0      0      2353.3474
0       0.25   0      0
0       0      0.25   51.86973
0       0      0      1

normalMatrix = new Matrix3f(modelMatrix).invert().transpose()

4.0 0.0 0.0
0.0 4.0 0.0
0.0 0.0 4.0
``````

Would anyone be able to shed some light on this issue…
(I don’t want to just stick with `modelMatrix` because I do want to support non-uniform scaling in the future)

Here are some screenshots describing the issue:

These are two frames of my planet as it rotates. The light source appears to be rotating with it (it shouldn’t be). Using the `modelMatrix` instead of `normalMatrix` solves the issue.

## One Response to “Incorrect Normal Matrix”

1. According to some math websites, when the modelMatrix lacks any
non-uniform scaling, calling `inverse().transpose()` on it will produce
the exact same matrix.

This is slightly incorrect. Let’s define N as M.inverse().transpose(). Then N = M is true only if M is a rotation matrix. If M has uniform scaling, the resulting matrix N will be different. However when transforming vertices with matrix N, the resulting vectors will have the same direction as with M but different magnitude. If you normalize the vectors after the transformation, the results will indeed be the same. With non-uniform scaling this is no longer enough. As a summary:

• If all you have is rotation, you don’t need a separate normal matrix.
• If you have rotation and uniform scaling, you don’t need the normal matrix either, but you need to normalize the transformed normals.
• If you have non-uniform scaling / shearing, you need to calculate normal matrix with the transpose of the inverse.

The output from your normal matrix calculation looks correct.

Also doing the transpose inverse on the GPU using
`transpose(inverse(normalMatrix))` worked fine.

Is this a typo? You are using the normal matrix calculation for the normalMatrix, which results in the original matrix.

Based on the given information it’s hard to guess what is wrong. Note that normal matrix is 3×3 whereas your model matrix is 4×4. Try to reduce the model matrix to 3×3 as the first thing by discarding the w components. It’s also possible that you are passing the normal matrix incorrectly to the GPU. You might need to add more information / screenshots to the question.

• ### How To Submit a iPhone App to the Appstore

by on July 5, 2012 - 0 Comments

The process to develop an iPhone app is not as hard as one might think. The entry into the app store has been opened up to many new types of develope...

• ### Develop iphone Apps on Windows

by on March 7, 2011 - 13 Comments

Top 10 Ways to Develop an iphone/ipad app without a Mac #1. Code in Java For Java developers, there is a workaround: XMLVM. XMLVM cross-compiles byte...

• ### Iphone Android App Ideas: Getting Started

by on March 19, 2011 - 3 Comments

Smartphone Application Ideas: Getting Started Smartphone application developers are constantly on the move. And since overzealous developers stick ...