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

升级Three.js版本后自定义BufferGeometry的UV纹理映射修复求助

修复Three.js r44升级至r143的UV映射问题

问题根源

旧版本r44的JSON几何中,UV数据按面存储(geometry.faceVertexUvs[0]里每个元素对应一个三角面的3组UV),而r143的BufferGeometry要求UV数据与顶点索引一一对应——每个索引位置必须匹配对应的UV坐标,不能直接按面批量导入。

具体修复方案

修改convertGeometryToFiveBufferGeometry函数中UV处理的逻辑(原第476行附近):

function convertGeometryToFiveBufferGeometry(geometry) {
  const bufferGeometry = new THREE.BufferGeometry();
  
  // 保留原有顶点处理逻辑
  const vertices = [];
  geometry.vertices.forEach(v => {
    vertices.push(v.x, v.y, v.z);
  });
  bufferGeometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
  
  // 保留原有索引处理逻辑
  const indices = [];
  geometry.faces.forEach(face => {
    indices.push(face.a, face.b, face.c);
  });
  bufferGeometry.setIndex(indices);
  
  // --- 修复UV处理核心逻辑 ---
  const uvs = [];
  // 遍历每个面的UV数据,按索引顺序对应填充
  geometry.faceVertexUvs[0].forEach(faceUvs => {
    // 每个面的三个UV与面的三个顶点索引一一对应
    uvs.push(faceUvs[0].x, faceUvs[0].y);
    uvs.push(faceUvs[1].x, faceUvs[1].y);
    uvs.push(faceUvs[2].x, faceUvs[2].y);
  });
  // UV数组长度需与索引数组完全匹配(每个索引对应一组UV)
  bufferGeometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));
  
  // 按需计算法线(若原有逻辑包含)
  bufferGeometry.computeVertexNormals();
  
  return bufferGeometry;
}

关键说明

  1. 旧版faceVertexUvs[0]的结构为[[UV0, UV1, UV2], [UV0, UV1, UV2], ...],每个子数组对应一个三角面的三组UV。
  2. r143中使用setIndex时,UV数组的顺序必须完全匹配索引数组:索引数组每三个值对应一个面,UV数组每三组值也要对应该面的三个顶点。
  3. 若同一顶点对应不同UV(旧版常见场景),无需复用顶点,直接按索引顺序填充对应UV即可,BufferGeometry会自动处理顶点拆分逻辑。

验证步骤

替换原有UV处理代码后重新加载模型:

  • 确认纹理映射与目标效果一致
  • 检查控制台无UV相关报错

内容的提问来源于stack exchange,提问作者R-yurew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:27:36