当前位置: 首页 > news >正文

【Three.js】知识梳理十:Three.js纹理贴图

1. 纹理贴图

在Three.js中,纹理贴图是一种将二维图像贴到三维物体表面的技术,以增强物体的视觉表现。纹理贴图可以使物体表面更加真实、细腻,为场景增色不少。

在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);
});

2. 纹理过滤

纹理过滤是一种处理技术,用于决定当纹理图像被映射到比其原始分辨率大或小的像素时,如何从纹理中采样颜色。主要有三种类型的纹理过滤:线性过滤、最近邻过滤和mipmap过滤。

  • 线性过滤(Linear Filtering) :这种过滤方法使用了纹理中最近的四个像素的加权平均值,以得到一个新的颜色值。这种方法产生的效果通常比较平滑,但在处理高对比度纹理时,可能会产生模糊的效果。
  • 最近邻过滤(Nearest Filtering) :这种过滤方法简单地选择纹理中最近的一个像素的颜色。这种方法在处理像素艺术和其他需要保持锐利边缘的纹理时非常有用,但可能会导致锯齿状边缘。
  • Mipmap过滤:这种过滤方法在加载纹理时,会创建纹理的多个缩小版本(称为mipmap),然后根据纹理在屏幕上的大小,选择合适大小的mipmap进行采样。这种方法可以在不同距离都保持纹理的良好表现,但会增加内存使用量。

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

minFilter属性控制当纹理被缩小时使用的过滤方法,magFilter属性控制当纹理被放大时使用的过滤方法。这两个属性的默认值都是THREE.LinearMipmapLinearFilter,即使用mipmap过滤。

以下是一个简单的示例,展示了如何在Three.js中设置纹理过滤:

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);
});

在这个例子中,我们首先加载了纹理,然后设置minFilter属性为THREE.NearestFiltermagFilter属性为THREE.LinearFilter。这表示当纹理被缩小时,我们使用最近邻过滤,当纹理被放大时,我们使用线性过滤。

3. UV映射原理

在三维图形中,UV坐标是用于将二维纹理映射到三维模型上的。这个名字中的"U"和"V"代表的是纹理坐标的两个维度,它们与三维空间的"X"、"Y"和"Z"坐标是独立的。

在UV映射中,"U"对应于纹理的水平(宽度)方向,"V"对应于纹理的垂直(高度)方向。UV坐标的范围通常是从0到1,其中(0,0)表示纹理的左下角,(1,1)表示纹理的右上角。

几何体有两组UV坐标,第一组组用于.map.normalMap.specularMap等贴图的映射,第二组用于阴影贴图.lightMap的映射

image.png

3.1 纹理UV坐标

在Three.js中,UV坐标是通过THREE.GeometryTHREE.BufferGeometry对象的.uv属性来定义的。每个面(或者是三角形)都有自己的UV坐标集合,这些集合是一个包含两个元素(U和V)的THREE.Vector2对象的数组。

以下是一个简单的示例,展示了如何在Three.js中定义UV坐标:

var geometry = new THREE.Geometry();
​
// 创建顶点
var v1 = new THREE.Vector3(0,0,0);
var v2 = new THREE.Vector3(1,0,0);
var v3 = new THREE.Vector3(0,1,0);
var v4 = new THREE.Vector3(1,1,0);
​
geometry.vertices.push(v1);
geometry.vertices.push(v2);
geometry.vertices.push(v3);
geometry.vertices.push(v4);
​
// 创建面
var face1 = new THREE.Face3(0, 1, 2);
var face2 = new THREE.Face3(1, 2, 3);
​
// 创建UV坐标
var uv1 = new THREE.Vector2(0, 0);
var uv2 = new THREE.Vector2(1, 0);
var uv3 = new THREE.Vector2(0, 1);
var uv4 = new THREE.Vector2(1, 1);
​
// 将UV坐标添加到每个面
geometry.faces.push(face1);
geometry.faceVertexUvs[0].push([uv1, uv2, uv3]);
​
geometry.faces.push(face2);
geometry.faceVertexUvs[0].push([uv2, uv3, uv4]);

在这个例子中,我们首先创建了一个新的THREE.Geometry对象,然后添加了四个顶点和两个面。然后,我们定义了每个面的UV坐标,并将它们添加到geometry.faceVertexUvs[0]数组。

