【three.js】纹理贴图

目录

 1.纹理贴图

2.纹理过滤

3.UV映射原理

3.1纹理UV坐标

3.2纹理映射

4.纹理阵列,偏移和旋转

4.1纹理阵列

4.2纹理偏移

4.3纹理旋转

5.UV动画


 1.纹理贴图

在Three.js中,纹理贴图是一种将二维图像应用到三维物体表面的技术,显著提升物体的视觉表现力。通过使用THREE.TextureLoader类,可以轻松地加载和应用纹理。

例如,加载一个纹理并应用到一个立方体上,可以通过以下代码实现:

const loader = new THREE.TextureLoader();
loader.load('path/to/your/texture.png', function(texture) {const material = new THREE.MeshBasicMaterial({map: texture});const geometry = new THREE.BoxGeometry(1, 1, 1);const cube = new THREE.Mesh(geometry, material);scene.add(cube);
});

        除了基本的THREE.MeshBasicMaterial,Three.js还支持其他材质类型,如THREE.MeshStandardMaterialTHREE.MeshPhongMaterial,它们提供了更逼真的光照和反射效果。

2.纹理过滤

纹理过滤是决定纹理映射到不同尺寸像素时如何采样的技术。Three.js支持三种主要的纹理过滤方法:

线性过滤(Linear Filtering):使用最近四个像素的加权平均值,产生平滑效果,但可能模糊高对比度纹理。

最近邻过滤(Nearest Filtering):选择最近的像素颜色,适用于保持锐利边缘的纹理,但可能导致锯齿状边缘。

Mipmap过滤:创建纹理的多个缩小版本(mipmap),根据纹理在屏幕上的大小选择合适的mipmap进行采样,提供不同距离下的良好表现,但增加内存使用。

在Three.js中,可以通过设置纹理的minFiltermagFilter属性来控制纹理过滤。例如

var loader = new THREE.TextureLoader();
​
// 加载纹理
loader.load('textures/yourTexture.png', function(texture) {// 设置纹理过滤texture.minFilter = THREE.NearestFilter;texture.magFilter = THREE.LinearFilter;
​// 创建材质var material = new THREE.MeshBasicMaterial({map: texture});
​// 创建网格var mesh = new THREE.Mesh(geometry, material);
​// 将网格添加到场景scene.add(mesh);
});

3.UV映射原理

UV映射是将二维纹理坐标映射到三维模型上的过程。UV坐标独立于三维坐标,通常范围从0到1,其中(0,0)表示纹理的左下角,(1,1)表示右上角。在Three.js中,UV坐标通过THREE.Geometry(已被THREE.BufferGeometry取代)或THREE.BufferGeometry对象的.uv属性定义。每个面或三角形都有自己的UV坐标集合。

定义UV坐标和创建纹理映射的示例如下:

var geometry = new THREE.BufferGeometry(); // 使用BufferGeometry替代Geometry
// ... 创建顶点和面,并设置UV坐标 ...
var loader = new THREE.TextureLoader();
loader.load('textures/yourTexture.png', function(texture) {var material = new THREE.MeshBasicMaterial({map: texture});var mesh = new THREE.Mesh(geometry, material);scene.add(mesh);
});

对于复杂的几何体,建议使用专业的3D建模软件(如Blender)生成UV坐标,并导出为Three.js可识别的格式。

3.1纹理UV坐标

纹理UV坐标是定义在二维纹理图像上的坐标系统,用于将纹理图像上的每个点映射到三维模型的表面上。UV坐标通常被归一化到[0, 1]范围内,其中(0, 0)表示纹理的左下角,(1, 1)表示纹理的右上角。通过调整UV坐标,可以控制纹理在模型表面上的布局和重复

