I’ m implementing tangent space calculation, embedded in an .Obj format mesh reader with that header
I essentially followed the math exposed in book “maths for 3d game programming and computer graphics†– eric lengyel
Vec3, Vec2 are self explanatory classes
//here are the core functions
//compute tangent basis per face
[font="]I tryed different type of smoothing and orthonormalization like:[/font]
[font="]All that code generate tangent space like in figure[/font]
[font="]Here are shaders for diffuse bump map lighting [/font]
[font="]I tryied transforming lighting vectors in object space , eye space, but I get the same results.[/font]
here is executable
http://demasprojects.altervista.org/files/Lighting.rar
it is driving me insane!!! please help me to solve this problem!!!
Code:
class ObjModel
{
public:
ObjModel();
~ObjModel();
bool loadModelData(char *fileName);
GLint createModelList();
void boundingBox();
void scaleDown();
void printData();
GLint showTangentBasis();
bool computeTBN();
private:
void decodeLine(char *fileLine);
void readVertexInfo(char *fileLine);
void readFaceInfo(char *fileLine);
void triangleTangentSpace(Vec3& tangent, Vec3& binormal, Vec3& normal,
Vec3 v[3], Vec2 t[3]);
ifstream m_file;
unsigned int m_numVertices;
unsigned int m_numFaces;
unsigned int m_numTextures;
unsigned int m_numNormals;
vector<Vec3> m_vertexCoords;
vector<Vec2> m_textureCoords;
vector<Vec3> m_normalCoords;
Vec3 m_minVertexCoord;
Vec3 m_maxVertexCoord;
bool m_hasNormals;
bool m_hasTextures;
vector<Vec3> m_tangentCoords;
vector<Vec3> m_binormalCoords;
bool m_hasTangentSpace;
struct Face
{
vector<unsigned int> vertices;
vector<unsigned int> texcoords;
vector<unsigned int> normals;
};
vector<Face> m_faces;
};
Vec3, Vec2 are self explanatory classes
//here are the core functions
//compute tangent basis per face
Code:
void
ObjModel::triangleTangentSpace(Vec3 &tangent, Vec3 &binormal, Vec3 &normal, Vec3 v[3], Vec2 t[3])
{
Vec3 Q1 = v[1] - v[0];
Vec3 Q2 = v[2] - v[0];
Vec2 s1t1 = t[1] - t[0];
Vec2 s2t2 = t[2] - t[0];
//matrices in column major order
float mat2x2[4] = {s1t1.getX(), s2t2.getX(), s1t1.getY(), s2t2.getY()};
float *imat2x2 = new float[4];
imat2x2 = invert2x2(imat2x2, mat2x2);
tangent.setX(imat2x2[0] * Q1.getX() + imat2x2[2] * Q2.getX());
tangent.setY(imat2x2[0] * Q1.getY() + imat2x2[2] * Q2.getY());
tangent.setZ(imat2x2[0] * Q1.getZ() + imat2x2[2] * Q2.getZ());
binormal.setX(imat2x2[1] * Q1.getX() + imat2x2[3] * Q2.getX());
binormal.setY(imat2x2[1] * Q1.getY() + imat2x2[3] * Q2.getY());
binormal.setZ(imat2x2[1] * Q1.getZ() + imat2x2[3] * Q2.getZ());
normal = Q1.cross(Q2);
}
//tangent basis per vertex smoothing
bool
ObjModel::computeTBN()
{
if (!m_hasTextures )return false;
unsigned int nn = m_vertexCoords.size();
m_tangentCoords.resize(nn);
m_binormalCoords.resize(nn);
m_normalCoords.assign(m_vertexCoords.size(), Vec3());
int nf = m_faces.size();
vector<Vec3> faceTangents = vector<Vec3>(nf);
vector<Vec3> faceBinormals = vector<Vec3>(nf);
vector<Vec3> faceNormals = vector<Vec3>(nf);
for (int i = 0; i < m_faces.size(); i++) {
//gathering data for per face tangent
Vec3 v[3];
Vec2 t[3];
v[0] = m_vertexCoords[m_faces[i].vertices[0]];
v[1] = m_vertexCoords[m_faces[i].vertices[1]];
v[2] = m_vertexCoords[m_faces[i].vertices[2]];
t[0] = m_textureCoords[m_faces[i].texcoords[0]];
t[1] = m_textureCoords[m_faces[i].texcoords[1]];
t[2] = m_textureCoords[m_faces[i].texcoords[2]];
triangleTangentSpace(faceTangents[i], faceBinormals[i], faceNormals[i], v, t);
}
for (unsigned int i = 0; i < nn; i++) {
for (int j = 0; j < m_faces.size(); j++) {
if (m_faces[j].vertices[0] == i || m_faces[j].vertices[1] == i || m_faces[j].vertices[2] == i) {
m_tangentCoords[i] += faceTangents[j];
m_binormalCoords[i] += faceBinormals[j];
m_normalCoords[i] += faceNormals[j];
}
}
m_tangentCoords[i].normalize();
m_binormalCoords[i].normalize();
m_normalCoords[i].normalize();
}
//mio
for (unsigned int i = 0; i < nn; i++) {
Vec3 n = m_normalCoords[i];
Vec3 t = m_tangentCoords[i];
Vec3 b = m_binormalCoords[i];
m_tangentCoords[i] = (t - n * n.dot(t));
m_binormalCoords[i] = (b - n * n.dot(b) - m_tangentCoords[i] * m_tangentCoords[i].dot(b));
m_tangentCoords[i].normalize();
m_binormalCoords[i].normalize();
m_normalCoords[i].normalize();
}
m_hasTangentSpace = true;
return true;
}
[font="]I tryed different type of smoothing and orthonormalization like:[/font]
Code:
//alternative smoothing
for (int i = 0; i < m_faces.size(); i++) {
for (int j = 0; j < m_faces[i].vertices.size(); j++) {
m_tangentCoords[m_faces[i].normals[j]] += faceTangents[i];
m_binormalCoords[m_faces[i].normals[j]] += faceBinormals[i];
m_normalCoords[m_faces[i].normals[j]] += faceNormals[i];
}
}
//alternative orthonormalization
for (int i = 0; i < nn; i++) {
m_normalCoords[i].normalize();
m_binormalCoords[i] -= m_normalCoords[i] * (m_normalCoords[i].dot(m_binormalCoords[i]));
m_binormalCoords[i].normalize();
m_tangentCoords[i] -= m_normalCoords[i] * (m_normalCoords[i].dot(m_tangentCoords[i]));
m_tangentCoords[i].normalize();
}
[font="]All that code generate tangent space like in figure[/font]
[font="]Here are shaders for diffuse bump map lighting [/font]
[font="]I tryied transforming lighting vectors in object space , eye space, but I get the same results.[/font]
Code:
vec4 lightPos = vec4(3.0, 0.0, 5.0, 1.0);
varying vec3 g_lightVec;
void main()
{
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
mat3 TBN_Matrix = gl_NormalMatrix * mat3(gl_MultiTexCoord3.xyz, gl_MultiTexCoord4.xyz, gl_Normal);
vec4 mv_Vertex = gl_ModelViewMatrix * gl_Vertex;
vec4 light = gl_ModelViewMatrix * lightPos;
vec3 lightVec = light.xyz - mv_Vertex.xyz;
g_lightVec = lightVec * TBN_Matrix;
}
/*fragment shader*/
uniform sampler2D Normal;
uniform sampler2D base_tex;
varying vec3 g_lightVec;
void main()
{
vec3 lightVec = normalize(g_lightVec);
vec4 color_base = texture2D(base_tex ,gl_TexCoord[0].st);
vec3 bump = texture2D(Normal, gl_TexCoord[0].st).rgb * 2.0 - 1.0;
bump = normalize(bump);
float diffuse = clamp(dot(lightVec, bump), 0.0, 1.0);
gl_FragColor = /*color_base */ diffuse;
gl_FragColor.a = 1.0;
}
here is executable
http://demasprojects.altervista.org/files/Lighting.rar
it is driving me insane!!! please help me to solve this problem!!!