3.2 纹理映射

现在我们有了几何体和UV坐标,下一步就是创建和加载纹理。在Three.js中,我们可以使用THREE.TextureLoader来加载纹理图片。以下是一个简单的例子:

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);
});

在上述代码中,我们首先创建一个新的THREE.TextureLoader实例,然后调用它的.load()方法来加载纹理。加载完成后,我们创建了一个新的THREE.MeshBasicMaterial对象,并将加载的纹理作为地图属性传递给它。然后,我们使用几何体和材质创建了一个新的THREE.Mesh对象,并将它添加到场景中。

为了更好地控制纹理贴图的映射,可以通过以下方法:

  • 改变纹理的偏移量:texture.offset = new THREE.Vector2(x, y);
  • 改变纹理的缩放比例:texture.repeat = new THREE.Vector2(x, y);

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

4.1 纹理阵列

在某些情况下,你可能希望在物体表面上重复使用一张纹理。比如,当你创建一片草地或墙壁时,你可能需要在模型上多次平铺相同的纹理。这就是纹理阵列的作用。

在Three.js中,我们可以通过设置纹理的repeat属性来实现纹理阵列。repeat属性是一个THREE.Vector2对象,表示纹理在U和V方向上的重复次数。默认情况下,这个值是(1, 1),表示纹理只在每个方向上显示一次。

以下是一个简单的示例,展示了如何在Three.js中创建纹理阵列:

var loader = new THREE.TextureLoader();
​
// 加载纹理
loader.load('textures/yourTexture.png', function(texture) {// 设置纹理阵列texture.wrapS = texture.wrapT = THREE.RepeatWrapping;texture.repeat.set(4, 4);
​// 创建材质var material = new THREE.MeshBasicMaterial({map: texture});
​// 创建网格var mesh = new THREE.Mesh(geometry, material);
​// 将网格添加到场景scene.add(mesh);
});

在这个例子中,我们首先加载了纹理,然后设置了wrapSwrapT属性为THREE.RepeatWrapping,表示我们希望纹理在两个方向上都能重复。接着,我们使用texture.repeat.set(4, 4)来设置纹理在U和V方向上重复4次。

4.2 纹理偏移

如前所述,纹理偏移可以通过调整纹理的offset属性来实现。offset属性是一个THREE.Vector2对象,表示纹理在U和V方向上的偏移量。默认情况下,这个值是(0, 0),表示没有偏移。

以下是一个简单的示例,展示了如何在Three.js中设置纹理偏移:

texture.offset.set(0.5, 0.5);

在这个例子中,我们将纹理的偏移设置为(0.5, 0.5),表示纹理在U和V方向上都向正方向偏移了一半的距离。

4.3 纹理旋转

Three.js中的纹理旋转可以通过修改纹理的rotation属性来实现。

rotation属性是一个以弧度为单位的角度值,用于指定纹理的旋转角度。默认情况下,这个值是0,表示没有旋转。

以下是一个简单的示例,展示了如何在Three.js中设置纹理旋转:

// 旋转纹理90度
texture.rotation = Math.PI / 2;

在这个例子中,我们将纹理的旋转角度设置为Math.PI / 2,即90度。需要注意的是,纹理旋转是以纹理的中心点为轴进行的。

5. UV动画

在Three.js中,我们可以通过修改纹理的offset属性来改变纹理的UV坐标。offset属性是一个THREE.Vector2对象,代表了纹理在U和V方向上的偏移量。我们可以在每一帧中稍微改变这个值,来实现纹理的移动效果。

下面是一个简单的示例,展示了如何在Three.js中创建一个UV动画:

// 加载纹理
var loader = new THREE.TextureLoader();
var texture = loader.load('textures/yourTexture.png');
​
// 创建材质
var material = new THREE.MeshBasicMaterial({map: texture});
​
// 创建网格
var mesh = new THREE.Mesh(geometry, material);
​
// 将网格添加到场景
scene.add(mesh);
​
// 在渲染循环中更新纹理偏移
function animate() {requestAnimationFrame(animate);
​// 每一帧稍微移动纹理material.map.offset.y -= 0.01;
​// 渲染场景renderer.render(scene, camera);
}
​
animate();