// 引入Three.js库(这里假设已经通过<script>标签或模块系统正确引入)// 创建场景
const scene = new THREE.Scene();// 创建相机
const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight, 0.1, 1000
);
camera.position.z = 5;// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 加载纹理
const textureLoader = new THREE.TextureLoader();
textureLoader.load('path/to/your/texture.jpg', function(texture) {// 创建一个平面几何体,但先不设置UV坐标(Three.js会自动生成默认的)const planeGeometry = new THREE.PlaneGeometry(2, 2); // 2x2的平面// 手动设置UV坐标// 我们将纹理的一部分(例如左上角1/4区域)映射到整个平面上planeGeometry.faceVertexUvs[0] = [[new THREE.Vector2(0, 0),       // 左下角的UV坐标(纹理的左上角)new THREE.Vector2(0.5, 0),     // 右下角的UV坐标(纹理横向1/2处)new THREE.Vector2(0.5, 0.5),   // 右上角的UV坐标(纹理的1/4右上角)new THREE.Vector2(0, 0.5)      // 左上角的UV坐标(与左下角相同,形成闭环)]];// 注意:上面的UV设置实际上会导致纹理在平面上重复,因为两个对角点的UV坐标相同。// 为了正确映射纹理的一部分到平面,我们应该这样设置:planeGeometry.faceVertexUvs[0] = [[new THREE.Vector2(0, 0),       // 左下角的UV坐标(纹理的左上角)new THREE.Vector2(0.25, 0),    // 右下角的UV坐标(纹理横向1/4处)new THREE.Vector2(0.25, 0.25), // 右上角的UV坐标(纹理的1/4右上角)new THREE.Vector2(0, 0.25)     // 左上角的UV坐标(纹理纵向1/4处)]];// 创建一个材质,并将加载的纹理应用到该材质上const material = new THREE.MeshBasicMaterial({ map: texture });// 使用几何体和材质创建一个网格,并将其添加到场景中const plane = new THREE.Mesh(planeGeometry, material);scene.add(plane);// 渲染循环function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);}animate();
});// 处理窗口大小变化(可选)
window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);
});

3.2纹理映射

纹理映射是一种技术,它将二维纹理图像应用到三维模型的表面上。这通常通过UV坐标来实现,使得当模型被渲染时,其表面会呈现出纹理图像的外观。纹理映射可以极大地增强三维模型的真实感和细节

// 引入Three.js库(假设已经通过<script>标签或模块导入)// 创建场景
const scene = new THREE.Scene();// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 加载纹理
const textureLoader = new THREE.TextureLoader();
textureLoader.load('path/to/your/texture.jpg', function(texture) {// 创建一个平面几何体(PlaneGeometry)const geometry = new THREE.PlaneGeometry(2, 2); // 创建一个2x2的平面// 默认情况下,PlaneGeometry的UV坐标已经设置好了,覆盖整个纹理// 但如果你想手动设置UV坐标,可以这样做:// geometry.faceVertexUvs[0] = [//     [//          new THREE.Vector2(0, 0), //          new THREE.Vector2(1, 0), //          new THREE.Vector2(1, 1), //          new THREE.Vector2(0, 1)//      ]// ]; // 这会设置一个简单的矩形UV映射// 创建一个材质,并将纹理应用于该材质const material = new THREE.MeshBasicMaterial({ map: texture });// 创建一个网格并添加到场景中const plane = new THREE.Mesh(geometry, material);scene.add(plane);// 渲染循环function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);}animate();
});// 处理窗口大小变化(可选)
window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);
});

4.纹理阵列,偏移和旋转

纹理阵列、偏移和旋转进一步增强了纹理的灵活性和表现力:

纹理阵列:通过设置texture.wrapStexture.wrapTTHREE.RepeatWrapping,并使用texture.repeat属性,可以在物体表面上重复使用纹理。

纹理偏移:通过调整texture.offset属性,可以实现纹理的局部移动效果。

