Search code examples
c++math3ddirectxhlsl

Calculate Normal Vector


Is it possible to calculate my mesh normal vector when I have just TANGENT and BINORMAL vectors ?

      float4 Binormal : BINORMAL ;
      float4 Tangent  : TANGENT  ;
      float4 Position : POSITION ;

Solution

  • As far as I understand it, a binormal vector is defined from the normal and tangent vectors through a cross product :

    binormal = tangent x normal

    Thus normal = binormal x tangent, that is, what you wrote is correct.

    Since according to the doc, the cross product is defined for vectors of size 3, you can do the following :

    normal = float4(cross(binormal.xyz, tangent.xyz), 1.0);
    

    This is using the cross product from HLSL, which I recommend. But to get into more detail, you are not actually performing a real cross product.

    The real formula should be the following, where u is binormal, v is tangent and s is normal :

    formula of cross product

    Thus the code for a cross product should, instead, be :

    normal.x = binormal.y*tangent.z - binormal.z*tangent.y;
    normal.y = binormal.z*tangent.x - binormal.x*tangent.z;
    normal.z = binormal.x*tangent.y - binormal.y*tangent.x;
    

    And an alternate, swizzled version (that returns a vector of size 3, use float4(..., 1.0) if you want a 4 item vector) :

    normal = binormal.yzx*tangent.zxy - binormal.zxy*tangent.yzx;