为了在GLSL着色器中使用法线贴图,您需要知道每个顶点的法线,切线和双切线向量。 RenderMonkey通过提供它自己的预定义变量(rm_tangent
和rm_binormal
)来实现这一点。我正在尝试将此功能添加到我自己的3D引擎中。显然,可以使用每个顶点的xyz坐标,uv纹理坐标和法向矢量来计算三角形中每个顶点的正切和双正切。经过一番搜索后,我设计了这个函数来计算我三角形结构中每个顶点的切线和双切线。计算3D切线空间
void CalculateTangentSpace(void) {
float x1 = m_vertices[1]->m_pos->Get(0) - m_vertices[0]->m_pos->Get(0);
float x2 = m_vertices[2]->m_pos->Get(0) - m_vertices[0]->m_pos->Get(0);
float y1 = m_vertices[1]->m_pos->Get(1) - m_vertices[0]->m_pos->Get(1);
float y2 = m_vertices[2]->m_pos->Get(1) - m_vertices[0]->m_pos->Get(1);
float z1 = m_vertices[1]->m_pos->Get(2) - m_vertices[0]->m_pos->Get(2);
float z2 = m_vertices[2]->m_pos->Get(2) - m_vertices[0]->m_pos->Get(2);
float u1 = m_vertices[1]->m_texCoords->Get(0) - m_vertices[0]->m_texCoords->Get(0);
float u2 = m_vertices[2]->m_texCoords->Get(0) - m_vertices[0]->m_texCoords->Get(0);
float v1 = m_vertices[1]->m_texCoords->Get(1) - m_vertices[0]->m_texCoords->Get(1);
float v2 = m_vertices[2]->m_texCoords->Get(1) - m_vertices[0]->m_texCoords->Get(1);
float r = 1.0f/(u1 * v2 - u2 * v1);
Vec3<float> udir((v2 * x1 - v1 * x2) * r, (v2 * y1 - v1 * y2) * r, (v2 * z1 - v1 * z2) * r);
Vec3<float> vdir((u1 * x2 - u2 * x1) * r, (u1 * y2 - u2 * y1) * r, (u1 * z2 - u2 * z1) * r);
Vec3<float> tangent[3];
Vec3<float> tempNormal;
tempNormal = *m_vertices[0]->m_normal;
tangent[0]=(udir-tempNormal*(Vec3Dot(tempNormal, udir)));
m_vertices[0]->m_tangent=&(tangent[0].Normalize());
m_vertices[0]->m_bitangent=Vec3Cross(m_vertices[0]->m_normal, m_vertices[0]->m_tangent);
tempNormal = *m_vertices[1]->m_normal;
tangent[1]=(udir-tempNormal*(Vec3Dot(tempNormal, udir)));
m_vertices[1]->m_tangent=&(tangent[1].Normalize());
m_vertices[1]->m_bitangent=Vec3Cross(m_vertices[1]->m_normal, m_vertices[1]->m_tangent);
tempNormal = *m_vertices[2]->m_normal;
tangent[2]=(udir-tempNormal*(Vec3Dot(tempNormal, udir)));
m_vertices[2]->m_tangent=&(tangent[2].Normalize());
m_vertices[2]->m_bitangent=Vec3Cross(m_vertices[2]->m_normal, m_vertices[2]->m_tangent);
}
当我使用这个功能,将计算得到的值,我的着色器,该机型看起来几乎就像他们在RenderMonkey中做,但他们在一个非常奇怪的方式闪烁。我将问题追溯到我发送OpenGL的切线和苦行。这让我怀疑我的代码做错了什么。任何人都可以看到任何问题或有任何其他方法尝试的建议吗?
我还应该指出,上面的代码非常黑客,我对背后的数学理解甚少。
对不起,但这只是错误的。你所做的只是将边缘v01缩放1/u1。 u1不仅可以为零,而且显然不正确。要获得正确的答案,请参阅http://stackoverflow.com/questions/5255806/how-to-calculate-tangent-and-binormal – Gottfried