在这个例子中,我们首先加载了纹理,然后创建了一个包含该纹理的材质和一个使用该材质的网格。然后,在我们的渲染循环中,我们每一帧都稍微改变纹理的offset.y值,从而使纹理在V方向上移动,产生动态效果。

附送250套精选项目源码

源码截图

 源码获取:关注公众号「码农园区」,回复 【源码】,即可获取全套源码下载链接

相关文章:

【Three.js】知识梳理十:Three.js纹理贴图

1. 纹理贴图 在Three.js中,纹理贴图是一种将二维图像贴到三维物体表面的技术,以增强物体的视觉表现。纹理贴图可以使物体表面更加真实、细腻,为场景增色不少。 在Three.js中,纹理贴图的加载主要通过THREE.TextureLoader类实现。…...

mysql order by后跟case when

在SQL中,ORDER BY子句用于对查询结果进行排序。当在ORDER BY后面使用CASE语句时,它的原理是:根据CASE语句中定义的条件和结果,为查询结果集中的每一行生成一个临时的排序值。然后,根据这些排序值对结果集进行排序。 具…...

数字孪生赋能的智慧园区物联网云平台建设方案(97页PPT)

方案介绍: 本方案通过数字孪生技术赋能智慧园区物联网云平台,实现了园区的智能化管理、优化资源配置、提高运营效率等目标。同时提升园区的安全性、环保性和可持续性。最后,该方案还充分考虑了系统的可扩展性、安全性和可靠性,为…...

TikTok小店运营策略

TikTok,作为一款全球知名的短视频社交平台,其用户基数庞大且日活跃用户持续增长,为商家提供了巨大的商机。欧洲作为TikTok的重要市场之一,其小店功能为商家提供了一个展示和销售产品的新渠道。本文将探讨如何有效地运营TikTok小店…...

Docker面试整理-如何查看和管理Docker容器的日志?

管理和查看 Docker 容器的日志是 Docker 容器管理的重要部分,有助于监控应用的行为和诊断问题。Docker 提供了几种方法来查看和管理容器日志。 查看容器日志 要查看 Docker 容器的日志,你可以使用 docker logs 命令。这个命令会打印容器的 STDOUT 和 STDERR 输出,这是大多数…...

Java从放弃到继续放弃

并发编程 为什么需要多线程? 由于硬件的发展,CPU的核数增多,如果仍然使用单线程对CPU资源会造成浪费。同时,单线程也会出现阻塞的问题。所以,选择向多线程转变。 多线程的使用使得程序能够并行计算,提高计…...

上传文件生成聊天机器人,实现客服、办公自动化智能体 | Chatopera

从谈论聊天机器人,到谈论智能体,是目前人工智能最炙手可热的话题,这两年最大的变化是大语言模型的应用。聊天机器人曾经很难定制,往往局限于个别行业,同时也只有行业内的领导者、头部企业能定制。比如银行、金融证券、…...

SD3303A 大功率高亮度LED驱动芯片IC

一般描述 SD3303A是一款大功率高亮度LED驱动芯片,可以提供1A的电流驱动3W的LED。具有高效率,低功耗等特点,适用于电池供电的LED照明设备。 SD3303A具有开路保护和过温保护。 SD3303A需要使用两颗10uF(或者更大)的瓷片电容,来保…...

站易WordPress

站易WordPress是一家专业提供网站建设和运营服务的公司。他们提供的服务包括企业官方网站建设、网站运营维护、网站托管、网站优化、跨境独立站建站、外贸网站建设以及海外多语言网站建设等。 此外,站易还提供使用现成的WordPress模板,这样可以快速且低…...

windows下JDK1.8安装

windows下JDK1.8安装 本文假设你知道了解基本的windows系统操作。 在Windows系统下安装JDK 1.8(Java Development Kit)的步骤如下: 步骤1:下载JDK 1.8 打开浏览器并访问Oracle JDK下载页面。https://www.oracle.com/java/technol…...

怎么修改Visual Studio Code中现在github账号

git config --global user.name “你的用户名” git config --global user.email “你的邮箱” git config --global --list git push -u origin your_branch_name git remote add origin...

戴尔R720服务器(3)组RAID

