threejs(五)纹理贴图、顶点UV坐标
一、创建纹理贴图
1、首先得有一张图片
2、用纹理贴图加载器 TextureLoader
的load()
方法加载图片,这个方法可以返回一个纹理对象Texture
;
3、把纹理对象Texture
作为球体模型材质 material 的.map
属性的值即可
const textLoader = new THREE.TextureLoader();
const geometry = new THREE.SphereGeometry(100);const material = new THREE.MeshLambertMaterial({// color: 0x00ffff,map: textLoader.load('./earth.jpg')
});
const mesh = new THREE.Mesh(geometry, material);export default mesh;
二、自定义顶点UV坐标
1、顶点UV坐标的作用
从纹理贴图上,提取像素,映射到网格模型 Mesh 的几何体表面上。
2、纹理贴图UV坐标的范围
顶点UV坐标可以在0~1.0
之间任意取值,纹理贴图左下角
对应的UV坐标是(0,0)
,右上角
对应的坐标(1,1)
。
3、自定义顶点UV geometry.attributes.uv
顶点UV坐标geometry.attributes.uv和顶点位置坐标geometry.attributes.position是一一对应的,
UV顶点坐标你可以根据需要在0~1之间任意设置,具体怎么设置,要看你想把图片的哪部分映射到Mesh的几何体表面上。
/**纹理坐标0~1之间随意定义*/
const uvs = new Float32Array([0, 0, //图片左下角1, 0, //图片右下角1, 1, //图片右上角0, 1, //图片左上角
]);
// 设置几何体attributes属性的位置normal属性
geometry.attributes.uv = new THREE.BufferAttribute(uvs, 2); //2个为一组,表示一个顶点的纹理坐标
4、获取纹理贴图四分之一
获取纹理贴图左下角四分之一部分的像素值
const uvs = new Float32Array([0, 0, 0.5, 0, 0.5, 0.5, 0, 0.5,
]);
三、把矩形图片裁剪为圆形渲染
变成下面这样:
很简单,用平面圆形CircleGeometry
就行了
const geometry = new THREE.CircleGeometry(50, 50); //圆形
// const geometry = new THREE.BoxGeometry(100, 100, 100); //长方体
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./texture.jpg');
const material = new THREE.MeshLambertMaterial({// 设置纹理贴图:Texture对象作为材质map属性的属性值map: texture,//map表示材质的颜色贴图属性
});const mesh = new THREE.Mesh(geometry, material);
四、纹理对象Texture阵列模式
示例:把一块块小瓷砖铺到地上的效果
–>
思路
1、创建一个矩形,把单一瓷砖图片通过 Texture 纹理贴图的 load() 方法赋给材质的 map 属性;
2、设置阵列模式:利用 THREE.RepeatWrapping
、texture.repeat.set
Texture的属性和方法
3、旋转阵列,由xy平面变为xz平面,即视觉上瓷砖从贴到垂直的墙上变成贴到了地上。
const geometry = new THREE.PlaneGeometry(100, 100, 100);
const textLoader = new THREE.TextureLoader();
const texture = textLoader.load('./瓷砖.jpg');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(30,30); // *重复的矩阵数量
const material = new THREE.MeshLambertMaterial({map: texture
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI/2); // *旋转矩形平面,正面朝上
五、实现透明背景箭头
思路
1、依旧是纹理贴图那一套,把图放在矩形平面,再旋转到 xz 平面;
2、这里背景透明是通过设置 material 的 transparent
属性实现的;
3、给 scene 添加了一个网格辅助线,为了让箭头跟网格辅助不重合,给箭头 mesh 对象 position.y 向上移了一点点
// 添加一个辅助网格地面
const gridHelper = new THREE.GridHelper(300, 25, 0x004444, 0x004444);
完整代码
const geometry = new THREE.PlaneGeometry(60, 60);
const textLoader = new THREE.TextureLoader();
const texture = textLoader.load('./转弯.png');
const material = new THREE.MeshLambertMaterial({map: texture,transparent: true, // *透明
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI/2); // *与地面平行
mesh.position.y = 1 // *抬上来了一点
六、UV动画(滚动效果)
用小的黑白键生成滚动的效果
思路
1、用纹理贴图把小图片放在矩形平面;
2、用阵列设置50个重复图片;
3、在 render 中通过 texture.offset.x +=0.1
设置纹理动画。
// 一个矩形平面几何体用来表示传送带
const geometry = new THREE.PlaneGeometry(200, 20);
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./纹理3.jpg');const material = new THREE.MeshLambertMaterial({map: texture,//map表示材质的颜色贴图属性
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI/2);// 设置阵列
texture.wrapS = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.x=50;//注意选择合适的阵列数量
// 渲染循环
function render() {texture.offset.x +=0.1;//设置纹理动画renderer.render(scene, camera);requestAnimationFrame(render);
}
render();