threejs(五)纹理贴图、顶点UV坐标

一、创建纹理贴图

1、首先得有一张图片

2、用纹理贴图加载器 TextureLoaderload()方法加载图片,这个方法可以返回一个纹理对象Texture

3、把纹理对象Texture作为球体模型材质 material 的.map属性的值即可

c 复制代码
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的几何体表面上。

c 复制代码
/**纹理坐标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、获取纹理贴图四分之一

获取纹理贴图左下角四分之一部分的像素值

c 复制代码
const uvs = new Float32Array([
    0, 0, 
    0.5, 0, 
    0.5, 0.5, 
    0, 0.5, 
]);

三、把矩形图片裁剪为圆形渲染

变成下面这样:

很简单,用平面圆形CircleGeometry就行了

c 复制代码
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.RepeatWrappingtexture.repeat.set
Texture的属性和方法

3、旋转阵列,由xy平面变为xz平面,即视觉上瓷砖从贴到垂直的墙上变成贴到了地上。

c 复制代码
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 向上移了一点点

c 复制代码
// 添加一个辅助网格地面
const gridHelper = new THREE.GridHelper(300, 25, 0x004444, 0x004444);

完整代码

c 复制代码
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 设置纹理动画。

c 复制代码
// 一个矩形平面几何体用来表示传送带
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;//注意选择合适的阵列数量
c 复制代码
// 渲染循环
function render() {
    texture.offset.x +=0.1;//设置纹理动画
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();
相关推荐
wyzqhhhh9 小时前
同时打开两个浏览器页面,关闭 A 页面的时候,要求 B 页面同时关闭,怎么实现?
前端·javascript·react.js
晴殇i9 小时前
从 WebSocket 到 SSE:实时通信的轻量化演进
前端·javascript
网络点点滴9 小时前
reactive创建对象类型的响应式数据
前端·javascript·vue.js
多则惑少则明11 小时前
Vue开发系列——自定义组件开发
前端·javascript·vue.js
一叶难遮天11 小时前
开启RN之旅——前端基础
前端·javascript·promise·js基础·es6/ts·npm/nrm
BetterChinglish11 小时前
html5中canvas图形变换transform、setTransform原理(变换矩阵)
javascript·html5·canvas·变换矩阵
是你的小橘呀11 小时前
深入解析 JavaScript 引擎与作用域机制
前端·javascript
风止何安啊12 小时前
深入 V8 引擎:JavaScript 执行机制与作用域模型的底层逻辑解析
javascript
你算哪颗溜溜梅12 小时前
uni.scanCode vs MpaasScan:支付宝扫码识别赢麻了,保姆级教程来咯~
javascript·uni-app
羽沢3112 小时前
Vue3组件间通信——pinia
前端·javascript·vue.js