У меня есть следующий код для вычисления касательных, битангентов. И я могу успешно визуализировать некоторые примеры сетки, используя нормальное отображение.
У меня есть проблема с конкретной сеткой, что она вычисляет тангенциальный коллинеал с нормой.
Любая помощь будет оценена, чтобы определить причину.
Вот пример:
v0: (-9,860292,6,589309, -8,947665)
v1: (-9,860292,0,000000, -8,947665),
версия 2 (-8,068345,0,000000, -8,947665)
ув0: (-0,073677, -0,141450)
ув1: (-0,074518, -0,140732),
ув2 (-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),
битангенс (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;
}
}}
Проблема заключалась в том, что следующий код неверен:
// 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;
Других решений пока нет …