Contents
Messing with Tangent Space
 
 
Printer-Friendly VersionPrinter-Friendly Version
 
Latest News
spacer View All spacer
 
November 22, 2009
 
Video Game Watchdog National Institute On Media And The Family Shutting Down [11]
 
Modern Warfare 2 Infinity Ward's 'Most Successful PC Version' Yet [12]
 
New Tech, Design Details Of Project Natal To Emerge At Gamefest In February
spacer
Latest Jobs
spacer View All     Post a Job     RSS spacer
 
November 22, 2009
 
Sucker Punch Productions
Texture Artist
 
Sucker Punch Productions
3D Environment Artist
 
Sucker Punch Productions
Network Programmer
 
Sucker Punch Productions
Character Artist
 
Sony Online Entertainment
Brand Manager
 
Monolith Productions
Sr. Software Engineer, Engine - Monolith Productions - #113767
 
Crystal Dynamics
Sr. Level Designer
 
Gargantuan Studios
Technical Art Director
spacer
Latest Features
spacer View All spacer
 
November 22, 2009
 
arrow Upping The Craft: Susan O'Connor On Games Writing [6]
 
arrow Small Developers: Minimizing Risks in Large Productions - Part II [6]
 
arrow iPhone Piracy: The Inside Story [48]
 
arrow And Yet It Grows: Analyzing the Size and Growth of the European Game Market [5]
 
arrow NPD: Behind the Numbers, October 2009 [13]
 
arrow Reflecting On Uncharted 2: How They Did It [5]
 
arrow Sponsored Feature: Rasterization on Larrabee -- Adaptive Rasterization Helps Boost Efficiency
 
arrow Postmortem: Wadjet Eye's The Blackwell Convergence [2]
spacer
Latest Blogs
spacer View All     Post     RSS spacer
 
November 22, 2009
 
Time Fcuk
 
Accepting the Inherent Value of Games
 
Planckogenesis, Part II: Song Structure & Gravy Train [1]
spacer
About
spacer News Director:
Leigh Alexander
Features Director:
Christian Nutt
Editor At Large:
Chris Remo
Advertising:
John 'Malik' Watson
Recruitment/Education:
Gina Gross
 
Features
  Messing with Tangent Space
by Siddharth Hegde
5 comments
Share RSS
 
 
July 16, 2007 Article Start Previous Page 4 of 7 Next
 

4. Problems in practice

And it all comes crashing down…

So, that was all theory, but generally when you take something from theory and implement it in practice you end up with some problems. The same goes for the tangent space generation process.

Advertisement
Most problems arise from the way texture coordinates may be applied for an object during the texture unwrap stage. In most cases the artist would have done this to save on texture memory. The best solution is to him to fix the texture mapping at his end, rather than you write special cases for each object. In any case I have taken some commonly faces problems and explained how you can fix them. Most these solutions are less than perfect and should be avoided.

Upside down mapping

Take a look at Figure 4. It has two adjacent faces defined by the vertices 1,2,3 and 2,6,3 with inverted v channels. This will cause the lighting calculations in a per-pixel lighting shader to give wrong output.

Figure 4: Six faces of a plane. Two with the texture mapping straight and two with the mapping inverted on the v channel

This sort of a mapping would be an issue if all 3 vectors were generated only from the texture coordinates. If you plan to do this, the Normal vector will be inverted, since the Bi-Normal points in the opposite direction.

If you use the method explained above in this tutorial, this would be a non-issue and can be ignored completely.

Mirrored mapping

Figure 5: A sample face

Ok, so we escaped solving problem one without any real problems. But what if the T vector was inverted, as would be the case in mirrored mapping?

Generate the Bi-Normal vector from the v channel first.
As we leaned from upside down mapping, our normal will be inverted. One simple way of doing this is to just avoid the inverted vector. Generate the Tangent vector from the cross product of the Normal and the Bi-Normal.

Another method listed by the guys at NVidia is to duplicate the edge sharing the inverted texture coordinates. Although this will work to create a valid world to tangent space matrix across a face, I don’t see how it will help as far as the lighting calculations go.

