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

GLM计算顶点法线异常 沿法线挤出顶点仅一半对象生效

顶点法线计算与挤出异常问题

我尝试计算法线来沿法线方向挤出顶点,但是只有一半的对象生效,粉色线条代表挤出的顶点。

初始法线计算代码

for (Vertex& v : vertices)
{

    glm::vec3 normal = { 0,0,0 };

    for (int i = 0; i < vertices.size(); i++)
    {
        const glm::vec3& a = vertices[i].position;
        const glm::vec3& b = vertices[i + 1].position;
        const glm::vec3& c = vertices[i + 2].position;

        glm::vec3 n = (b - a) * (c - a);
        
        normal += glm::normalize(n);
    }

    v.normal = glm::normalize(normal);
}

编辑1:叉乘计算返回零向量

我尝试改用glm::cross(b-a, c-a)计算叉乘,但输出始终为0,对象显示效果异常。
对应代码如下:

for (Vertex& v : vertices)
{

    glm::vec3 normal = { 0,0,0 };

    for (int i = 0; i < vertices.size(); i++)
    {

        const glm::vec3& a = vertices[i].position;
        const glm::vec3& b = vertices[i + 1].position;
        const glm::vec3& c = vertices[i + 2].position;

        glm::vec3 n = glm::cross( (b - a), (c - a) );
         
        normal += glm::normalize(n);
    }

    v.normal = glm::normalize(normal);
}

补充说明:所有向量的Y分量始终等于0


编辑2:基础形状说明

基础形状为仅使用x、z分量的2D图形,后续会沿Y轴挤出。


问题更新

我已通过先计算顶点切线(tangent)、再通过切线计算法线的方式修复了初始问题,但出现了新问题:修改对象位置时,切线/法线计算会导致对象变形,推测和归一化逻辑相关。
临时修复代码如下:

glm::vec3 GetUnitNormal(const glm::vec2& p1, const glm::vec2& p2, const float s)
    {
        const glm::vec2 p3 = p1 + ( (p2 - p1) * s );
        const float m = (p3.y - p1.y) / (p3.x - p1.x);
        const float c = p1.y - m * p1.x;
        const float y = (m * p1.x) + c;

        const glm::vec2 tangent = glm::normalize(glm::vec2(p1.x, y));
        glm::vec3 normal = glm::vec3(-tangent.y, 0, tangent.x);

        return glm::normalize(normal);
    }

编辑4:关联问题

新的变形问题已单独发布提问。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:27:03