今天收到7块硬盘,现在共有8块硬盘了,找了个视频学习了怎么使用阵列卡组RAID并记录。 ​​ ‍ 视频参考:【戴尔服务器添加RAID5热备盘hotspare】 ‍ 阵列卡组RAID5 开始 连接iDRAC控制台服务器开机按F2进入BIOS选择Device Settings​ ​​…...

eNSP学习——配置高级的访问控制列表

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建OSPF网络 3、配置Telnet 4、配置高级ACL控制访问 需要eNSP各种配置命令的点击链接自取:华为eNSP各种设备配置命令大全PDF版_ensp配置命令大全资源-…...

oracle的bitmap索引是什么

Oracle的Bitmap索引是一种特殊的索引类型,主要用于处理那些数值稀疏(low-cardinality,低基数)的字段,特别是那些值不经常改变的字段。以下是关于Bitmap索引的详细解释: 定义: Bitmap索引是一种…...

「前端+鸿蒙」鸿蒙应用开发-TS接口-特殊用途

在 TypeScript 中,接口除了定义对象的结构之外,还有一些特殊用途,这些用途使得接口成为一种灵活的工具,用于提高代码的可维护性和可扩展性。 TS快速入门-接口-特殊用途 1. 定义函数类型 接口可以用来定义函数的类型,…...

Centos7系统禁用Nouveau内核驱动程序【笔记】

在CentOS系统中,Nouveau是开源的NVIDIA显卡驱动程序,但它与NVIDIA的官方驱动程序NVIDIA Proprietary Driver存在兼容性问题。 如果你想要禁用Nouveau并使用NVIDIA官方驱动,可以按照以下步骤操作: 1、创建一个黑名单文件以禁用No…...

Vue 面试通杀秘籍

理论篇: 1. 说说对 Vue 渐进式框架的理解(腾讯医典) a) 渐进式的含义: 主张最少, 没有多做职责之外的事 b) Vue 有些方面是不如 React,不如 Angular.但它是渐进的,没有强主张, 你可以在原有…...

聚焦新版综合编程能力面试考查汇总

