五、Three.js顶点UV坐标、纹理贴图

一部分来自1. 创建纹理贴图 | Three.js中文网 ,一部分是自己的总结。 

一、创建纹理贴图

 注意:把一张图片贴在模型上就是纹理贴图

1、纹理加载器TextureLoader

注意:将图片加载到加载器中

通过纹理贴图加载器TextureLoaderload()方法加载一张图片可以返回一个纹理对象Texture,纹理对象Texture可以作为模型材质颜色贴图.map属性的值。

const geometry = new THREE.PlaneGeometry(200, 100); 
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./earth.jpg');
const material = new THREE.MeshLambertMaterial({// 设置纹理贴图:Texture对象作为材质map属性的属性值map: texture,//map表示材质的颜色贴图属性
});

2、颜色贴图属性.map

 也可以通过颜色贴图属性.map直接设置纹理贴图,和材质的参数设置一样。

material.map = texture;

3、颜色贴图和color属性颜色值会混合

材质的颜色贴图属性.map设置后,模型会从纹理贴图上采集像素值,这时候一般来说不需要再设置材质颜色.color.map贴图之所以称之为颜色贴图就是因为网格模型会获得颜色贴图的颜色值RGB。

颜色贴图map和color属性颜色值会混合。如果没有特殊需要,设置了颜色贴图.map,不用设置color的值,color默认白色0xffffff。

const material = new THREE.MeshBasicMaterial({color:'green',map:texture
})

4、测试不同几何体添加纹理贴图的效果

你可以尝试把颜色纹理贴图映射到不同的几何体上查看渲染效果,至于为什么映射效果不同,其实和UV坐标相关,具体可以关注下节课关于UV坐标的讲解

4.1、矩形

const geometry = new THREE.BoxGeometry(100, 100, 100); //长方体

 4.2、圆形

const geometry = new THREE.SphereGeometry(60, 25, 25); //球体

5、全部代码:

import * as THREE from 'three'const geometry = new THREE.SphereGeometry(100,100,100)
const LoadTex = new THREE.TextureLoader();
const texture = LoadTex.load('./map.jpg')
const material = new THREE.MeshBasicMaterial({// color:'green'map:texture
})const mesh = new THREE.Mesh(geometry,material)
export default mesh

二、自定义顶点UV坐标

 学习自定义顶点UV坐标之前,首先保证你对BufferGeometry的顶点数据、纹理贴图都有一定的理解。

1、顶点UV坐标的作用

顶点UV坐标的作用是从纹理贴图上提取像素映射到网格模型Mesh的几何体表面上。

浏览器控制台查看threejs几何体默认的UV坐标数据

const geometry = new THREE.PlaneGeometry(200, 100); //矩形平面
// const geometry = new THREE.BoxGeometry(100, 100, 100); //长方体
// const geometry = new THREE.SphereGeometry(100, 30, 30);//球体
console.log('uv',geometry.attributes.uv);

2、纹理贴图UV坐标范围

 顶点UV坐标可以在0~1.0之间任意取值,纹理贴图左下角对应的UV坐标是(0,0)右上角对应的坐标(1,1)

3、自定义顶点UVgeometry.attributes.uv

