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

Three.js墙面与地面纹理未正常渲染问题求助

Three.js纹理不显示问题排查与解决

核心原因:缺失UV坐标映射

Three.js的几何体如果没有UV坐标(纹理坐标),材质无法识别如何将纹理图像映射到网格表面,只会渲染材质的基础纯色。你的墙面自定义BufferGeometry和地面ShapeGeometry都未设置UV属性,这是纹理不显示的关键原因。

1. 为墙面BufferGeometry添加UV坐标

手动定义UV数组,对应每个顶点的纹理位置,示例将墙面四个顶点映射到纹理的四个角落:

// 在创建wallGeometry的position属性后,添加UV属性
const wallUVs = new Float32Array([
  0, 0, // 顶点1对应纹理左下角
  0, 1, // 顶点2对应纹理左上角
  1, 0, // 顶点3对应纹理右下角
  1, 1  // 顶点4对应纹理右上角
]);
wallGeometry.setAttribute('uv', new THREE.BufferAttribute(wallUVs, 2));

2. 为地面ShapeGeometry生成UV坐标

ShapeGeometry默认不会自动生成UV,可通过手动计算添加:

const shapeGeometry = new THREE.ShapeGeometry(floorGeometry);
// 基于Shape的边界计算UV,适配纹理映射
const uvArray = [];
const positions = shapeGeometry.attributes.position.array;
const bounds = floorGeometry.getBoundingBox();
const width = bounds.max.x - bounds.min.x;
const height = bounds.max.y - bounds.min.y;

for (let i = 0; i < positions.length; i += 3) {
  const x = (positions[i] - bounds.min.x) / width;
  const y = (positions[i + 1] - bounds.min.y) / height;
  uvArray.push(x, y);
}
shapeGeometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvArray, 2));

其他优化建议

  • 异步纹理加载处理:TextureLoader.load是异步操作,可监听加载完成事件确保材质正确更新:
    const floorTex = new THREE.TextureLoader().load(floorTexture, (texture) => {
      texture.encoding = THREE.sRGBEncoding; // 与渲染器编码保持一致
      floorMaterial.map = texture;
      floorMaterial.needsUpdate = true;
    });
    
  • 墙面材质替换:MeshBasicMaterial不受光照影响,建议换成MeshStandardMaterial,匹配场景的光照设置:
    const wallMaterial = new THREE.MeshStandardMaterial({ map: wallTex, side: THREE.DoubleSide });
    
  • 纹理平铺设置:若需要纹理重复平铺,添加以下配置:
    floorTex.wrapS = THREE.RepeatWrapping;
    floorTex.wrapT = THREE.RepeatWrapping;
    floorTex.repeat.set(2, 2); // 横向、纵向各重复2次
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:31:04