Bumpmapping Normal Rotation

Started by
6 comments, last by Geometrian 15 years, 6 months ago
Hello, My shaders are coming along nicely, and now I've come to bump mapping. I've gotten the bumpmap loaded and in the shader, so now I just need to get the normals to replace the surface normals. The bumpmap normals are in their own space (mostly z component because they are on a flat map), however, so they need to be rotated around a bit. My pathetic attempt to do this is as follows:
vec3 bumpnorm = normalize( texture2D(BumpMap,gl_MultiTexCoord0.xy).xyz * 2.0 - 1.0);
vec3 tangent = -vec3(abs(bumpnorm.y) + abs(bumpnorm.z), abs(bumpnorm.x), 0);
vec3 binormal = cross(tangent, bumpnorm);
mat3 TangentSpace_Matrix;
TangentSpace_Matrix[0] =  gl_NormalMatrix * tangent; 
TangentSpace_Matrix[1] =  gl_NormalMatrix * binormal; 
TangentSpace_Matrix[2] =  gl_NormalMatrix * gl_Normal;
vec3 bumpnormal = TangentSpace_Matrix * bumpnorm;
normal = normalize(gl_NormalMatrix * bumpnormal);
where bumpnormal replaces gl_Normal in the last line. This code doesn't rotate the normals properly, and I'm at a loss as to how it should be done. I'd like to keep the calculations in GLSL. Ideas? Thanks, -Geometrian

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Advertisement
Maybe I'm missing something. There're more than 1 way to do bump-mapping. So I just enumerate some issues that seem me strange.

How have you derived the tangent formula? If the bumpnorm vector is
n := [x y z]
then the tangent will be
t := [-|y|-|z| -|x| 0]
and the dot-product of the both
n . t = -x(|y|+|z|)-y|x|
what seems me not to guarantee orthogonality.

Furthur, you use the bumpnorm vector to compute the tangent and bi-normal (btw: it's a bi-tangent in fact) but compose the matrix by using the tangent, bi-normal, and gl_normal instead. How is guaranteed that this composition builds a ortho-normal basis?

Next, IMHO you transform the bumpnormal vector 2 times with the gl_NormalMatrix. The formula corresponding with your code is
n' := N * N * TBN * b
where n' denotes the resulting normal, N the normal matrix, and b the bumpnorm.


Can you post a reference where the applied bump-mapping technique can be looked up?
You cannot compute the tangent vector from the normal vector fetched from the bump map. You'll need to compute tangents from the vertex positions and texture coordinates using a method like that described here:

http://www.terathon.com/code/tangent.html

Then use the TBN matrix to transform the direction to light into tangent space in your vertex shader.
Quote:Original post by haegarr
Can you post a reference where the applied bump-mapping technique can be looked up?
I got the tangent and bitangent here:
http://www.gamedev.net/community/forums/topic.asp?topic_id=468836
and the rest of it here:
http://www.gamedev.net/community/forums/topic.asp?topic_id=373422.

I'll have a look at the link posted.

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Quote:Original post by Geometrian
I got the tangent and bitangent here:
http://www.gamedev.net/community/forums/topic.asp?topic_id=468836
...

and doesn't Ignifex came to the same conclusion as I did? You should ever check yourself whatever is suggested as a solution. More than ever if already somebody else has complained about it.

Quote:Original post by Geometrian
...
and the rest of it here:
http://www.gamedev.net/community/forums/topic.asp?topic_id=373422.

The TBN stuff seems me okay. The double multiplication by N isn't shown in that thread, is it?


In summary, I still see all three points made in my above post being a problem. Eric has already hinted at a page with explanations.
Hi,

I tried several times with the tangent space matrix, and t,b,n matrix, but I'm still having difficulty. I'm not very good with matrix or vector math, and I'm still in the dark about what exactly to do.
Here's my code:
vec3 texcoord = texture2D(BumpMap,gl_MultiTexCoord0.xy).xyz;vec3 T = vec3(1,0,texcoord.z);vec3 N = normalize(texcoord * 2.0 - 1.0);vec3 B = cross(N,T);mat3 TangentSpaceMatrix;TangentSpaceMatrix[0] = T;TangentSpaceMatrix[1] = B;TangentSpaceMatrix[2] = N;normal = N;lightDir = TangentSpaceMatrix * lightDir;
Yes, I know it's flawed; how should it look though?

Thanks,
-G

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

The first aspect you have to see is how to compute the TBN matrix:

You have a mesh, build of a couple of vertices, each one providing a position and a normal vector. That is not enough. You need to have a full co-ordinate frame at each vertex. That frame consists of a position (already available), a normal (already available), a tangent and a bi-tangent.

Does your DCC package export tangents as well? If so, you're in luck. Export them, so that each vertex provides a position, normal, and tangent. Then in the GPU the bi-tangent can be re-constructed by using the cross product.

If you can't get the tangent from an export, Eric has shown you a way to compute them. For that way you need to have (u,v) co-ordinates for each vertex. You want to apply a bump-map, so you have (u,v) co-ordinates at hand. Use Eric's suggestion to compute the tangent for each vertex.

Notice that you need to do so by considering several vertices at once. Hence you have to do it on the CPU. Presumbly it is doable in a geometry shader, too, but I haven't done so and hence be not sure. (A vertex shader has access to only 1 vertex in a run, and hence cannot perform the computations. Perhaps it become possible if you blow up the vertex structure with the needed data from the other vertices, too, but that would obviously generate a big memory overhead.)

Then, push vertices with their position, normal, tangent, and (u,v), of course, into the GPU. Reconstruct the bi-tangent on the GPU by utilizing the cross-product (see Eric's articel for details).
Hi,

The object I'm using is the GLUT teapot, so no tangents there.

I know this is supposed to be inefficient, but I want to try calculating the TBN matrix in the shader for each vertex (i.e., transform the normals, not the light). It must be possible, because even with knowledge of the adjacent geometry, people have readily normalmapped the GLUT teapot before.

In this case, I think the tangent and bitangent should be aligned with the u and v texture axes, which (I hope) eliminates the need for CPU calculations.

If I'm totally out of whack here, just let me know.

-G

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

This topic is closed to new replies.

Advertisement