This fixes above would work if you had only one texture coordinate unit inverted, but what if your code needs to handle both an upside down mapping and mirrored mapping on two adjacent faces at the same time?
In this case, the only solution is to invert each of the vectors manually. Although I would consider this a dirty fix it looks like this is the only solution.

Detecting inverted texture coordinates between two adjacent faces can be fairly simple.

Once the Tangent and Bi-Normal vectors have been generated…

  1. Check if the Tangent vectors face the same direction. This can be done quickly using a dot product and checking if the answer is positive.
  2. Then get the face normals for the two faces. Check if they face the same direction.
  3. If results from step 1 and 2 both result in positive or both negative answers, then your texture coordinates along the u channel is fine.
  4. Now do the same for the Bi-Normal vector to check if the v channels are inverted.

Cylindrical mapping

Figure 6: A sample cylinder and a close up of the edges that join behind

Another common problem that arises is with cylindrical mapping. In Figure 6 you can see a sample cylinder with cylindrical mapping applied on it. The second image is a close up of the same cylinder that shows the vertex edges where the two ends of the texture will meet. The u channel across the vertices on edge E1 will be 1.0 and the vertices on edge E2 will have a value of 0.0. This goes in the opposite direction of the rest the vertices on the cylinder. This would also cause the vectors of the tangent space matrix to be blended wrong across the faces between E1 and E2.

The solution here is to duplicate the vertices along edge E2 and attach them to the vertices on E1 to create new faces. They will have the exact same position as the old vertices. The old vertices on E2 will no longer be a part of the faces between E1 and E2. An important point to remember is that these vertices will be temporary. They will be used only to generate the world to tangent space matrix. They will not be used in the actual rendering, so the model and the texture on it will continue to look the same during rendering.

When generating the texture coordinates, you can assign fake texture coordinates to the temporary vertices. These fake coordinates should make sure that the Tangent vector will point in the same direction. In the above example, the temporary vertices along E2 could have a u value of 1.05 (Assuming the vertices on E1 have a u value of 1.0).
Another method would be use the same trick we used in mirrored mapping. We could generate the vectors from the v component and the face normals.

A third solution is to stretch the tangent space calculations between neighboring faces. In the above example, the faces between E1 and E2 would have their tangent space vectors calculated by stretching vectors from the left E1.

Spheres

Figure 7: A sample sphere, incompatible with the tangent space generation process

Some time back I had a task to apply per pixel lighting shader on some pool balls. If you look at the way a sphere is modeled in Figure 7, you will realize that the vertices get closer to each other at the top and bottom until they finally join one single vertex. This would make the tangent space matrix completely wrong at the tip vertices as the tangent space vectors on the neighboring faces will nullify each other.

Figure 8: A geo-sphere

In this case your artist has just modeled the sphere wrong. You should go back and ask him to create the sphere as a geo-sphere as it is known in 3D Studio Max. Take a look at Figure 8. In a geo sphere the vertices will be spread evenly across the sphere and you should not have any problem generating the tangent space matrix.

 
Article Start Previous Page 4 of 7 Next
 
Comments

Kiran Sudhakara
profile image
Step 2: Calculate the T vector
T = E2-1.xyz / E2-1.u

This formula does not seem correct. Wouldn't this just scale the edge?

David Larsson
profile image
Responce to Kiran's comment:

I think the formula is supposed to be more like this(could be wrong though):

NE2-1 = Normalize(E2-1)
NE3-1 = Normalize(E3-1)
T = (NE2-1.xyz / E2-1.u) + (NE3-1.xyz / E3-1.u)

Kiran Sudhakara
profile image
Unfortunately I believe this is wrong aswell. Consider a simple case where E2-1.uv is 1,0 (so E2-1.xyz is already the tangent!), and E3-1.uv is an angled vector across the UV space.

Shih-Kai Lai
profile image
http://www.terathon.com/code/tangent.html
http://www.blacksmith-studios.dk/projects/downloads/tangent_matrix_derivation.ph
p

These 2 website have good explanations about tangent space.

Does any body know, if 2 vertex of a triangle have the same UV, then should I ignore that triangle, or ask art to change the UV? The determinant will become 0 in this case...

Julian Hainsworth
profile image
No two vertices should have the exact same UV-Coords, if this is a problem with your meshes you should see your artist


none
 
Comment:
 


Submit Comment