目录 一、业务性编程和广度能力考查 (一)基本定义 (二)必要性分析 二、高频考查样题(编程扩展问法) 考题1: 用java 代码实现一个死锁用例,说说怎么解决死锁问题?(高…...

[工具探索]英寸vs毫米下常见尺寸排版

文章目录 常见尺寸1. 照片尺寸2. 纸张尺寸3. 显示器和电视屏幕尺寸4. 手机屏幕尺寸5. 笔记本电脑屏幕尺寸6. 其他设备尺寸 换算公式换算方法常见照片尺寸对比表国际标准ISO(216)纸张尺寸 什么是英寸? 英寸(英语:inch&a…...

Mimio安装

mkdir -p /usr/local/develop/minio/bin mkdir -p /usr/local/develop/minio/bin wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/develop/minio/bin/minio 编辑脚本 启动脚本 vim /usr/local/develop/minio/start_minio.sh #!/bin/bash # 设…...

RawChat:优化AI对话体验,全面兼容GPT功能平台

文章目录 一、Rawchat简介1.1 RawChat的主要特性1.2 RawChat的技术原理简述 二、使用教程三、案例应用3.1 图片内容分析3.2 生图演示3.3 文档解析3.4 探索更多 四、小结 一、Rawchat简介 RawChat平台的诞生,其核心理念是降低用户访问类似ChatGPT这类先进AI服务的门…...

一文详解PaaS平台:机遇、挑战与新变革

随着信息化发展,数字技术与经济社会各个领域的融合逐渐深入,行业需求不断升级,逐渐呈现多样化、复杂性的态势。传统软件开发模式,耗时耗力,已经难以应对企业新形势下的业务需求。面对挑战,PaaS平台以其天然…...

Go每日一库之rotatelogs

介绍 Golang的rotatelogs库是一个用于日志轮转(log rotation)的库。日志轮转是一种常用的日志管理策略,它允许开发者将日志按照一定规则分割成多个文件,以便于管理和分析。通过使用rotatelogs库,开发者可以方便地实现…...

我的网络安全之路——一场诗意的邂逅

文章来源|MS08067 安全实验室 本文作者:tuooo 我的网络安全之路 一场诗意的邂逅 童年的星光中,我仰望着璀璨的荧屏,心怀对未知机器世界的浩瀚与好奇。那时的我,每每想到各种游戏的破解版本与工具,便会被技术…...

Android 中USB-HID协议实现

前言 所有通过USB连接android设备进行通讯的步骤都是大同小异:查询usb设备列表 ——>匹配对应的设备类型(如productid , vendorId)等——>连接usb设备,找到连接通讯的节点——>配置通讯信息,进行通讯。以上是…...

学习AI 机器学习,深度学习需要用到的python库

学习人工智能(AI)时,Python是最流行的编程语言之一。以下是一些常用的Python库和工具,它们可以帮助你入门并深入学习AI和机器学习: 数据处理和分析库 NumPy: 用于处理大型多维数组和矩阵运算,并提供数学函…...

计算机网络 期末复习(谢希仁版本)第8章

元文件就是一种非常小的文件,它描述或指明其他文件的一些重要信息。这里的元文件保存了有关这个音频/视频文件的信息。 10. 流式:TCP;流式实况:UDP。...

abap 多线程运行demo

SAP 提供多种多线程的方法去优化程序的执行效率 1.分别执行多个job 2.Call function STARTING NEW TASK 3.直接使用SAP 提供的SPTA 框架函数:SPTA_PARA_PROCESS_START_2 本次,我们着重来介绍一下三种方法中函数的使用方法 获取空闲线程数:SPBT_INITIALIZE *&------…...

python科研做图系列之时序图的绘制——对比折线图

参考知乎 折线图 我需要从两个不同的excel都读取第一列作为时间列,第二列作为编码列。 在同一张图上画出两条时间序列的折线图 横坐标是分钟,纵坐标是编码 帮我画的好看一些,记得解决中文乱码问题 英文版折线图 ,先搞个英文版,导师要求中文的话,再换成中文版 impor…...

数字信号处理:关于锁存器Latch的发现

关于锁存器的发明,有下面一段伪历史,所谓伪历史,就是我不想去考证发明人是否有这样一条思路,但是这肯定算是一个思路。 伪历史是这样开始的,人们先发明了反相器,就如下图所示。 接着,人们开始考…...

关闭网站弹窗代码/厦门网站关键词推广

PHP怎么实现的根据银行卡号判断是哪个银行?提问:PHP怎么实现的根据银行卡号判断是哪个银行?回答如下:bankList.php的内容会写在下面。请全选其中所有数据后,另存为bankList.php文件使用。header(Content-type:text/htm…...

wordpress 仿钛媒体/微博推广方法有哪些

最近再次复习C语言,用的教材是《C Primer》这本教材, 看到第二章的时候,里面有个问题困扰了我。 于是想上网查查怎么回事, 结果看了很久都没有得到一个满意的答案。 书上有这么一段话:当将一个超出数据类型取值范围的值…...

网站开发所需基础知识/深圳网站优化公司

故障现象:逻辑DG数据库日志能够应用,但是确不会将应用后的日志删除,查看日志发现已经自动设置了TURNING OFF LOG AUTO DELETECompleted: alter database register logfile /archivelog/archive_2_25797_614088933.arcTue Apr 24 11:06:10 201…...

做家装网站源码/网络销售就是忽悠人

问题描述先看下后台返回的Set-Cookie字段:查看浏览器Cookies:思路发现只有JESSIONID存入到了浏览器Storage中的Cookies。通过比较 Response Headers 中两个 set-cookie字段可以发现字段不同:JSESSIONID:path/ZTEV-JWT-Token&#…...

教育网站开发用例图/seo诊断方法步骤

jna jni我最近偶然发现了一个不错的框架,如果您不得不使用本机代码的话,您会喜欢的。 在此框架之前,如果需要调用本机代码,则可以使用JNI 。 JNI使用了一个经过验证的但复杂且容易出错的过程。 首先,您像往常一样编写J…...

网站方案制作/网站建设需要啥

原文:借助Canvas黑魔法,实现营销增益模型Uplift Model | 人人都是产品经理 在后互联网时代,随着营销成本的高涨,如何从存量人群中精准找到营销敏感人群进行触达,进而提高ROI一直是业务中重要的课题。 这样的业务场景…...