Jump to content
  • Advertisement
Sign in to follow this  
Melley

Parsing tangent values correctly | c++/opengl

This topic is 558 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ive been trying to make a 3Dmodel parser, on one hand to understand the process better, and on the other hand to be able to make formats that I can call my own, but the result creates seams once I introduce normal mapping. Maybe somebody can explain what is happening, and/or what I should be doing different.

What I do is make an object in maya (in this a case a cube-sphere), export as obj and then try to parse it. My problem is: how do I handle shared vertices and edges for tangents? When it comes to vertex_normals this is fairly straight forward:

    vector <vec3>normalref(normalsize, vec3(0)); //normalsize, amount of vn, fill with 0

    //fill normalref with calculated normals
    vec3 normalbuffer;

    //i=vert1, i+1=uv1, i+2 vn1
    //i+3=vert2,i+4=uv2,i+5=vn2
    //i+6=vert3, i+7=uv3, i+8=vn3
    for (size_t i = 0; i < totalrefs.size(); i += 9) {
        normalbuffer = cross(
            vref[totalrefs[i + 3] - 1] - vref[totalrefs[i] - 1],
            vref[totalrefs[i + 6] - 1] - vref[totalrefs[i] - 1]);

        normalref[totalrefs[i + 2] - 1] += normalbuffer;
        normalref[totalrefs[i + 5] - 1] += normalbuffer;
        normalref[totalrefs[i + 8] - 1] += normalbuffer;
    }
    for (auto&x : normalref)x = normalize(x); //and normalize

For each face, add the cross (plane angle) to each vn connected, then after, normalize each of the vns, And you will have a vertex_normal that will work with a seamless phong shader.

 

But when It comes to tangent values, this is not as straight forward. The idea is that you convert the tangent on gpu, alongside with the normal for that vertice/corner, and make a bitangent, and tbn matrix, that you use for further calculations. But what I cant figure out is: How do you balance the tangent values for each side?

 

I keep getting edges that overlap and shadows that do not make any sense. Calculating the tangents themselves for each face is not very hard:

for (size_t i = 0; i < totalrefs.size(); i += 9)
    {
        edge1 = vref[totalrefs[i + 3] - 1] - vref[totalrefs[i] - 1];
        edge2 = vref[totalrefs[i + 6] - 1] - vref[totalrefs[i] - 1];
        deltaUV1 = uvref[totalrefs[i + 4] - 1] - uvref[totalrefs[i + 1] - 1];
        deltaUV2 = uvref[totalrefs[i + 7] - 1] - uvref[totalrefs[i + 1] - 1];
        f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);

        tangentbuf = normalize(f*vec3(
            (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x),
            (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y),
            (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z)));

        tangents[tangcount++] = tangentbuf;
        tangents[tangcount++] = tangentbuf;
        tangents[tangcount++] = tangentbuf;
    }

But this approach that works with vertex_normals, does not work for tangents. Even if i map them per vertex, per uv, or per vn. I get the same poor result showing seams. As far as I can gather, the problem is shared vertex/corner balancing, and I do not know how to do that correctly.

 

Somebody help!

 

this is what it currently looks like:

 

RlnQ0FB.png

 

Where the specular value is turned up, to make out the seam more clearly. This seam is not there when I use normals to do the shading, and, each face isnt square-ish either, but interpolated properly. Im pretty certain this is caused by the way I either calculate the tangents, or how I index them, can somebody explain to me how this should be done?

Edited by Melley

Share this post


Link to post
Share on other sites
Advertisement

Or maybe someone can just suggest a way to parse the tangents? Assuming you have a working way to get vertices, uvs and normals into the environment?

Share this post


Link to post
Share on other sites

Just to be sure that your problem is really related to the TBN coordinates. You don't have seams with applying texturing ?

Also, seams with TBN is something that can happen.

Share this post


Link to post
Share on other sites

Just to be sure that your problem is really related to the TBN coordinates. You don't have seams with applying texturing ?

Also, seams with TBN is something that can happen.

 

The texturing does not get seams, and when I make use of only the normal for non-normal-mapping (plain phong/ads shading) I do not get seams either.

Tangent calculation seems to get messed up when sharing edges/vertices and when wrapping around

Edited by Melley

Share this post


Link to post
Share on other sites

OK. Try to render your TBN unit vectors now and see if things look OK at the area where you have seams.

Oh they are normalized already

for (auto&x : tangentref)x = normalize(x); //clean up
Edited by Melley

Share this post


Link to post
Share on other sites

 

OK. Try to render your TBN unit vectors now and see if things look OK at the area where you have seams.

Oh they are normalized already

for (auto&x : tangentref)x = normalize(x); //clean up

 

I wanted to check if some of the TBN vectors could be reversed/swapped.

From your first image it looks like you have a little decay. This can come from the original topology or from something else.

Just display in the screen each of the TBN vectors with a distinct color and look at the region where you have these seams. I suspect this is the area where the texture goes from the right to the left again.

Also, check with another model (not spherical), and check if you have such seams at this area (junction of texture coordinates when they move from 1 to 0 again).

Share this post


Link to post
Share on other sites

Just display in the screen each of the TBN vectors with a distinct color and look at the region where you have these seams. I suspect this is the area where the texture goes from the right to the left again

 

What are possible fixes for that? Im using the wrong matrix or something? I've been trying to recalculate the tangents, but maybe I shouldnt?

Share this post


Link to post
Share on other sites

export as obj and then try to parse it

Don't use obj as your interchange format; use a format that supports tangents.
Don't compute your own normals/tangents from the vertex positions either -- use the exact values that were exported into your file.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!