纹理旋转:通过设置texture.rotation属性,可以旋转纹理。需要注意的是,旋转角度是以弧度为单位的。

        最后,通过修改纹理的offset属性,可以在每一帧中稍微改变其值,从而实现UV动画效果。结合THREE.Clock对象,可以更加流畅和可控地控制动画的速度和帧率。

4.1纹理阵列

纹理阵列(Texture Array)是一种将多个纹理图像组合成一个单一纹理对象的技术。这样,可以在一个渲染过程中使用多个纹理,而无需频繁地切换纹理。纹理阵列在图形处理中非常有用,特别是在需要同时处理多个纹理时,如场景的背景、物体的不同部分等。

实例:

假设有一个包含多个不同纹理的纹理阵列,可以在Shader中通过索引来选择要使用的纹理。例如,在Unity的Shader中,可以使用tex2DArray函数来从纹理阵列中采样纹理。

sampler2DArray _TexArray;
float4 frag(v2f i) : SV_Target
{float4 col = tex2DArray(_TexArray, float3(i.uv, 0)); // 假设使用第一个纹理return col;
}

4.2纹理偏移

纹理偏移(Texture Offset)是一种通过改变UV坐标来移动纹理图像在模型表面位置的技术。通过调整UV坐标的偏移量,可以实现纹理在模型表面的平移效果。

示例

在Unity中,可以通过调整材质的_MainTex_ST.zw属性来改变纹理的偏移量。例如,要向右移动纹理,可以增加_MainTex_ST.x的值;要向上移动纹理,可以增加_MainTex_ST.y的值。

// 假设有一个名为_MainTex的纹理
Renderer renderer = GetComponent<Renderer>();
Material material = renderer.material;
Vector4 offsetScale = material.GetVector("_MainTex_ST");
offsetScale.x += 0.1f; // 向右移动纹理
material.SetVector("_MainTex_ST", offsetScale);

4.3纹理旋转

纹理旋转(Texture Rotation)是一种通过改变UV坐标来旋转纹理图像在模型表面方向的技术。通过调整UV坐标的旋转角度,可以实现纹理在模型表面的旋转效果。

示例

在Unity的Shader中,可以通过调整UV坐标的旋转矩阵来实现纹理的旋转。例如,要旋转纹理90度,可以使用以下Shader代码:

struct appdata
{float4 vertex : POSITION;float2 uv : TEXCOORD0;
};struct v2f
{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;
};v2f vert(appdata v)
{v2f o;o.vertex = UnityObjectToClipPos(v.vertex);// 旋转UV坐标(90度)float2 rotatedUV = float2(cos(PI/2) * v.uv.x - sin(PI/2) * v.uv.y, sin(PI/2) * v.uv.x + cos(PI/2) * v.uv.y);o.uv = rotatedUV;return o;
}sampler2D _MainTex;
float4 frag(v2f i) : SV_Target
{float4 col = tex2D(_MainTex, i.uv);return col;
}

5.UV动画

UV动画是一种通过动态改变UV坐标来实现纹理在模型表面移动或变化的效果。通过逐帧更新UV坐标,可以创建出各种动态的纹理效果,如滚动、波动、闪烁等。

示例

在Unity中,可以通过编写脚本来实现UV动画。例如,以下脚本实现了一个简单的UV滚动动画:

using UnityEngine;public class UVScrollAnimation : MonoBehaviour
{public float scrollSpeed = 0.1f;private Mesh mesh;private Vector2[] uvs;void Start(){mesh = GetComponent<MeshFilter>().mesh;uvs = mesh.uv.Clone() as Vector2[];}void Update(){for (int i = 0; i < uvs.Length; i++){uvs[i].x += Time.deltaTime * scrollSpeed;if (uvs[i].x > 1.0f){uvs[i].x -= 1.0f; // 纹理循环滚动}}mesh.uv = uvs;}
}

将上述脚本附加到一个带有MeshFilter组件的GameObject上,并设置scrollSpeed属性,即可看到纹理在模型表面滚动的动画效果。

码字不易,各位大佬点点赞呗

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

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

相关文章

Excel 技巧10 - 如何检查输入重复数据(★★)

本文讲了如何在Excel中通过COUNTIF来检查输入重复数据。 当输入重复数据时&#xff0c;显示错误提示。 1&#xff0c;通过COUNTIF来检查输入重复数据 比如下面是想检查不要输入重复的学号。 选中C列&#xff0c;点 Menu > 数据 > 数据验证 在数据验证页面&#xff0c…

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)

inode 和 block 的映射 该博文中有详细解释&#xff1a;【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题&#xff1a; 问题一&#xff1a; 我们访问文件&#xff0c;都是用的文件名&#xff0c;没用过 inode 号啊&#xff1f; 之前总是说可以通过一个…

[计算机网络]一. 计算机网络概论第一部分

作者申明&#xff1a;作者所有文章借助了各个渠道的图片视频以及资料&#xff0c;在此致谢。作者所有文章不用于盈利&#xff0c;只是用于个人学习。 1.0推荐动画 【网络】半小时看懂<计算机网络>_哔哩哔哩_bilibili 1.1计算机网络在信息时代的作用 在当今信息时代&…

Python操作Excel——openpyxl使用笔记(2)

2. 操作工作表 前面提到一个工作簿中会有一个或者多个工作表&#xff0c;当前使用的工作表被称作活动工作表&#xff0c;这里展开介绍一下对于工作表的一些操作。 2.1 枚举所有工作表 使用for循环可以很方便的遍历每个工作表&#xff1a; import openpyxl wb openpyxl.o…

Social LSTM:Human Trajectory Prediction in Crowded Spaces | 文献翻译

概要 行人遵循不同轨迹以避免障碍物和容纳同行者。任何在这种场景中巡航的自动驾驶车辆都需要能够遇见行人的未来位置并相应地调整其路线以避免碰撞。轨迹预测问题能够被看作一个顺序生成任务&#xff0c;其中我们对基于行人过去的位置预测其未来的轨迹感兴趣。根据最近RNN&am…

从零开始:Gitee 仓库创建与 Git 配置指南

引言 Git 是一款广泛使用的版本控制工具&#xff0c;它能够帮助开发者在开发过程中高效地管理代码的版本。而 Gitee&#xff08;码云&#xff09;是国内知名的 Git 托管平台&#xff0c;它提供了强大的代码托管、团队协作和项目管理功能。如果你是 Git 和 Gitee 的新手&#x…

挖掘机检测数据集,准确识别率91.0%,4327张原始图片,支持YOLO,COCO JSON,PASICAL VOC XML等多种格式标注

挖掘机检测数据集&#xff0c;准确识别率91.0%&#xff0c;4327张图片&#xff0c;支持YOLO&#xff0c;COCO JSON&#xff0c;PASICAL VOC XML等多种格式标注 数据集详情 数据集分割 训练组70&#xff05; 3022图片 有效集20&#xff05; 870图片 测试集10&…

CV 图像处理基础笔记大全(超全版哦~)!!!

一、图像的数字化表示 像素 数字图像由众多像素组成&#xff0c;是图像的基本构成单位。在灰度图像中&#xff0c;一个像素用一个数值表示其亮度&#xff0c;通常 8 位存储&#xff0c;取值范围 0 - 255&#xff0c;0 为纯黑&#xff0c;255 为纯白。例如&#xff0c;一幅简单的…

QT 使用QTableView读取数据库数据,表格分页,跳转,导出,过滤功能

文章目录 效果图概述功能点代码分析导航栏表格更新视图表格导出表格过滤 总结 效果图 概述 本案例用于对数据库中的数据进行显示等其他操作。数据库的映射&#xff0c;插入等功能看此博客框架&#xff1a;数据模型使用QSqlTableModel&#xff0c;视图使用QTableView&#xff0…

UI自动化测试:异常截图和page_source

自动化测试过程中&#xff0c;是否遇到过脚本执行中途出错却不知道原因的情况&#xff1f;测试人员面临的不仅是问题的复现&#xff0c;还有对错误的快速定位和分析。而异常截图与页面源码&#xff08;Page Source&#xff09;的结合&#xff0c;正是解决这一难题的利器。 在实…

Spark常见面试题-部分待更新

1. 简述hadoop 和 spark 的不同点&#xff08;为什么spark更快&#xff09; Hadoop是一个分布式管理、存储、计算的生态系统&#xff0c;包括HDFS&#xff08;分布式文件系统&#xff09;、MapReduce&#xff08;计算引擎&#xff09;和YARN&#xff08;资源调度器&#xff09;…

HackMyVM-Klim靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Getshell 3、提权 CVE-2008-0166 四、结论 一、测试环境 1、系统环境 渗透机&#xff1a;kali2021.1(192.168.159.127) 靶 机&#xff1a;debian(192.168.159.27) 注意事…

数据结构题目 课时6

题目 1、设一棵树的度是 4&#xff0c;其中度为 0, 1, 2, 3, 4 的结点个数分别是 8, 4, 2, 1 和&#xff08; &#xff09;。 A. 4 B. 3 C. 2 D. 1 2、设一棵 m 叉树中有 N₁个度数为 1 的结点&#xff0c;N₂个度数为 2 的结点&#xff0c;……&#xff0c;Nₘ个度…

Linux下源码编译安装Nginx1.24及服务脚本实战

1、下载Nginx [rootlocalhost ~]# wget -c https://nginx.org/download/nginx-1.24.0.tar.gz2、解压 [rootlocalhost ~]# tar xf nginx-1.24.0.tar.gz -C /usr/local/src/3、安装依赖 [rootlocalhost ~]# yum install gcc gcc-c make pcre-devel openssl-devel -y4、 准备 N…

Web前端------表单标签

一.表单标签介绍 1.认识表单 表单---类似于日常生活中的申请单 都是去填写一些信息去申请某个功能&#xff0c;例如&#xff1a;账号密码昵称&#xff0c;登陆网站 2.常见标签 常见的标签 <form></form> 表单标签&#xff0c;所有表单信息都包含在这个标签内…

LLM - 大模型 ScallingLaws 的迁移学习与混合训练(PLM) 教程(3)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145212097 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…

Unity2017 控制.abc格式的三维动画播放

首先需要导入插件Alembic&#xff0c;否则导入abc动画&#xff0c;Unity是不会识别的。 Unity2017版本及以下直接从我这儿下载&#xff1a;https://download.csdn.net/download/qq_41603955/90272382 高版本Unity&#xff0c;请移步AssetStore商店搜找。 导入abc之后&#x…

【视觉惯性SLAM:十七、ORB-SLAM3 中的跟踪流程】

17.1 跟踪流程流程图 ORB-SLAM3 的跟踪模块是整个系统的重要组成部分&#xff0c;负责实时确定相机在三维空间中的姿态位置&#xff0c;并保持关键帧之间的连续性。其基本目标是将输入的视频流与已有地图数据进行对齐&#xff0c;完成位姿估计和地图更新。 流程图概述 一个…

开发神器之cursor

文章目录 cursor简介主要特点 下载cursor页面的简单介绍切换大模型指定ai学习的文件指定特定的代码喂给ai创建项目框架文件 cursor简介 Cursor 是一款专为开发者设计的智能代码编辑器&#xff0c;集成了先进的 AI 技术&#xff0c;旨在提升编程效率。以下是其主要特点和功能&a…

CSRF攻击XSS攻击

概述 ​在 HTML 中&#xff0c;<a>, <form>, <img>, <script>, <iframe>, <link> 等标签以及 Ajax 都可以指向一个资源地址&#xff0c;而所谓的跨域请求就是指&#xff1a;当前发起请求的域与该请求指向的资源所在的域不一样。这里的域指…