iDevGames Forums
Smoothing tangents for bumpmapping - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Smoothing tangents for bumpmapping (/thread-3097.html)



Smoothing tangents for bumpmapping - TomorrowPlusX - Aug 13, 2007 10:49 AM

So, a while back I asked about calculating tangents ( http://idevgames.com/forum/showthread.php?t=14099 ) -- the good news is that after giving up and working on physics for a while, I spent the weekend on bumpmapping and by god, it works now. And looks great!

Now, that being said, there's one issue. For my procedural geometry, I submit tangent vectors as I generate the model ( easy enough, when creating cylinders, spheres, etc ). To test that my tangents are all correct, I have a flat normalmap ( 128, 128, 255 ) and render that. It *should* look more or less exactly like straight up per-pixel lighting.

And, as you can see below, for my cylinder geometry it does:
[Image: GoodManualTangents.png]

Now, this holds true for all my ( simple ) procedural geometry, but when I load a model from disk, I generate tangents from texture coordinates. The tangents are -- as far as I can tell by eyeballing correct, since the bumpmapping looks correct -- but when I use the flat normalmap, I can see that the tangents are on the triangle plane, and don't respect vertex normals. So I get something like flat shading, rather than smooth shading.

Here's a pick of what I'm seeing with an OBJ model I made in wings:
[Image: BadAutoTangents.png]

Here's the same model rendered with a vanilla per-pixel shader, to show how it should look:
[Image: WhatBadAutoTangentsShouldLookLike.png]

I've tried to swizzle the tangents after generation to track surface normals, but with no luck.

Code:
for ( int i = 0; i < 3; i++ )
{
    if ( dot( normals[i], normal ) < 1.0f - EPSILON )
    {
        vec3 axis = normalize( cross( tangents[i], normals[i] ));
        float angle = -degrees(acosf( dot( normals[i], normal )));
        tangents[i] = normalize( quat( axis, angle ).toMatrix() * tangents[i] );
    }
}

Basically, above I'm checking if the vertex normal differs from the face normal, and if it does, I'm rotating the tangent about their cross product by the number of degrees they differ.

In my mind, this should rotate the tangents from the triangle face to the vertex normal's orientation. But it doesn't result in any visible difference.

Admittedly, this is a minor issue. When I apply a colormap alongside the normalmap you can't really see the flat shading, but I know it's there, and that bothers me.


Smoothing tangents for bumpmapping - TomorrowPlusX - Aug 13, 2007 10:54 AM

BLEARG.

My "math" to fix the autotangents was backwards.
Code:
for ( int i = 0; i < 3; i++ )
{
    if ( dot( normals[i], normal ) < 1.0f - EPSILON )
    {
        vec3 axis = normalize( cross( normal, normals[i] ));
        float angle = degrees( acosf( dot( normals[i], normal )));
        tangents[i] = normalize( quat( axis, angle ).toMatrix() * tangents[i] );
    }
}

Sorry, folks.

....

Why is it that after posting here, I figure these things out?