升级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; }
关键说明
- 旧版
faceVertexUvs[0]的结构为[[UV0, UV1, UV2], [UV0, UV1, UV2], ...],每个子数组对应一个三角面的三组UV。 - r143中使用
setIndex时,UV数组的顺序必须完全匹配索引数组:索引数组每三个值对应一个面,UV数组每三组值也要对应该面的三个顶点。 - 若同一顶点对应不同UV(旧版常见场景),无需复用顶点,直接按索引顺序填充对应UV即可,
BufferGeometry会自动处理顶点拆分逻辑。
验证步骤
替换原有UV处理代码后重新加载模型:
- 确认纹理映射与目标效果一致
- 检查控制台无UV相关报错
内容的提问来源于stack exchange,提问作者R-yurew
相关产品推荐
相关产品推荐

