Results 1 to 5 of 5

Thread: Calculate Tangent and BiNormal for Normal Mapping

  1. #1

    Calculate Tangent and BiNormal for Normal Mapping

    Hi people. this is not competition related.

    I'm using Opengl to play with Normal mapping for the Alert figher project. I'm having problems calculating the Tanget and BinNormal vectors from the data have. Here is the code I came up with, can anyone see any problems (it's converted from C++, as always). Or even better has some code that works already .

    [pascal]

    function ROUNDOFF(d: Single): Single;
    begin
    //ROUNDOFF here is a macro that sets a value to 0.0f if the value is a very small
    // value, such as > -0.001f and <0> -0.001) and (Result < 0.001) then Result := 0.0;
    end;

    procedure FindInvTBN(v0,v1,v2: TVector;t0,t1,t2:TTextureCoordinate;
    var InvNormal: TVector; var InvBinormal: TVector; var InvTangent: TVector);

    var v2v1, v3v1: TVector;
    c2c1_T, c2c1_B: Single;
    c3c1_T, c3c1_B: Single;
    fDenominator, fScale1, fScale2: Single;
    T,B,N: TVector;

    begin
    //Calculate the vectors from the current vertex
    //to the two other vertices in the triangle
    v2v1 := VectorSub(v0,v2);
    v3v1 := VectorSub(v1,v0);
    //Calculate the “direction” of the triangle based on texture coordinates.
    c2c1_T := t0.u - t2.u;
    c2c1_B := t0.v - t2.v;
    c3c1_T := t1.u - t2.u;
    c3c1_B := t1.v - t2.v;
    //Look at the references for more explanation for this one.
    fDenominator := c2c1_T * c3c1_B - c3c1_T * c2c1_B;
    if ROUNDOFF(fDenominator) = 0.0 then
    begin
    //We won't risk a divide by zero, so set the tangent matrix to the
    //identity matrix
    InvTangent := NewVector(1.0, 0.0, 0.0);
    InvBinormal := NewVector(0.0, 1.0, 0.0);
    InvNormal := NewVector(0.0, 0.0, 1.0);
    end
    else
    begin
    fScale1 := 1.0 / fDenominator;
    T := NewVector((c3c1_B * v2v1.x - c2c1_B * v3v1.x) * fscale1,
    (c3c1_B * v2v1.y - c2c1_B * v3v1.y) * fScale1,
    (c3c1_B * v2v1.z - c2c1_B * v3v1.z) * fScale1);
    B := NewVector((-c3c1_T * v2v1.x + c2c1_T * v3v1.x) * fScale1,
    (c3c1_T * v2v1.y + c2c1_T * v3v1.y) * fScale1,
    (-c3c1_T * v2v1.z + c2c1_T * v3v1.z) * fScale1);
    N := CrossProduct(T, B);
    //This is where programmers should break up the function to smooth the tangent, binormal and
    // normal values. */

    //Look at “Derivation of the Tangent Space Matrix” for more information.
    fScale2 := 1.0 / ((T.x * B.y * N.z - T.z * B.y * N.x) +
    (B.x * N.y * T.z - B.z * N.y * T.x) +
    (N.x * T.y * B.z - N.z * T.y * B.x));

    InvTangent := NewVector(CrossProduct(B,N).x * fScale2,
    CrossProduct((VectorScale(N, -1)),T).x * fScale2,
    CrossProduct(T,B).x * fScale2 );
    InvTangent := VectorNormalize(InvTangent);

    InvBinormal := NewVector(CrossProduct(VectorScale(B, -1), N).y * fScale2,
    CrossProduct(N,T).y * fScale2,
    CrossProduct(VectorScale(T, -1), B).y * fScale2);
    InvBinormal := VectorNormalize(InvBinormal);

    InvNormal := NewVector(CrossProduct(B,N).z * fScale2,
    CrossProduct(VectorScale(N, -1), T).z * fScale2,
    CrossProduct(T,B).z * fScale2);
    InvNormal := VectorNormalize(InvNormal);
    end;

    end;
    [/pascal]
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

  2. #2

    Calculate Tangent and BiNormal for Normal Mapping

    I use the translated code from Terathon

    I could post the translated code but I use my own vector lib which is using operator overloading

    Edit: Ah wait.. for some reason the function has been erased from the lib... I can maybe find it later today

    Edit2: Actually I found it again without operator overloaded vectors:
    [pascal]function calculateTangentSpaceVector(position1, position2, position3: tvertex): normals;
    var side0, side1, normal, tangent, binormal, tangentCross: tvector4f;
    deltaV0, deltaV1, deltaU0, deltaU1: real;
    begin
    side0 := sub(position2.pos, position1.pos);
    side1 := sub(position3.pos, position1.pos);
    normal := normalize(cross(side0, side1));

    deltaV0 := position1.texcoord.y - position2.texcoord.y;
    deltaV1 := position3.texcoord.y - position1.texcoord.y;
    tangent := normalize(sub(multiply(side0, deltaV1), multiply(side1, deltaV0)));

    deltaU0 := position1.texcoord.x - position2.texcoord.x;
    deltaU1 := position3.texcoord.x - position1.texcoord.x;
    binormal := normalize(sub(multiply(side0, deltau1), multiply(side1, deltau0)));
    tangentCross := normalize(cross(tangent, binormal));
    if (dot(tangentCross,normal) < 0.0) then
    begin
    tangent := sub(tangent,tangent);
    binormal := sub(binormal,binormal);
    end;
    result.tangent := tangent;
    result.binormal := binormal;
    end;[/pascal]
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  3. #3

    Calculate Tangent and BiNormal for Normal Mapping

    Thanks JSoftware. You code looks allot simpler than the stuff I have.

    I got it all working anyway. Here are some sample screen shots.








    the models are not mine (I wish they were) but they are some rather cool low poly ones from a Star Trek Bridge Commander mod. I did generate the normal maps however and convert them to my own format.
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

  4. #4

    Calculate Tangent and BiNormal for Normal Mapping

    I looks nice but isn't the light a bit of? It looks to me like it's only "local" light, like if you're calculating light in tangent space instead of transforming it to world or light space?

    Edit: or maybe the light comes from the camera in all the shots?
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  5. #5

    Calculate Tangent and BiNormal for Normal Mapping

    The light is a directional one coming from the direction of the camera. I still need to experiment a bit more, but this is allot better than it was, I had a blank screen for a few days ops:
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

Bookmarks

Posting Permissions

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