Касательное пространство, касательное / бинормальное вычисление

У меня есть следующий код для вычисления касательных, битангентов. И я могу успешно визуализировать некоторые примеры сетки, используя нормальное отображение.

У меня есть проблема с конкретной сеткой, что она вычисляет тангенциальный коллинеал с нормой.

Любая помощь будет оценена, чтобы определить причину.

Вот пример:

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;
}

}}

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;
0

Другие решения

Других решений пока нет …