GLSL: Bump mapping. Is tangent needed?

Started by
25 comments, last by BloodLust666 16 years, 1 month ago
Is the tangent attribute needed for every vertex? Is there a way around it with just using the normal map? If neither... How exactly is the tangent for a vertex calculated?
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Advertisement
Bumpmapping won't work without tangents (bitangents can be calculated with a cross product. The calculation is simple:

v[0...2] vertex position
t[0...2] texcoords
tan.xyz = (v1-v0).xyz * (t2-t0).y - (v2-v0).xyz * (t1-t0).y;

No, it's not inherently needed. It depends on how you do bumpmapping.

Objectspace bumpmapping doesn't need tangent or bitangent information at all. The normalmap encodes the normal in objectspace, so it can be used for lighting calculations directly (assuming you do lighting in objectspace, otherwise you'll need a coordsys adjustment, but still no tangents). The drawback is the large memory footprint of such maps. On modern hardware, and with powerful normalmap compression, this might not be such a problem anymore.

When using tangent space bumpmapping, you'll obviously need the tangent. Otherwise, you can't define the coordinate space the normalmap is encoded in, and you won't be able to correctly transform the normal. However, supplying the tangent per vertex is only one possibility. On modern hardware, you can directly evaluate the tangent in the fragment shader, by local finite differencing. This is probably going to be more expensive than simply supplying the precomputed tangent on current hardware, but this will quickly change in the future. It can already be very viable on skinned geometry, since you don't have to transform the tangents and/or bitangents anymore.

There are several different ways to compute the vertex tangents. Each approach has advantages and drawbacks, often dependent on the style of modelling you use in your geometry. Eric posted a pretty good method on his website.
I just randomly came across this site while looking up per-pixel lighting and found that this method does not use tangents, which I think is the way I want to go...

could someone show me the fragment shader program that would go with this? I'm not sure how it would look...

http://www.paulsprojects.net/opengl/bumpmap/bumpmap.html
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Quote:Original post by BloodLust666
I just randomly came across this site while looking up per-pixel lighting and found that this method does not use tangents, which I think is the way I want to go...

http://www.paulsprojects.net/opengl/bumpmap/bumpmap.html


It does use tangents as well (if you look at the code), the page mentions all the vectors in the equation being in tangent-space.
Quote:Original post by Yann L
memory footprint of such maps. On modern hardware, and with powerful normalmap compression, this might not be such a problem anymore.


I have been messing around with compressed normal maps using GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT (http://www.opengl.org/registry/specs/EXT/texture_compression_latc.txt). E.g. normal.xz can be stored in luminance and alpha, and the y-coordinate can be recovered in a shader). The quality is satisfactory for me and with compression, each normal only takes up 1 byte. I do the lighting in the same space, as Yann writes about. It's fast and I have no need for transformations. So if you have simple requirements you can get away with world-space or object-space normal mapping without computing TBN (tangent, bitangent, normal).
BloodLust666,

If you don't want to calculate tangent, why don't you just follow what Yann L said?

You should use a normal map and then perturb the content using you the texture of the 3D model. It can give you a nice bump mapping effect too.

Just the remind you, preparing a 3D model that can fit in normal map implementation is equally difficult as calculating vertex tangent. In my opinions, calculating vertex tangent is indeed easier as I don't need ensure the texel and the vertex is one-to-one, and therefore, save you alot of arguing time from the artist.

[Edited by - ma_hty on February 28, 2008 11:54:53 PM]
oh oops... i didn't notice it said tangent space, i mostly just look at

Color=(N'.L)*Decal + [(N'.H)^Power]*Gloss

N' is the normal from the normal map
L is the vector to the light
Decal is the texture color
H is the halfway vector
Power is the specular power
Gloss allows per-fragment coloring of the specular component

and saw there were no tangents in there. I haven't heard of tangent space actually. Not really sure what that is. But i'll definitely re-look at what Yann L suggested, thanks! I'll post back if i have any other questions
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML

// Calculate handedness
tangent[a].w = (Dot(Cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;

What exactly does that line mean? What's the handedness? If i'm guessing correctly, couldn't I just use a Vector3D and if the "handedness" is -1 then multiply my 3d vector by -1 to make it negative? is that essentially what handedness is?
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
the handedness basically tells if the tangent space coordinate frame is right or left handed for this vertex. Note, that this info is per vertex so you should pass it to the vertex shader and do the calculations as described on the page.

Both handedness values are possible for a model for instance when part of the model is mirrored and got mirrored uv coordinates assigned.

This topic is closed to new replies.

Advertisement