|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| Calculate tangent from normal? |
|
![]() richardmonette Member since: 1/2/2009 |
||||
|
|
||||
| Is it possible to calculate a tangent from a normal? I am trying to do normal mapping in a software renderer I am making (for fun and learning). Normally (pun intended) in HLSL I would use the : NORMAL0 and : TANGENT0 semantics to get this information from the vertex stream and then generate a TBN (for going from tangent to world space) matrix doing something like: output.tangentToWorld[0] = mul(input.tangent, World); output.tangentToWorld[1] = mul(cross(input.tangent,input.normal), World); output.tangentToWorld[2] = mul(input.normal, World); Then I can easily use this to bring the tangent space normal from my texture map into world space doing something like: float3 normalFromMap = tex2D(NormalMapSampler, input.texCoord); normalFromMap = mul(normalFromMap, input.tangentToWorld); normalFromMap = normalize(normalFromMap); Ive got normals at each vertex in my software render stream but Im missing the tangents! How could I calculate these? [Edited by - richardmonette on November 6, 2009 9:05:12 AM] |
||||
|
||||
![]() Erik Rufelt Member since: 4/17/2002 From: Sweden |
||||
|
|
||||
| There are infinitely many vectors that you can use as tangents, as it can be any vector perpendicular to the normal. You can find one by calculating the cross-product of the normal and an arbitrary vector that isn't parallel to the normal. [Edited by - Erik Rufelt on November 4, 2009 4:03:12 PM] |
||||
|
||||
![]() richardmonette Member since: 1/2/2009 |
||||
|
|
||||
| Here's what I've come up with (based off this guide http://www.ozone3d.net/tutorials/mesh_deformer_p2.php): Vec3 tangent; Vec3 c1 = cross(normal, Vec3(0.0, 0.0, 1.0)); Vec3 c2 = cross(normal, Vec3(0.0, 1.0, 0.0)); if( len(c1) > len(c2) ) { tangent = c1; } else { tangent = c2; } normalizeSelfFAST(tangent); Vec3 bitangent = cross(tangent, normal); This seems to be working pretty well (produces the correct visual result). Is this a good solution or can you see any improvements? |
||||
|
||||
![]() Erik Rufelt Member since: 4/17/2002 From: Sweden |
||||
|
|
||||
| It's a good solution. |
||||
|
||||
![]() cignox1 Member since: 3/13/2003 From: Bolzano, Italy |
||||
|
|
||||
| Usually you build your tangents/bitangents such that they match the uv coordinates, but I don't know for sure what you need, so the suggested solution may be enough. |
||||
|
||||
![]() richardmonette Member since: 1/2/2009 |
||||
|
|
||||
| How do you "match" tangents / bitangents to UVs? |
||||
|
||||
![]() osmanb Member since: 1/28/2000 From: Latham, NY, United States |
||||
|
|
||||
| Yeah, picking arbitrary perpendicular tangents isn't going to work, at all. That's not the most important property of tangents/bi-tangents. The key thing is that the tangent is the vector that points in the direction of increasing 'U', and the bi-tangent points in the direction of increasing 'V'. Imaging looking at the polygon, head-on, in space. Then imagine rotating (about the normal) so that the texture co-ordinate gradients are increasing precisely along your X and Y axes. That co-ordinate system is the tangent-space for that polygon. This is important, because the normal maps are stored *in that space*. So you need to know how it's oriented to transform the normals back into world space (or whatever) to do lighting. |
||||
|
||||
![]() richardmonette Member since: 1/2/2009 |
||||
|
|
||||
| Thanks for the post. Definitely clears this up, at least on the conceptual level. So I've got my normals (transformed into world space). I know that once I've got a tangent (which should be increasing down the U axis) I can just cross product that with my normal to get my bi-tangent. But I'm still kind of stuck on how to implement something that will give me the correct tangent. Is there a good reference on how to handle that? |
||||
|
||||
![]() Erik Rufelt Member since: 4/17/2002 From: Sweden |
||||
|
|
||||
| What information do you have, and what information do you need? Do you have a triangle with texture coordinates for each vertex, and a normal to that, and want to calculate the tangent so that it matches the direction of the first texture coordinate? |
||||
|
||||
![]() richardmonette Member since: 1/2/2009 |
||||
|
|
||||
| "Do you have a triangle with texture coordinates for each vertex, and a normal to that, and want to calculate the tangent so that it matches the direction of the first texture coordinate?" Correct, Ive got a triangle, normal at each vertex, UV at each vertex. Id like to generate the tangent at that vertex. Here's what I am thinking might work: 1. Get the U direction using the adjacent vertices. 2. Calculate the plane which is described by the normal 3. Project the U direction onto this plane |
||||
|
||||
![]() cignox1 Member since: 3/13/2003 From: Bolzano, Italy |
||||
|
|
||||
| Give a look to this, hope it helps |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|