Three.js如何实现立方体Cube每个面应用不同纹理贴图
Three.js 立方体六面独立纹理实现方案
核心原理
THREE.Mesh构造函数的第二个参数除了接收单个材质,还支持接收材质数组:针对BoxGeometry,传入长度为6的材质数组时,会自动按固定顺序把材质映射到立方体的6个独立面,无需修改几何体结构。- 材质数组的顺序和对应面的映射规则固定:
- 索引0:正X轴方向(右侧面)
- 索引1:负X轴方向(左侧面)
- 索引2:正Y轴方向(顶面)
- 索引3:负Y轴方向(底面)
- 索引4:正Z轴方向(正面)
- 索引5:负Z轴方向(背面)
代码修改方式
原代码只加载了单张纹理、生成了单个材质,所以所有面复用同一张贴图,替换为如下逻辑即可:
写法1:兼容所有Three.js版本的计数加载写法
// 按面顺序配置6张贴图的路径 const faceTexturePaths = [ './img/right.jpg', './img/left.jpg', './img/top.jpg', './img/bottom.jpg', './img/front.jpg', './img/back.jpg' ]; const faceMaterials = []; let loadedTextureNum = 0; faceTexturePaths.forEach(path => { loader.load(path, (texture) => { faceMaterials.push(new THREE.MeshBasicMaterial({ map: texture })); loadedTextureNum++; // 等6张贴图全部加载完成后再创建立方体,避免纹理缺失 if (loadedTextureNum === 6) { const cubeGeometry = new THREE.BoxGeometry(140, 140, 140); // 传入材质数组而非单个材质 const cube = new THREE.Mesh(cubeGeometry, faceMaterials); this.add(cube); } }) })
写法2:更简洁的异步写法(支持r129及以上版本Three.js)
利用TextureLoader自带的loadAsync方法配合Promise.all并行加载,不需要手动计数:
const createMultiTextureCube = async () => { const faceTexturePaths = [ './img/right.jpg', './img/left.jpg', './img/top.jpg', './img/bottom.jpg', './img/front.jpg', './img/back.jpg' ]; // 并行加载所有纹理 const textures = await Promise.all( faceTexturePaths.map(path => loader.loadAsync(path)) ); // 按顺序生成每个面的材质 const faceMaterials = textures.map(texture => new THREE.MeshBasicMaterial({ map: texture })); const cubeGeometry = new THREE.BoxGeometry(140, 140, 140); const cube = new THREE.Mesh(cubeGeometry, faceMaterials); this.add(cube); } createMultiTextureCube();
补充说明
如果某个面不需要贴图、只需要纯色,直接在材质数组对应索引位置传入纯色材质即可,比如new THREE.MeshBasicMaterial({ color: 0xff0000 })就可以把对应面设置为纯红色,不需要强制所有面都使用纹理材质。
内容的提问来源于stack exchange,提问作者juju
相关产品推荐
相关产品推荐

