我有以下代码来计算切线,bitangents。我可以使用法线贴图成功渲染一些网格示例。
我对特定网格有问题,它会使用法线计算切线角色。
任何帮助都将被认可,以确定原因。
这个例子是这样的:
v0:( - 9.860292,6.589309,-8.947665) v1:( - 9.860292,0.000000,-8.947665), v2(-8.068345,0.000000,-8.947665)
uv0:( - 0.073677,-0.141450) uv1:( - 0.074518,-0.140732), uv2(-0.074243,-0.140732)
deltaPos1:(0.000000,-6.589309,0.000000) deltaPos2:(1.791947,-6.589309,0.000000)
deltaUV1:( - 0.000841,0.000718) deltaUV2:( - 0.000566,0.000718)
正常:(1.000000,0.000000,0.000000) Tanget:(6516.150391,-0.000000,-0.000000), bitangent(7632.445312,-9177.340820,-0.000000)
void MeshRenderer::computeTangentBasis(
// inputs
std::vector<unsigned int>& indices,
std::vector<glm::vec3> & vertices,
std::vector<glm::vec2> & uvs,
std::vector<glm::vec3> & normals,
// outputs
std::vector<glm::vec3> & tangents,
std::vector<glm::vec3> & bitangents
){
tangents.clear();
bitangents.clear();
GLMHelper glmHelper;
for (unsigned int i=0; i<indices.size(); i+=3 ){
// Shortcuts for vertices
int index0 = indices[i];
int index1 = indices[i+1];
int index2 = indices[i+2];
glm::vec3 & v0 = vertices[index0];
glm::vec3 & v1 = vertices[index1];
glm::vec3 & v2 = vertices[index2];
std::cout << " v0: " << glmHelper.convertVec3(v0) << " v1: " << glmHelper.convertVec3(v1) <<
", v2 " << glmHelper.convertVec3(v2) << std::endl;
// Shortcuts for UVs
glm::vec2 & uv0 = uvs[index0];
glm::vec2 & uv1 = uvs[index1];
glm::vec2 & uv2 = uvs[index2];
std::cout << " uv0: " << glmHelper.convertVec2(uv0) << " uv1: " << glmHelper.convertVec2(uv1) <<
", uv2 " << glmHelper.convertVec2(uv2) << std::endl;
// Edges of the triangle : postion delta
glm::vec3 deltaPos1 = v1-v0;
glm::vec3 deltaPos2 = v2-v0;
std::cout << " deltaPos1: " << glmHelper.convertVec3(deltaPos1) << " deltaPos2: " << glmHelper.convertVec3(deltaPos2) << std::endl;
// UV delta
glm::vec2 deltaUV1 = uv1-uv0;
glm::vec2 deltaUV2 = uv2-uv0;
std::cout << " deltaUV1: " << glmHelper.convertVec2(deltaUV1) << " deltaUV2: " << glmHelper.convertVec2(deltaUV2) << std::endl;
float r = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
glm::vec3 tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y)*r;
glm::vec3 bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x)*r;
// Set the same tangent for all three vertices of the triangle.
// They will be merged later, in vboindexer.cpp
tangents.push_back(tangent);
tangents.push_back(tangent);
tangents.push_back(tangent);
// Same thing for bitangents
bitangents.push_back(bitangent);
bitangents.push_back(bitangent);
bitangents.push_back(bitangent);
std::cout << "i:" << i << " Normal: " << glmHelper.convertVec3(normals[i]) << " Tanget: " << glmHelper.convertVec3(tangent) <<
", bitangent " << glmHelper.convertVec3(bitangent) << std::endl;
}
// See "Going Further"
for (unsigned int i=0; i<vertices.size(); i+=1 )
{
glm::vec3 & n = normals[i];
glm::vec3 & t = tangents[i];
glm::vec3 & b = bitangents[i];
// Gram-Schmidt orthogonalize
t = glm::normalize(t - n * glm::dot(n, t));
// Calculate handedness
if (glm::dot(glm::cross(n, t), b) < 0.0f){
t = t * -1.0f;
}
}
}
答案 0 :(得分:0)
问题是以下代码错误:
// Set the same tangent for all three vertices of the triangle.
// They will be merged later, in vboindexer.cpp
tangents.push_back(tangent);
tangents.push_back(tangent);
tangents.push_back(tangent);
// Same thing for bitangents
bitangents.push_back(bitangent);
bitangents.push_back(bitangent);
bitangents.push_back(bitangent);
它应该是:
// Set the same tangent for all three vertices of the triangle.
tangents[index0] = tangent;
tangents[index1] = tangent;
tangents[index2] = tangent;
// Same thing for bitangents
bitangents[index0] = bitangent;
bitangents[index1] = bitangent;
bitangents[index2] = bitangent;