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
相关产品推荐
相关产品推荐