/**纹理坐标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, 
]);

5、全部代码:

import * as THREE from 'three';const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([0, 0, 0,100, 0, 0,100, 100, 0,0, 0, 0,100, 100, 0,0, 100, 0
])
const attribue = new THREE.BufferAttribute(vertices, 3);
geometry.attributes.position = attribue;const uv = new Float32Array([0, 0,1, 0,1, 1,0, 0,1, 1,0, 1
])
geometry.attributes.uv = new THREE.BufferAttribute(uv, 2)const LoadTex = new THREE.TextureLoader();
const texture = LoadTex.load('./map.jpg')
const material = new THREE.MeshBasicMaterial({// color: 'green',map: texture
})const mesh = new THREE.Mesh(geometry, material)
export default mesh

 三、圆形平面设置纹理贴图

其实很简单,可以通过圆形几何体CircleGeometry创建一个网格模型Mesh,把一张图片作为圆形Mesh材质的颜色贴图,这样就可以把一张方形图片剪裁渲染为圆形效果。

import * as THREE from 'three';const geometry = new THREE.CircleGeometry(100,100)const LoadTex = new THREE.TextureLoader();
const texture = LoadTex.load('./map.jpg')
const material = new THREE.MeshBasicMaterial({// color: 'green',map: texture
})const mesh = new THREE.Mesh(geometry, material)
export default mesh

四、纹理对象Texture阵列

使用threejs纹理对象Texture的阵列功能+矩形平面几何体PlaneGeometry实现一个地面瓷砖效果

1、矩形平面设置颜色贴图

const geometry = new THREE.PlaneGeometry(2000, 2000);
//纹理贴图加载器TextureLoader
const texLoader = new THREE.TextureLoader();
// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./瓷砖.jpg');
const material = new THREE.MeshLambertMaterial({// 设置纹理贴图:Texture对象作为材质map属性的属性值map: texture,//map表示材质的颜色贴图属性
});
const mesh = new THREE.Mesh(geometry, material);

2、纹理对象Texture的阵列功能

// .load()方法加载图像,返回一个纹理对象Texture
const texture = texLoader.load('./瓷砖.jpg');
// 设置阵列模式
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.set(12,12);//注意选择合适的阵列数量

3、旋转矩形平面

注意旋转方向影响矩形平面背面还是正面朝上,threejs默认渲染正面,不渲染背面

// 旋转矩形平面
mesh.rotateX(-Math.PI/2);

5、全部代码

import * as THREE from 'three';const geometry = new THREE.PlaneGeometry(2000, 2000)const LoadTex = new THREE.TextureLoader();
const texture = LoadTex.load('./瓷砖.jpg')
//允许阵列
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;texture.repeat.set(12, 12)const material = new THREE.MeshBasicMaterial({// color: 'green',map: texture
})const mesh = new THREE.Mesh(geometry, material)
mesh.rotateX(-Math.PI/2)
export default mesh

 五、矩形Mesh+背景透明png贴图

three.js项目开发中,把一个背景透明的.png图像作为平面矩形网格模型Mesh的颜色贴图是一个非常有用的功能,通过这样一个功能,可以对three.js三维场景进行标注。

整体思路:创建一个矩形平面,设置颜色贴图.map,注意选择背景透明的.png图像作为颜色贴图,同时材质设置transparent: true,这样png图片背景完全透明的部分不显示。

// 矩形平面网格模型设置背景透明的png贴图
const geometry = new THREE.PlaneGeometry(60, 60); //默认在XOY平面上
const textureLoader = new THREE.TextureLoader();
const material = new THREE.MeshBasicMaterial({map: textureLoader.load('./指南针.png'),        transparent: true, //使用背景透明的png贴图,注意开启透明计算
});
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(-Math.PI / 2);

 

1、网格地面辅助观察GridHelper

//辅助网格线
const gridHelper = new THREE.GridHelper(500,25,'green','red')
scene.add(gridHelper)

 

2、开启透明transparent: true

const material = new THREE.MeshBasicMaterial({// color: 'green',map: texture,transparent: true, //使用背景透明的png贴图,注意开启透明计算
})

3、旋转平移矩形平面

PlaneGeometry矩形平面默认是在XOY平面上,如果你想平行于XOZ平面,就需要手动旋转。

mesh.rotateX(-Math.PI/2);//平行地面:矩形Mesh默认单面可见,注意旋转-Math.PI / 2

如果你不想矩形平面Mesh与地面网格线重合,可以通过位置属性.position偏移。

mesh.position.y = 1;//适当偏移,不与地面重合

六、UV动画

通过纹理对象的偏移属性.offset给大家实现一个UV动画效果。

1、纹理对象.offset属性

 纹理对象Texture的.offset的功能是偏移贴图在Mesh上位置,本质上相当于修改了UV顶点坐标。

texture.offset.x +=0.5;//纹理U方向偏移
texture.offset.y +=0.5;//纹理V方向偏移

2、纹理对象.wrapS.wrapT.offset组合使用

texture.offset.x +=0.5;//纹理U方向偏移
// 设置.wrapS也就是U方向,纹理映射模式(包裹模式)
texture.wrapS = THREE.RepeatWrapping;//对应offste.x偏移
texture.offset.y +=0.5;//纹理V方向偏移
// 设置.wrapT也就是V方向,纹理映射模式
texture.wrapT = THREE.RepeatWrapping;//对应offste.y偏移

 

3、纹理UV动画

纹理对象Texture的.offset的功能是偏移贴图在Mesh上位置。

// 渲染循环
function render() {texture.offset.x +=0.001;//设置纹理动画:偏移量根据纹理和动画需要,设置合适的值renderer.render(scene, camera);requestAnimationFrame(render);
}
render();

4、纹理贴图阵列 + UV动画

通过阵列纹理贴图设置.map,这样的话贴图像素可以更小一些

// 设置U方向阵列模式
texture.wrapS = THREE.RepeatWrapping;
// uv两个方向纹理重复数量
texture.repeat.x=50;//注意选择合适的阵列数量
// 渲染循环
function render() {texture.offset.x +=0.1;//设置纹理动画:偏移量根据纹理和动画需要,设置合适的值renderer.render(scene, camera);requestAnimationFrame(render);
}
render();

5、全部代码

import * as THREE from 'three';const geometry = new THREE.PlaneGeometry(500, 100)const LoadTex = new THREE.TextureLoader();
const texture = LoadTex.load('./瓷砖.jpg')
const material = new THREE.MeshBasicMaterial({// color: 'green',map: texture,transparent: true, //使用背景透明的png贴图,注意开启透明计算
})texture.wrapS = THREE.RepeatWrapping;
texture.repeat.x = 6;
const cube = new THREE.Mesh(geometry, material)
cube.rotateX(-Math.PI / 2);
export  { cube, texture }
import { cube, texture } from './group.js'function render() {texture.offset.x += 0.005renderer.render(scene, camera)requestAnimationFrame(render)
}render()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用postman测试api接口基本步骤

测试一个已写好的 API 接口需要系统性地验证其功能、性能、安全性及异常处理能力。以下是使用 Postman 进行 API 接口测试的详细步骤和注意事项: 1. 确认接口文档 明确输入输出:了解接口的请求方法(GET/POST/PUT/DELETE)、URL、请…

綫性與非綫性泛函分析與應用_1.例題(下)-半母本

第1章 實分析與函數論:快速回顧(下) 五、基數;有限集和無限集相關例題 例題1:集合基數的判斷 判斷集合和集合B=\{a,b,c,d,e\}的基數關係。 解析: 可以構造一個雙射,例如,,,,。 所以,兩個集合具有相同的基數。 例題2:可數集的證明 證明整數集是可數集。 解析: …

Windows系统第一次运行C语言程序,环境配置,软件安装等遇到的坑及解决方法

明确需要编辑器和编译器,并选择自己要用什么(我选的编辑器是VSCode:Visual Studio Code;编译器是gcc)下载VSCode并配置环境变量(这里没啥问题),安装C/C的拓展安装Cygwin,…

浅拷贝和深拷贝的区别?可以举例说明

在编程中,浅拷贝和深拷贝是用于复制对象的两种不同方式,它们的主要区别在于复制对象时对对象内部成员的处理方式。今天我们对此进行讨论。 目录 1 浅拷贝 2 深拷贝 1 浅拷贝 浅拷贝创建一个新对象,新对象的属性值会复制原始对象的属性值…

微信小程序实现拉卡拉支付

功能需求:拉卡拉支付(通过跳转拉卡拉平台进行支付),他人支付(通过链接进行平台跳转支付) 1.支付操作 //支付 const onCanStartPay async (obj) > {uni.showLoading({mask: true})// 支付接口获取需要传…

使用ESP-IDF来驱动INMP441全向麦克风

之前的文章我们讲过了I2S。 I2S是什么通信协议?它如何传输音频数据?它和I2C是什么关系?_i2c接口和i2s-CSDN博客文章浏览阅读836次,点赞12次,收藏14次。这个可以参考ADC来理解,我们的ADC也是有左对齐和右对…

MobaXterm_Portable_v23.2 免费下载与使用教程(附安卓替代方案)

一、MobaXterm_Portable 简介 MobaXterm 是一款功能强大的全能终端工具,支持 SSH、SFTP、RDP、VNC、X11 转发 等多种协议,集成了终端、文件传输、远程桌面等功能。其便携版(Portable Edition)无需安装,解压即可使用&a…

【带你 langchain 双排系列教程】6.LangChain多模态输入与自定义输出实战指南

一、为什么需要多模态交互? 在真实业务场景中,数据从来都不是单一形式的。想象一个智能客服系统需要同时分析用户的文字描述、上传的产品图片和语音留言,或者一个内容审核系统需要检查文本、图像和视频的组合内容。传统单一模态的处理方式已…

【Bluedroid】AVRCP 连接源码分析(三)

接着上一篇【Bluedroid】AVRCP 连接源码分析(一)-CSDN博客,继续AVRCP连接的源码分析。 AVRC_OpenBrowse /packages/modules/Bluetooth/system/stack/avrc/avrc_api.cc /*****************************************************************…

基于大语言模型的推荐系统(1)

推荐系统(recommendation system)非常重要。事实上,搜索引擎,电子商务,视频,音乐平台,社交网络等等,几乎所有互联网应用的核心就是向用户推荐内容,商品,电影&…

高性能GPU计算:释放计算潜力的加速利器

高性能GPU计算:释放计算潜力的加速利器 大家好,我是Echo_Wish,今天我们来聊一聊 高性能GPU计算。近年来,随着人工智能、深度学习、科学计算等领域的快速发展,GPU(图形处理单元)作为计算加速的核心技术,逐渐成为数据处理的“核心大脑”。尤其是在深度学习模型训练和大规…

QT闲记-状态栏,模态对话框,非模态对话框

1、创建状态栏 跟菜单栏一样,如果是继承于QMainWindow类,那么可以获取窗口的状态栏,否则就要创建一个状态栏。通过statusBar()获取窗口的状态栏。 2、添加组件 通常添加Label 来显示相关信息,当然也可以添加其他的组件。通过addWidget()添加组件 3、设置状态栏样式 …

SHELL32!SHLoadPopupMenu函数分析之添加属性菜单项

SHELL32!SHLoadPopupMenu函数分析之添加属性菜单项 第一部分: // // user does not support pop-up only menu. // STDAPI_(HMENU) SHLoadPopupMenu(HINSTANCE hinst, UINT id) { HMENU hmenuParent LoadMenu(hinst, MAKEINTRESOURCE(id)); if (hmenuPare…

将RocketMQ集成到了Spring Boot项目中,实现站内信功能

1. 添加依赖 首先,在pom.xml中添加RocketMQ的依赖: <dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot

C语言基础要素:安装 Visual Studio 2022

安装 Visual Studio 2022 Visual Studio 是由微软开发的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;支持多种编程语言和开发平台。它提供了丰富的工具和功能&#xff0c;帮助开发者高效地编写、调试和部署应用程序。无论是桌面应用、Web 应用还是移动应用&#…

[ TypeScript ] “undefined extends xxx“ 总是为 true 的 bug

版本号 "typescript": "^5.7.3", "unplugin": "^2.2.0",说明 在使用 unplugin 时 , 我定义插件的参数是 必填的, 使用时却是一个可空参数, 不传参也不会报错, (options?: UserOptions) > Return &#x1f632;&#x1f632;&…

[通俗易懂C++]:指针和const

之前的文章有说过,使用指针我们可以改变指针指向的内容(通过给指针赋一个新的地址)或者改变被保存地址的值(通过给解引用指针赋一个新值): int main() {int x { 5 }; // 创建一个整数变量 x&#xff0c;初始值为 5int* ptr { &x }; // 创建一个指针 ptr&#xff0c;指向 …

华为昇腾服务器(固件版本查询、驱动版本查询、CANN版本查询)

文章目录 1. **查看固件和驱动版本**2. **查看CANN版本**3. **其他辅助方法**注意事项 在华为昇腾服务器上查看固件、驱动和CANN版本的常用方法如下&#xff1a; 1. 查看固件和驱动版本 通过命令行工具 npu-smi 执行以下命令查看当前设备的固件&#xff08;Firmware&#xff0…

设计心得——解耦的实现技术

一、说明 在前面的“设计心得——解耦”中&#xff0c;对解耦进行了高层次的抽象说明。本篇则对在实践中常用的解耦技术进行逐一分析说明&#xff0c;以期为开发者能更从理论到实践搭建一个桥梁。至于大家能够如何更好的在自己的项目中进行解耦的实践&#xff0c;就需要不断的…

Blaze RangePartitioning 算子Native实现全解析

引言&#xff1a;本文将全面且深入地解析Blaze RangePartitioning算子的Native实现过程。相较于原生Spark&#xff0c;RangePartitioning的Native实现在执行时间上达到了30%的显著下降&#xff0c;同时在资源开销方面节省了高达76%。这一改进大幅降低了运行成本&#xff0c;展现…