Skip to main content
GameDev.net gamedev.net
🔒 Locked

Calculating Tangent and Bitangent

Started by LordSputnik Sep 4, 2010 at 6:51 PM 3 replies 6k views
Original Post
LordSputnik
LordSputnik
I need some feedback and advice! We have a deferred rendering system, which allows for animated objects, and are hoping to add tangent space normals to it.

The renderer currently sends the following per-pixel to the post renderer:

Diffuse Color
World Space Normals
Specular Intensity and Exponent
World Space Position

The way I see it, there are two methods of doing this:

1. Calculate tangent and bi-tangent per frame of each mesh's animation, using the new object space position of the vertices and their UV co-ordinates. This seems very much the traditional method of doing things. The normal can be calculated as the cross product of the tangent and bi-tangent.

2. Render the UV co-ordinates of each vertex to a render target. Then use the world space co-ordinate texture to calculate the tangent per fragment in each frame (in screen space). Use a cross product of the global normal texture and the tangent to calculate the bi-tangent.

From either method, use the tangent and bitangent to apply the tangent space normal map.

I'm thinking that the second method, although requiring the generation of a UV texture, would still be faster as the calculations are done on the GPU, as opposed to the CPU for the first method. But is it worth the extra texture for the speed boost I'd gain?

Thoughts appreciated!

Sput
LordSputnik
LordSputnik
Anyone have any ideas? :S *bump*
Frongo
Frongo
I'm not sure calculating the tangent and bitangent per frame is really necessary. If you have your tangent and bitangent calculated on your model in its default pose, you should be able to multiply the default pose tangent and bitangent by your bone matrices the same way it is done with normals. I'm not sure what kind of artifacts this would produce, perhaps there is some more research to be done there.

After you have your tangent and bitangent multiplied with your bone matrices, you could sample your tangent space normal map and convert it into a world space normal, then pass it to your post renderer. This approach would fit in nicely with your values you're already sending to your post renderer, and would avoid calculating your tangent and bitangent per frame.
Prune
Prune
You can also calculate it in the shader (along with normals) by crossing screen-space derivatives, but the problem is accumulating and then normalizing per vertex so you don't get flat shading. So you need geometry shader and transform feedback if you go this route and want per-vertex instead of per-face.
"But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?" --Mark Twain

~~~~~~~~~~~~~~~Looking for a high-performance, easy to use, and lightweight math library? http://www.cmldev.net/ (note: I'm not associated with that project; just a user)
kvark
kvark
That's an interesting question.
If your models are flat-shaded (what is most probably not the case), your way lies within geometry shader & transform feedback, as was mentioned earlier.

If you have smooth vertices, what implies you have a normal set up for each vertex (and you animate it together with a position), then why not keep the complete tangential space basis per vertex for the animation (instead of reconstructing it from the normal)? While you can add the tangent to your vertex attributes, I find it easier to have a single quaternion representing the tangential space.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.