GLSL Tangent Space

Started by
6 comments, last by Geometrian 15 years, 5 months ago
Hello, I've made some more progress on the normal mapping shader. It now works for x-axis rotations, but not y-axis ones. The code is from some links people gave me: http://www.ozone3d.net/tutorials/bump_mapping_p3.php getting the tangent space like: http://www.ozone3d.net/tutorials/mesh_deformer_p2.php#tangent_space. What follows is my vertex shader:
varying vec3 lightVec; 
varying vec3 eyeVec;
varying vec2 texCoord;
attribute vec3 vTangent; 
					 

void main(void)
{
    gl_Position = ftransform();
    texCoord = gl_MultiTexCoord0.xy;


    vec3 c1 = cross(gl_Normal, vec3(0.0, 0.0, 1.0)); 
    vec3 c2 = cross(gl_Normal, vec3(0.0, 1.0, 0.0)); 
    if(length(c1)>length(c2))
    {
        vTangent = c1;	
    }
    else
    {
        vTangent = c2;	
    }
    vTangent = normalize(vTangent);


    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
    vec3 t = normalize(gl_NormalMatrix * vTangent);
    vec3 b = cross(n, t);

    vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
    vec3 tmpVec = gl_LightSource[0].position.xyz - vVertex;

    lightVec.x = dot(tmpVec, t);
    lightVec.y = dot(tmpVec, b);
    lightVec.z = dot(tmpVec, n);

    tmpVec = -vVertex;
    eyeVec.x = dot(tmpVec, t);
    eyeVec.y = dot(tmpVec, b);
    eyeVec.z = dot(tmpVec, n);
}

Again, this only works when the object is rotated around the x (horizontal) axis. When rotated around the y-axis, it does not work, so the transformation did not take place correctly. Please help, -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
Nevermind, it seems to be working now.
[EDIT: no it's not]

[Edited by - Geometrian on October 26, 2008 5:07:38 PM]

[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"]

I'm thinking I should just scrap all of this normal mapping code I've gotten so far, because the critical part of the normal mapping--transforming the normals or light--doesn't work for me, but everything else I can do.

Most of the normal mapping procedures I've seen require knowledge of the geometry and computations on the CPU to find the TBN matrix. They also transform the light's position, instead of the normals' position, which is obviously faster.

I want to make a normal mapping shader that uses resources entirely in the GPU; not on the CPU. It will work with no knowledge of adjacent geometry. I know this can be done--googling "normal map teapot" gives multiple hits showing a normal mapped teapot--the teapot is an inbuilt primitive, so no knowledge of the geometry is known, yet these pictures show the normal mapping executed correctly.

Similarly, I'm working from prebuilt primitives, such as the GLUT teapot, so this sort of normal mapping is essential.

What I'm looking for is a shader (preferably GLSL) which will transform the normals into object space so that they can be used. This calculation will be done in the vertex shader for every vertex with no knowledge of the surrounding geometry. The texture coordinates are known, and the tangent and bitangent vectors should be parallel to the texture's u and v axes. All of this shouldn't be too complicated, but I'm totally at a loss how to do it.

[EDIT: if this cannot be done for whatever reason--how is the TBN matrix calculated if knowledge of the surrounding geometry is not available? It is done somehow]

Any help of any kind would be gladly appreciated.
-Geometrian

[Edited by - Geometrian on October 26, 2008 7:06:38 PM]

[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"]

Can this be done with geometry shaders? If so, where can I find an example of one that calculates the TBN matrix?

[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"]

Just for the record, most "teapot demos" use a loaded model, rather than the teapot data set to generate the surface/s. So make sure you know the background before jumping into conclusions about that sort of stuff :)

OK, so the only way to calculate the TBN matrix is through the CPU or a geometry shader?

[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"]

I guess it could be done with geometry shader as long as you can get adjacency information. I think you need to supply your data as GL_TRIANGLES_ADJACENCY.
Anyway, you are saying that your use GLUT teapot, which isn't up to date so it probably uses GL_TRIANGLES or something.
Why don't you use some file format that can store tangents that are precomputed?
It is better than considered any other bull shit.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
OK, so I have a tangent space calculator that runs when the program loads. How should it be passed to my shaders?

[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