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

从glTF顶点位置缓冲区生成顶点法线时大量法线为零向量的问题求助

从glTF顶点位置缓冲区生成顶点法线时大量法线为零向量的问题求助

我正在尝试用叉积方法从glTF的顶点位置缓冲区生成顶点法线(JavaScript实现),但大部分生成的法线结果都是(0, 0, 0)。我的代码如下:

const vertices = new Float32Array(
    positionsBuffer,
    meshData.positions.byteOffset,
    meshData.positions.byteLength / 4
)

const indices =
    new Uint16Array(
        indexBuffer,
        meshData.indices.byteOffset,
        meshData.indices.byteLength / 2
    )

const normals = new Float32Array(vertices.length)

for (let i = 0; i < indices.length; i += 9) {
    const vert0 = vec3.create(
        vertices[indices[i]],
        vertices[indices[i + 1]],
        vertices[indices[i + 2]]
    )
    const vert1 = vec3.create(
        vertices[indices[i + 3]],
        vertices[indices[i + 4]],
        vertices[indices[i + 5]]
    )

    const vert2 = vec3.create(
        vertices[indices[i + 6]],
        vertices[indices[i + 7]],
        vertices[indices[i + 8]]
    )

    // p = cross(B-A, C-A)
    const normal = vec3.normalize(
        vec3.cross(
            vec3.subtract(vert1, vert0),
            vec3.subtract(vert2, vert0)
        )
    )

    normals[indices[i]] += normal[0]
    normals[indices[i + 1]] += normal[1]
    normals[indices[i + 2]] += normal[2]

    normals[indices[i + 3]] += normal[0]
    normals[indices[i + 4]] += normal[1]
    normals[indices[i + 5]] += normal[2]

    normals[indices[i + 6]] += normal[0]
    normals[indices[i + 7]] += normal[1]
    normals[indices[i + 8]] += normal[2]
}

for (let i = 0; i < indices.length; i += 3) {
    const normalizedNormal = vec3.normalize(
        vec3.create(
            normals[indices[i]],
            normals[indices[i + 1]],
            normals[indices[i + 2]]
        )
    )

    normals[indices[i]] = normalizedNormal[0]
    normals[indices[i + 1]] = normalizedNormal[1]
    normals[indices[i + 2]] = normalizedNormal[2]
}

我预期能得到类似这样的效果:
预期的法线渲染效果

但实际得到的却是这样:
实际生成的法线渲染效果

我试过修改绕序,但没有任何效果;归一化与否也看不出区别(不过这可能是因为着色器中本来就会对法线做归一化处理)。我查过网上的资料,数学逻辑看起来是没问题的。而且我用同样的方式生成切线是完全正常的,这说明所有顶点都被正确处理了,但就是normals[indices[i]] += normal[0]这类操作经常得到0,我实在搞不懂原因,也不知道该怎么解决,希望能得到大家的建议。

补充信息:渲染使用WebGPU实现,两种情况下的着色器代码没有区别;模型是通过Khronos Blender glTF 2.0导出器生成的。

备注:内容来源于stack exchange,提问作者Hauuagdb Hshg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:19:30