You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构建含位置、纹理坐标和法线的唯一顶点集后渲染异常

问题:合并含位置、纹理坐标与法线的唯一顶点后渲染错乱

我在创建包含位置坐标、纹理坐标和法线的唯一顶点集时遇到问题,选用std::unordered_set实现。从.obj文件加载的数据完全正确,仅使用顶点位置可正常渲染网格,但新生成的顶点集却渲染出一团乱三角。

正确渲染效果(仅使用顶点位置):
正确渲染效果

生成唯一顶点后的错误效果:
错误渲染效果

相关代码实现如下:

struct vertex
{
    glm::vec3 Position;
    glm::vec2 TextureCoord;
    glm::vec3 Normal;

    bool operator==(const vertex& rhs) const
    {
        bool Res1 = this->Position == rhs.Position;
        bool Res2 = this->TextureCoord == rhs.TextureCoord;
        bool Res3 = this->Normal == rhs.Normal;

        return Res1 && Res2 && Res3;
    }
};

namespace std
{
template<>
struct hash<vertex>
{
    size_t operator()(const vertex& VertData) const
    {
        size_t res = 0;
        const_cast<hash<vertex>*>(this)->hash_combine(res, hash<glm::vec3>()(VertData.Position));
        const_cast<hash<vertex>*>(this)->hash_combine(res, hash<glm::vec2>()(VertData.TextureCoord));
        const_cast<hash<vertex>*>(this)->hash_combine(res, hash<glm::vec3>()(VertData.Normal));
        return res;
    }
private:
    // NOTE: got from glm library
    void hash_combine(size_t& seed, size_t hash)
    {
        hash += 0x9e3779b9 + (seed << 6) + (seed >> 2);
        seed ^= hash;
    }   
};
}

void mesh::BuildUniqueVertices()
{
    std::unordered_set<vertex> UniqueVertices;
    //std::unordered_map<u32, vertex> UniqueVertices;
    u32 IndexCount = CoordIndices.size();
    std::vector<u32> RemapedIndices(IndexCount);

    for(u32 VertexIndex = 0;
        VertexIndex < IndexCount;
        ++VertexIndex)
    {
        vertex Vert = {};

        v3 Pos = Coords[CoordIndices[VertexIndex]];
        Vert.Position = glm::vec3(Pos.x, Pos.y, Pos.z);

        if(NormalIndices.size() != 0)
        {
            v3 Norm = Normals[NormalIndices[VertexIndex]];
            Vert.Normal = glm::vec3(Norm.x, Norm.y, Norm.z);
        } 

        if(TextCoords.size() != 0)
        {
            v2 TextCoord = TextCoords[TextCoordIndices[VertexIndex]];
            Vert.TextureCoord = glm::vec2(TextCoord.x, TextCoord.y);
        }

        // NOTE: think about something faster
        auto Hint = UniqueVertices.insert(Vert);
        if (Hint.second) 
        {
            RemapedIndices[VertexIndex] = VertexIndex;
        }
        else 
        {
            RemapedIndices[VertexIndex] = static_cast<u32>(std::distance(UniqueVertices.begin(), UniqueVertices.find(Vert)));
        }
    }

    VertexIndices = std::move(RemapedIndices);

    Vertices.reserve(UniqueVertices.size());
    for(auto it = UniqueVertices.begin(); 
             it != UniqueVertices.end();)
    {
        Vertices.push_back(std::move(UniqueVertices.extract(it++).value()));
    }
}

我怀疑哈希函数工作异常导致渲染出初始网格边界附近的乱三角,请问问题可能出在哪里?


内容的提问来源于stack exchange,提问作者Zhukov Artem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:35:22