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

Three.js r125+从文件构建自定义BufferGeometry及设置三角面的问题

实现方案

Three.js的BufferGeometry对应旧版Geometry的faces逻辑,不需要重复存储顶点,直接用索引数组实现即可,你原有的扇形拆分逻辑几乎不需要修改,只需要把添加Face3的逻辑替换为往索引数组中推顶点索引,最后给BufferGeometry设置索引属性就行。

你第一版读取VERTICES、VERTEX NORMALS设置position、normal属性的代码可以直接保留,只需要新增下面处理FACES的代码:

// 接你第一版设置完position、normal属性之后的代码
while(pieces[0]!="FACES")
{
    i++;
    pieces = jedata[i].split(" ");
}
cnt = parseInt(pieces[1]);
while(pieces[0]!="0:")
{
    i++;
    pieces = jedata[i].split(" ");
}
const indices = []; // 存储所有三角面的顶点索引
for(var j = 0; j < cnt; j++)
{
    pieces = jedata[i+j].trim().split(" ");
    var faces = [];
    var vcnt = pieces[7];
    for(var k=0; k<vcnt*2; k+=2)
    {
        faces.push(parseInt(pieces[k+8]));
    }
    // 扇形拆分逻辑和旧版完全一致
    for(var k=1; k<faces.length-1; k++)
    {
        indices.push(faces[0], faces[k], faces[k+1]);
    }
}
// 给BufferGeometry设置索引
geo.setIndex(indices);
// 如果你读取的顶点法线有误差,可以调用下面的方法重新计算平滑法线
// geo.computeVertexNormals();

临时方案的问题说明

  1. 顶点数据翻倍:临时方案将每个三角面的顶点都单独存储,原本可复用的顶点被重复写入了多次,而使用索引模式时顶点仅需存储一次,索引数组仅存顶点的引用,内存占用和旧版Geometry完全一致。
  2. 光照异常:两个核心原因:
    • 重复存储顶点时,原本共享同一个顶点的面被拆分为了多组独立顶点,顶点法线的连续性被破坏,就会出现光照接缝;
    • 未使用索引时Three.js默认按顺序每3个顶点为一个面处理,很容易出现面的绕序和法线方向不匹配,导致光照计算错误。

额外注意点

如果你的自定义3D文件的顶点索引是从1开始计数的,读取后需要手动减1,Three.js的BufferGeometry索引默认从0开始计数,这是这类自定义格式解析的常见坑点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:51:04