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();
相关推荐
西西学代码4 小时前
Flutter---坐标网格图标
前端·javascript·flutter
James_ZHAAO4 小时前
三分钟学懂3D建模中的UV Position Map
uv
@PHARAOH4 小时前
HOW - prefetch 二级页面实践
前端·javascript·react.js
咚咚咚小柒4 小时前
【前端】用el-popover做通用悬停气泡(可设置弹框宽度)
前端·javascript·vue.js·elementui·html·scss
执剑、天涯6 小时前
通过一个typescript的小游戏,使用单元测试实战(二)
javascript·typescript·单元测试
古一|7 小时前
vue3都有哪些升级相比vue2-核心响应式系统重构
javascript·vue.js·重构
HHHHHY7 小时前
http接口响应头类型不对,导致svg图片无法预览,前端解决方案
前端·javascript
元亓亓亓7 小时前
考研408--组成原理--day1
开发语言·javascript·考研·计组
Mintopia8 小时前
🌌 知识图谱与 AIGC 融合:
前端·javascript·aigc