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 9 of 9

Thread: Rasterization stage and matrix interpolation

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    4

    Rasterization stage and matrix interpolation

    Hi everyone,

    I am a little confused about the rasterization stage. For example, my vertex shader is something like this:

    Code glsl:
    #version 410 core
     
    in vec3 position;
    in vec3 normal;
    in vec3 tangent;
     
    out vec3 worldPosition;
    out vec3 worldNormal;
    out mat4 TBN;
     
    uniform mat4 modelMatrix;
    uniform mat4 mvp;
    ...
     
    main() {
     
        //...
     
    }

    And my fragment shader is something like this:

    Code glsl:
    #version 410 core
     
    in vec3 worldPosition;
    in vec3 worldNormal;
    in mat4 TBN;
     
    out vec4 fragColor;
     
    main() {
     
        // ...
     
    }

    For my understanding, the GPU will interpolate both the worldPosition&worldNormal transferred from vertex shader to fragment shader as per-fragment value. My question is: how about the matrix? Do I get a per-fragment value for the 4x4 matrix? If so, is it correct for my TBN matrix after interpolation?

    Thanks!
    Last edited by Dark Photon; 01-17-2018 at 04:58 AM.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,926
    Quote Originally Posted by skybig View Post
    For my understanding, the GPU will interpolate both the worldPosition&worldNormal transferred from vertex shader to fragment shader as per-fragment value. My question is: how about the matrix? Do I get a per-fragment value for the 4x4 matrix?
    Yes. Vertex shader outputs are interpolated unless they're integers or integer vectors (ivec/uvec) or have the "flat" qualifier.

    Quote Originally Posted by skybig View Post
    If so, is it correct for my TBN matrix after interpolation?
    It depends upon what you mean by "correct". E.g. the result of interpolating orthonormal matrices typically isn't orthonormal. OTOH, transforming a vector by the result of interpolating matrices is equivalent to transforming the vector by the original matrices then interpolating: (u*A+v*B).x = u*(A.x)+v*(B.x).

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    4
    Quote Originally Posted by GClements View Post
    Yes. Vertex shader outputs are interpolated unless they're integers or integer vectors (ivec/uvec) or have the "flat" qualifier.


    It depends upon what you mean by "correct". E.g. the result of interpolating orthonormal matrices typically isn't orthonormal. OTOH, transforming a vector by the result of interpolating matrices is equivalent to transforming the vector by the original matrices then interpolating: (u*A+v*B).x = u*(A.x)+v*(B.x).
    Thank you for the reply! So, the rasterizer does interpolate the 4x4 matrix (mat4).

    For the "correct" part, my situation is that I'm gonna do the normal mapping so I'd like to calculate the TBN matrix (tangent, bitangent, normal) to transfer the normal in tangent space (within the texture) to world space . I'm just thinking if I do the calculation in vertex shader, and after the rasterizer, I use them in the fragment shader, do I get the correct result? (get the correct world normal)

    Does it more often to calculate the TBN matrix in fragment shader?
    Last edited by skybig; 01-17-2018 at 01:10 AM. Reason: typo

  4. #4
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    459
    You will generally precompute the TBN axis and use them as vertex attributes. Then simply create the 3*3 matrix in the vertex shader using the at least 2 precomputed axis, and pass it to the fragment shader.

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,926
    Quote Originally Posted by skybig View Post
    Thank you for the reply! So, the rasterizer does interpolate the 4x4 matrix (mat4).

    For the "correct" part, my situation is that I'm gonna do the normal mapping so I'd like to calculate the TBN matrix (tangent, bitangent, normal) to transfer the normal in tangent space (within the texture) to world space . I'm just thinking if I do the calculation in vertex shader, and after the rasterizer, I use them in the fragment shader, do I get the correct result? (get the correct world normal)

    Does it more often to calculate the TBN matrix in fragment shader?
    It's typical to calculate the matrix in the vertex shader and interpolate. The matrix typically isn't renormalised (orthogonalised) in the fragment shader. Note that you only need a 3x3 matrix (normals are directions, not positions). But you should normalise the transformed normal, as the interpolated matrix won't preserve lengths.

  6. #6
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    4
    Quote Originally Posted by Silence View Post
    You will generally precompute the TBN axis and use them as vertex attributes. Then simply create the 3*3 matrix in the vertex shader using the at least 2 precomputed axis, and pass it to the fragment shader.
    Thank you!! Got it!

  7. #7
    Junior Member Newbie
    Join Date
    Jan 2018
    Posts
    4
    Quote Originally Posted by GClements View Post
    It's typical to calculate the matrix in the vertex shader and interpolate. The matrix typically isn't renormalised (orthogonalised) in the fragment shader. Note that you only need a 3x3 matrix (normals are directions, not positions). But you should normalise the transformed normal, as the interpolated matrix won't preserve lengths.
    Got it! And correct, I should use mat3! Thank you very much!

  8. #8
    Member Regular Contributor
    Join Date
    Jul 2012
    Posts
    459
    Quote Originally Posted by GClements View Post
    It's typical to calculate the matrix in the vertex shader and interpolate. The matrix typically isn't renormalised (orthogonalised) in the fragment shader. Note that you only need a 3x3 matrix (normals are directions, not positions). But you should normalise the transformed normal, as the interpolated matrix won't preserve lengths.
    Just to clarify what you wrote GClements, do you mean to calculate the tangent and binormal inside the vertex shader ? Or was you meaning (like I wrote in my post) to use the pre-computed axis stored as vertex attributes as the 3*3 matrix axis ?

  9. #9
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,926
    Quote Originally Posted by Silence View Post
    Just to clarify what you wrote GClements, do you mean to calculate the tangent and binormal inside the vertex shader ? Or was you meaning (like I wrote in my post) to use the pre-computed axis stored as vertex attributes as the 3*3 matrix axis ?
    If you have T,B,N as vertex attributes, then the vertex shader will simply copy them (either as a mat3 or as 3 separate vec3s). Sometimes B is calculated in the vertex shader as NT. Rarely, T might be computed from other information but this isn't usually possible in a vertex shader; computing T,B,N in a tessellation evaluation shader is fairly common.

    PS: B is the "bitangent". Surfaces have two tangents (tangent and bitangent) and one normal, curves have one tangent and two normals (normal and binormal). Unfortunately, someone once mistakenly used the curve terminology for a surface and the error has since propagated across countless tutorials.

Posting Permissions

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