PDA

View Full Version : Tangent calculation

capedica
05-01-2005, 11:58 PM
Hi,
sorry for problems that i have with shader, this is one of these: i'm using this code to calculate tangent from vertex,normal and texture coordinates :
Code from Terathon (http://www.terathon.com/code/tangent.html)
but the result is this (i'm using a classic normal map shader):
http://img221.echo.cx/img221/7885/prova7go.jpg

The code that i'm using is this:

{
mesh->m_tangent = new GLfloat[mesh->m_vertex_count*4];

for(int i=0;i<mesh->m_vertex_count;i++)
{
mesh->m_tangent[i*4]=0.0;
mesh->m_tangent[i*4+1]=0.0;
mesh->m_tangent[i*4+2]=0.0;
mesh->m_tangent[i*4+3]=0.0;
}

GLfloat *tan1 = new GLfloat[mesh->m_vertex_count*3 * 2];
GLfloat *tan2 = tan1 +mesh->m_vertex_count*3;

for(int i=0;i<mesh->m_vertex_count*3*2;i++)
{
tan1[i] = 0.0;
}

for (long a = 0; a < mesh->m_tri_count; a++)
{

long i1 = mesh->m_tri_index[a*3];
long i2 = mesh->m_tri_index[a*3+1];
long i3 = mesh->m_tri_index[a*3+2];

GLfloat* v1 = &amp;mesh->m_vertex[i1*3];
GLfloat* v2 = &amp;mesh->m_vertex[i2*3];
GLfloat* v3 = &amp;mesh->m_vertex[i3*3];

GLfloat* w1 = &amp;mesh->m_tex_coord[2*mesh->m_tri_texindex[a*3]];
GLfloat* w2 = &amp;mesh->m_tex_coord[2*mesh->m_tri_texindex[a*3+1]];
GLfloat* w3 = &amp;mesh->m_tex_coord[2*mesh->m_tri_texindex[a*3+2]];

float x1 = v2[0] - v1[0];
float x2 = v3[0] - v1[0];
float y1 = v2[1] - v1[1];
float y2 = v3[1] - v1[1];
float z1 = v2[2] - v1[2];
float z2 = v3[2] - v1[2];

float s1 = (w2[0] - w1[0]);
float s2 = (w3[0] - w1[0]);
float t1 = (w2[1] - w1[1]);
float t2 = (w3[1] - w1[1]);

float r = 1.0f / (s1 * t2 - s2 * t1);
if (fabs(r)>10e6)
r=0.0; //
float sdir[3] = {(t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
(t2 * z1 - t1 * z2) * r};
float tdir[3] = {(s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
(s1 * z2 - s2 * z1) * r};

tan1[i1*3] += sdir[0];
tan1[i1*3+1] += sdir[1];
tan1[i1*3+2] += sdir[2];

tan1[i2*3] += sdir[0];
tan1[i2*3+1] += sdir[1];
tan1[i2*3+2] += sdir[2];

tan1[i3*3] += sdir[0];
tan1[i3*3+1] += sdir[1];
tan1[i3*3+2] += sdir[2];

tan2[i1*3] += tdir[0];
tan2[i1*3+1] += tdir[1];
tan2[i1*3+2] += tdir[2];

tan2[i2*3] += tdir[0];
tan2[i2*3+1] += tdir[1];
tan2[i2*3+2] += tdir[2];

tan2[i3*3] += tdir[0];
tan2[i3*3+1] += tdir[1];
tan2[i3*3+2] += tdir[2];

}

long count = mesh->m_vertex_count;
GLfloat* n;
GLfloat* t;

for (long a = 0; a < count; a++)
{

n = &amp;mesh->m_vertex_normals[a*3];
t = &amp;tan1[a*3];
float calctemp;
float temp[3];

// Gram-Schmidt orthogonalize
// Calcolo (t-n*(n*t))
calctemp = (n[0]*t[0]+n[1]*t[1]+n[2]*t[2]);
mesh->m_tangent[a*4] = t[0] - calctemp*n[0];
mesh->m_tangent[a*4+1] = t[1] - calctemp*n[1];
mesh->m_tangent[a*4+2] = t[2] - calctemp*n[2];

float d = sqrtf(mesh->m_tangent[a*4]*mesh->m_tangent[a*4]+mesh->m_tangent[a*4+1]*mesh->m_tangent[a*4+1]+mesh->m_tangent[a*4+2]*mesh->m_tangent[a*4+2]);

if (d!=0.0)
{
mesh->m_tangent[a*4] /= d;
mesh->m_tangent[a*4+1] /= d;
mesh->m_tangent[a*4+2] /= d;
}

// Calculate handedness
// n%t
temp[0] = n[1]*t[2]-n[2]*t[1];
temp[1] = n[2]*t[0]-n[0]*t[2];
temp[2] = n[0]*t[1]-n[1]*t[0];

mesh->m_tangent[a*4+3] = (temp[0]*tan2[a*3]+temp[1]*tan2[a*3+1]+temp[2]*tan2[a*3+2] < 0.0f) ? 1.0f : -1.0f;

}

delete[] tan1;

mesh->m_bitangent = new GLfloat[mesh->m_vertex_count*3];

for(int i=0;i<mesh->m_vertex_count;i++)
{
mesh->m_bitangent[i*3]=0.0;
mesh->m_bitangent[i*3+1]=0.0;
mesh->m_bitangent[i*3+2]=0.0;
}

for(int i=0;i<mesh->m_vertex_count;i++)
{
mesh->m_bitangent[i*3] = (mesh->m_vertex_normals[i*3+1]*mesh->m_tangent[i*4+2] - mesh->m_vertex_normals[i*3+2]*mesh->m_tangent[i*4+1])*mesh->m_tangent[i*4+3];
mesh->m_bitangent[i*3+1] = (mesh->m_vertex_normals[i*3+2]*mesh->m_tangent[i*4] - mesh->m_vertex_normals[i*3]*mesh->m_tangent[i*4+2])*mesh->m_tangent[i*4+3];
mesh->m_bitangent[i*3+2] = (mesh->m_vertex_normals[i*3]*mesh->m_tangent[i*4+1] - mesh->m_vertex_normals[i*3+1]*mesh->m_tangent[i*4])*mesh->m_tangent[i*4+3];
}

}

Do you ever had a visual problem similiar to this? and which could be possible causes (all that came in your mine)?
is it possible a problem with smoothing groups?
Thank you very much