切线空间,切线/二次正规计算

时间:2014-03-29 20:33:39

标签: c++ opengl 3d bump-mapping

我有以下代码来计算切线,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;
        }

    }


}

1 个答案:

答案 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;