Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Obtaining normal Matrix for 1.3+ shader

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    19

    Obtaining normal Matrix for 1.3+ shader

    Hello.

    I am porting code to work with GLSL >=1.3 shaders.
    The gl_NormalMatrix built-in uniform, among others, is deprecated and unsupported in GLSL 1.3 and above.
    However, OGL, to my understand, still calculates matrices when using the traditional functions such as glTransformf(), glPushMatrix(), etc.

    I have the following code to get these and inject them to my uniforms, but there is no GL definition for normal matrix. Why is this missing, or is it called differently?

    Code :
    	void setUniforms() {
     
    		GLfloat m[16];
     
    		glGetFloatv(GL_MODELVIEW_MATRIX, &m[0]);
    		glUniformMatrix4fv(modelViewMatrixLoc, 1, GL_FALSE, &m[0]);
     
    		glGetFloatv(GL_PROJECTION_MATRIX, &m[0]);
    		glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, &m[0]);
     
    		// Error: GL_NORMAL_MATRIX is not a thing. :-(
    		glGetFloatv(GL_NORMAL_MATRIX, 1, GL_FALSE, &m[0]);
    		glUniformMatrix4fv(normalMatrixLoc, 1, GL_FALSE, &m[0]);
    	}

    So yeah, must I really calculate this by myself now?

    Thanks in advance!

  2. #2
    Intern Newbie
    Join Date
    Mar 2013
    Posts
    42
    Hey,

    Yes, you have to "calculate" the normal matrix by your own. But this is really easy.
    The model matrix a 4x4 matrix. All you have to do now is just convert the Model matrix to a simple 3x3 matrix.
    This is because the normals do not need a translation or a scale factor. All they need is the models rotation.

    Model matrix e.g.:
    Code :
    1 0 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 1

    this will become:
    Code :
    1 0 0
    0 1 0
    0 0 1

    That's all, hope this will help you

    - Daniel

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    19
    I don't get why they pretty much force people to implement their own matrix stack now, rofl.

    Anyway, I can see truncating the translation column, but scale matrices can affect more than just the bottom row, as far as I know at least. Also scales will (can) affect normals, but in a different manner.

    I don't use scales, so thank God.

    Code :
    	void setUniforms() {
     
    		GLfloat m[16];
     
    		glGetFloatv(GL_PROJECTION_MATRIX, &m[0]);
    		glUniformMatrix4fv(projectionMatrixLoc, 1, GL_FALSE, &m[0]);
     
    		glGetFloatv(GL_MODELVIEW_MATRIX, &m[0]);
    		glUniformMatrix4fv(modelViewMatrixLoc, 1, GL_FALSE, &m[0]);
     
    		// Error: GL_NORMAL_MATRIX is not a thing. :-(
    		//glGetFloatv(GL_NORMAL_MATRIX, 1, GL_FALSE, &m[0]);
     
    		// HACKHACK: As long as we don't do scale transformations (which we don't) we will be fine doing just this.
    		m[12] = 0;
    		m[13] = 0;
    		m[14] = 0;
    		glUniformMatrix4fv(normalMatrixLoc, 1, GL_FALSE, &m[0]);
    	}

    I hope I will get away with doing just that. Only other geometric data I will have to transform manually are light positions, so I should be fine for now.

    In any case, thanks for letting me know.
    Last edited by Zylzyl; 01-11-2014 at 10:28 AM.

  4. #4
    Intern Newbie
    Join Date
    Dec 2013
    Posts
    45
    Quote Originally Posted by Alphaomega86 View Post

    Yes, you have to "calculate" the normal matrix by your own. But this is really easy.
    The model matrix a 4x4 matrix. All you have to do now is just convert the Model matrix to a simple 3x3 matrix.
    This is because the normals do not need a translation or a scale factor. All they need is the models rotation.
    l
    It is a little more than that, actually. First you can just reduce it to a 3x3 matrix as you said, but then you must take its inverse, then transpose it (or fitting called, the inverse transpose). Changing it to 3x3 only removes the translation factor. I can't explain the reasoning behind this better than this

    Quote Originally Posted by Zylzyl View Post
    I don't get why they pretty much force people to implement their own matrix stack now, rofl.
    The idea is to separate actual graphics related stuff (i.e. lights, transformations, fog, etc) from the API, so you are just dealing with the data. That way, how you format and use your data is totally up to you, and you write your code and shaders accordingly.

    On another note, check out the GLM library to replace the matrix math functions that have been deprecated, and check out the Unofficial OpenGL SDK, where you can find a matrix stack implementation if you must use one.

  5. #5
    Junior Member Newbie
    Join Date
    Jul 2011
    Location
    USA
    Posts
    23
    Quote Originally Posted by chbaker0 View Post
    It is a little more than that, actually. First you can just reduce it to a 3x3 matrix as you said, but then you must take its inverse, then transpose it (or fitting called, the inverse transpose). Changing it to 3x3 only removes the translation factor. I can't explain the reasoning behind this better than this
    There's no need to do an inverse transpose all the time. The website you linked to mentions they are using non-uniform scaling and rotations. He mentions this on the same page:

    Quote Originally Posted by Jason McKesson
    One more thing to note before we move on. Doing the inverse-transpose is only really necessary if you are using a non-uniform scale. In practice, it's actually somewhat rare to use this kind of scale factor. We do it in these tutorials, so that it is easier to build models from simple geometric components.


    A rotation is certainly orthogonal. By mathematical induction, the product of any finite number of orthogonal matrices is again orthogonal--so rotations are not really a problem. As the author says, a non-uniform scale will require the inverse-transpose so there's nothing we can do about those.

    A uniform scale, however, won't require the inverse-transpose. To see this, note that a uniform scale is not orthogonal. Consider this: is the transpose of a uniform scale equal to its inverse? No, unless it is the identity matrix. So it appears that we may need to compute the inverse-transpose for this case after all. Since the scale is uniform, however, the transform only affects the magnitude of the normal vectors but not the direction. So re-normalizing the normals will work in this special case and so we avoid computing the inverse-transpose.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •