Zenja

12-22-2010, 06:51 AM

According to the OpenGL spec, gl_NormalMatrix is calculated as the transpose of the inverse of the current ModelView matrix. Eg:

gl_NormalMatrix = transpose(inverse(modelview))

Each normal is transformed by this matrix, which is essentially object transform independant from camera transform (ie. world transform). This is used to transform the vertex normal when doing lighting equations. If you have thousands of objects in the world, each with their own modelview transform, you have a lot of inverse matrices to calculate.

I have stumbled onto a faster method which only performs the inverse calculation once. I apologise in advance if this is common knowledge, but I've never seen it before, and my google kung-fu is failing me, so I'll post this here in case anybody else is interested.

The faster method to calculate the gl_NormalMatrix is to calculate camera(-1)*modelview. Since modelview = camera*world_transform, camera(-1)*camera cancel each other out, leaving our desired world transform. Trim this 4x4 matrix into a 3x3 matrix, and we have our gl_NormalMatrix. We only need to calculate camera(-1) once, and use it for all scene nodes, and since most engines already calculate this for other purposes, you can get the gl_NormalMatrix without a single additional matrix inverse calculation. When you have thousands of spatial scene nodes, the savings add up.

Just thought I'd share.

gl_NormalMatrix = transpose(inverse(modelview))

Each normal is transformed by this matrix, which is essentially object transform independant from camera transform (ie. world transform). This is used to transform the vertex normal when doing lighting equations. If you have thousands of objects in the world, each with their own modelview transform, you have a lot of inverse matrices to calculate.

I have stumbled onto a faster method which only performs the inverse calculation once. I apologise in advance if this is common knowledge, but I've never seen it before, and my google kung-fu is failing me, so I'll post this here in case anybody else is interested.

The faster method to calculate the gl_NormalMatrix is to calculate camera(-1)*modelview. Since modelview = camera*world_transform, camera(-1)*camera cancel each other out, leaving our desired world transform. Trim this 4x4 matrix into a 3x3 matrix, and we have our gl_NormalMatrix. We only need to calculate camera(-1) once, and use it for all scene nodes, and since most engines already calculate this for other purposes, you can get the gl_NormalMatrix without a single additional matrix inverse calculation. When you have thousands of spatial scene nodes, the savings add up.

Just thought I'd share.