从零开始学习three.js(15):一文详解three.js中的纹理映射UV

1. UV 映射基础概念

1.1 什么是 UV 坐标?

在三维计算机图形学中,UV 坐标是将二维纹理映射到三维模型表面的坐标系统。UV 中的 U 和 V 分别代表2D纹理空间的水平(X)和垂直(Y)坐标轴,与三维空间中的 XYZ 坐标形成区分。

  • UV 坐标系范围:[0,0] 到 [1,1]
  • 每个顶点对应一个UV坐标
  • 纹理采样器通过UV值获取纹理颜色

1.2 坐标系差异

// Three.js 中的坐标系对比
三维模型坐标:(x, y, z) ∈ [-∞, +∞]
纹理UV坐标:(u, v) ∈ [0, 1]
屏幕像素坐标:(x, y) ∈ [0, viewportSize]

2. Three.js 中的 UV 实现

2.1 Geometry 与 BufferGeometry

// 经典 Geometry 的UV设置
const geometry = new THREE.Geometry();
geometry.faceVertexUvs[0].push([new THREE.Vector2(0, 0),new THREE.Vector2(1, 0),new THREE.Vector2(0.5, 1)
]);// BufferGeometry 的UV设置
// 自定义平面几何体
const geometry = new THREE.BufferGeometry();
const vertices = new Float32Array([...]); // 顶点坐标
const uv = new Float32Array([0, 0, // 顶点0的UV1, 0, // 顶点1的UV1, 1, // 顶点2的UV0, 1  // 顶点3的UV
]);
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setAttribute('uv', new THREE.BufferAttribute(uv, 2)); // 关键UV设置[1,5](@ref)

2.2 内置几何体的UV映射

映射类型特点适用场景Three.js实现
​平面映射​正交投影,无透视变形墙面、地面PlaneGeometry默认UV2
​立方体映射​6面独立展开盒子、建筑BoxGeometry自动生成4
​球形映射​极坐标展开行星、球体SphereGeometry经线展开6
​圆柱映射​环形展开管道、柱体需手动设置UV3
2.2.1 BoxGeometry
  • 6个立方体面共享同一张纹理
  • 每个面UV范围:[ (0,0), (1,1) ]
  • 默认沿表面均匀展开,,但可能存在接缝
2.2.2 SphereGeometry
  • 经线方向:U坐标(0到1)
  • 纬线方向:V坐标(0到1)
  • 极点处UV密度较高
  • 采用球形投影,UV 在两极可能出现拉伸。
2.2.3 CylinderGeometry
  • 侧面:U环绕圆柱,V沿高度
  • 顶部/底面:圆形UV展开

3. UV 操作实战技巧

3.1 动态修改UV坐标

// 获取UV属性数组
const uvAttribute = geometry.getAttribute('uv');
const uvs = uvAttribute.array;// 修改第三个顶点的U坐标
uvs[2 * 2] = 0.75; // 索引计算:顶点索引 * 分量数 + 偏移// 必须标记更新
uvAttribute.needsUpdate = true;

3.2 纹理重复与偏移

const texture = new THREE.TextureLoader().load('tile.jpg');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.MirroredRepeatWrapping;
texture.repeat.set(2, 3);
texture.offset.set(0.5, 0.25);

4. 高级 UV 应用

4.1 多重纹理混合

// 着色器代码示例
varying vec2 vUv;
uniform sampler2D texture1;
uniform sampler2D texture2;void main() {vec4 texColor1 = texture2D(texture1, vUv);vec4 texColor2 = texture2D(texture2, vUv * 2.0);gl_FragColor = mix(texColor1, texColor2, 0.5);
}

4.2 UV 动画

function animate() {requestAnimationFrame(animate);// 水平滚动纹理texture.offset.x += 0.01;// 动态修改UV坐标const uvs = geometry.attributes.uv.array;for(let i=0; i<uvs.length; i+=2){uvs[i] += Math.sin(Date.now() * 0.001) * 0.01;}geometry.attributes.uv.needsUpdate = true;
}

4.3 顶点着色器中的 UV 控制

通过自定义着色器实现复杂效果:

// 顶点着色器
varying vec2 vUv;
uniform float time;void main() {vUv = uv + vec2(time * 0.1, 0.0);gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

4.4 法线映射与 UV 的关系

法线贴图依赖 UV 坐标确定法线方向:

const material = new THREE.MeshStandardMaterial({normalMap: normalTexture,normalScale: new THREE.Vector2(0.5, 0.5) // 控制法线强度
});

4.5 光照烘焙与 UV

在 Blender 中烘焙光照后导出带有uv2的模型:

// 在Three.js中启用第二组UV
geometry.setAttribute('uv2', new THREE.BufferAttribute(uv2Array, 2));
material.aoMap = aoTexture;
material.aoMap.uvTransform = new THREE.Matrix3().fromArray(uvTransform);

5. 常见问题解决方案

5.1 纹理拉伸问题

  • 成因:UV分布不均匀

  • 解决方案:

    1. 使用更密集的几何细分
    2. 制作UDIM纹理集
    3. 应用三平面投影

5.2 接缝处理技巧

  • 原因:UV 坐标不连续或导出时顶点 UV 重复。

  • 解决方案

  1. 在 Blender 中使用Smart UV Project重新展开。

  2. 导出时勾选Merge by Distance选项。

  3. 在 Three.js 中调整 UV 坐标:

    const uvArray = geometry.attributes.uv.array;
    for (let i = 0; i < uvArray.length; i += 2) {uvArray[i] = uvArray[i] % 1;uvArray[i + 1] = uvArray[i + 1] % 1;
    }
    geometry.attributes.uv.needsUpdate = true;
    

6. 性能优化建议

  1. 合并UV集:将多个材质的UV合并到同一纹理图集
  2. 使用压缩纹理格式:推荐 KTX2或者Basis Universal 格式
  3. 避免动态UV更新:静态几何体应冻结UV缓冲区
  4. LOD策略:根据距离切换UV细节层级

7. 调试工具推荐

  1. UV检查材质
const debugMaterial = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('uv-grid.png')
});
  1. Three.js编辑器:可视化UV展开
  2. Blender + Three.js导出:专业级UV编辑流程

结语

UV映射是连接3D模型与2D纹理的核心桥梁。通过深入理解Three.js的UV实现机制,开发者可以创建更复杂的材质效果、优化渲染性能,并解决实际项目中的各种纹理映射难题。实际开发中需注意:纹理尺寸需为2的幂、不同材质类型对UV的支持差异、移动端性能优化等。建议结合WebGL着色器编程,进一步挖掘UV系统的潜力。

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

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

相关文章

代码复用与分层

1. 代码复用与分层 函数&#xff1a;将常用的代码块封装成函数&#xff0c;提供自己或者团队使用。 库&#xff1a;将代码打包成静态或者动态库&#xff0c;提供出来一个头文件供自己或者团队使用。比如stm32中的HAL库。 框架&#xff1a;通常实现一个完整的系统性的代码&am…

人脸真假检测:SVM 与 ResNet18 的实战对比

在人工智能蓬勃发展的当下&#xff0c;人脸相关技术广泛应用于安防、金融、娱乐等诸多领域。然而&#xff0c;随着人脸合成技术的日益成熟&#xff0c;人脸真假检测成为保障这些应用安全的关键环节。本文将深入探讨基于支持向量机&#xff08;SVM&#xff09;结合局部二值模式&…

类加载器, JVM类加载机制

1.类加载器 Java里有如下几种类加载器 1.引导类加载器 负责加载支撑JVM运行的位于JRE的lib目录下的核心类库&#xff0c;比如rt.jar、charsets.jar等 2.扩展类加载器 负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包 3.应用程序类加载器 负责加载Class…

Hadoop 2.x设计理念解析

目录 一、背景 二、整体架构 三、组件详解 3.1 yarn 3.2 hdfs 四、计算流程 4.1 上传资源到 HDFS 4.2 向 RM 提交作业请求 4.3 RM 调度资源启动 AM 4.4 AM运行用户代码 4.5 NodeManager运行用户代码 4.6 资源释放 五、设计不足 一、背景 有人可能会好奇&#xf…

串口屏调试 1.0

http://wiki.tjc1688.com 先把商家的链接贴过来 淘晶驰T1系列3.2寸串口屏tft液晶屏显示屏HMI触摸屏超12864液晶屏 这是主包的型号 打开这个玩意 有十个基本的功能区 新建工程 在界面的右边&#xff0c;指令一定要写在page前面&#xff0c;这里的波特率等等什么的都可以…

《设计数据密集型应用》——阅读小记

设计数据密集型应用 这本书非常推荐看英语版&#xff0c;如果考过了CET-6就可以很轻松的阅读这本书。 当前计算机软件已经不是单体的时代了&#xff0c;分布式系统&#xff0c;微服务现在是服务端开发的主流&#xff0c;如果没有读过这本书&#xff0c;则强力建议读这本书。 …

【SpringMVC】详解cookie,session及实战

目录 1.前言 2.正文 2.1cookie与session概念 2.2返回cookie参数 2.3设置session 3.小结 1.前言 哈喽大家好吖&#xff0c;今天继续来给大家来分享SpringMVC的学习&#xff0c;今天主要带来的是cookie与session的讲解以及通过postman和fiddler来实战&#xff0c;废话不多…

令狐冲的互联网大厂Java面试之旅

场景描绘&#xff1a;互联网大厂Java面试 在某个阳光明媚的上午&#xff0c;令狐冲来到了风清扬所在的互联网大厂&#xff0c;准备迎接他的Java开发工程师面试。风清扬是一位以严谨和深厚技术功底著称的面试官&#xff0c;令狐冲稍显紧张&#xff0c;但他相信自己的准备。 第…

照片to谷歌地球/奥维地图使用指南

软件介绍 照片to谷歌地球/奥维地图是一款由WTSolutions开发的跨平台图片处理工具&#xff0c;能够将带有GPS信息的照片导入Google Earth&#xff08;谷歌地球&#xff09;或奥维地图。该软件支持Windows、Mac、iOS、Linux和Android系统&#xff0c;无需下载安装&#xff0c;直…

客户端建立一个连接需要占用客户端的端口吗

客户端建立TCP连接时需占用本地端口&#xff0c;具体机制如下&#xff1a; 一、端口占用的必要性 四元组唯一性‌ TCP连接通过‌源IP、源端口、目标IP、目标端口‌四元组唯一标识。客户端发起连接时&#xff0c;必须绑定本地端口以完成通信标识。 动态端口分配‌ 客户端操作…

【生存技能】ubuntu 24.04 如何pip install

目录 原因解决方案说明 在接手一个新项目需要安装python库时弹出了以下提示: 原因 这个报错是因为在ubuntu中尝试直接使用 pip 安装 Python 包到系统环境中&#xff0c;ubuntu 系统 出于稳定性考虑禁止了这种操作 这里的kali是因为这台机器的用户起名叫kali,我也不知道为什么…

智能时代下,水利安全员证如何引领行业变革?

当 5G、AI、物联网等技术深度融入水利工程&#xff0c;传统安全管理模式正经历颠覆性变革。在这场智能化浪潮中&#xff0c;水利安全员证扮演着怎样的角色&#xff1f;又将如何重塑行业人才需求格局&#xff1f; 水利工程智能化转型对安全管理提出新挑战。无人机巡检、智能监测…

TDengine 在智能制造中的核心价值

简介 智能制造与数据库技术的深度融合&#xff0c;已成为现代工业技术进步的一个重要里程碑。随着信息技术的飞速发展&#xff0c;智能制造已经成为推动工业转型升级的关键动力。在这一进程中&#xff0c;数据库技术扮演着不可或缺的角色&#xff0c;它不仅承载着海量的生产数…

微调ModernBERT为大型语言模型打造高效“过滤器”

ModernBERT&#xff08;2024 年 12 月&#xff09;是最近发布的小型语言模型&#xff0c;由 Answer.AI、LightOn 和 HuggingFace 共同开发。它利用了现代优化技术&#xff0c;如用于 8,192 token 上下文窗口的 RoPE 和 GeGLU layers&#xff0c;在保持效率的同时提升性能。jina…

电网拓扑分析:原理与应用

在现代电力系统中&#xff0c;电网拓扑分析是一项至关重要的技术&#xff0c;它为电力系统的安全、稳定和高效运行提供了坚实的基础。电网拓扑描述了电力系统中各元件&#xff08;如发电机、变压器、输电线路、负荷等&#xff09;之间的连接关系&#xff0c;通过拓扑分析&#…

OSPF案例

拓扑图&#xff1a; 要求&#xff1a; 1&#xff0c;R5为ISP&#xff0c;其上只能配置IP地址&#xff1b;R4作为企业边界路由器&#xff0c; 出口公网地址需要通过PPP协议获取&#xff0c;并进行chap认证 2&#xff0c;整个OSPF环境IP基于172.16.0.0/16划分&#xff1b;…

2D横板跳跃游戏笔记(查漏补缺ing...)

1.Compression&#xff08;压缩质量&#xff09;&#xff1a;可以改为None&#xff0c;不压缩的效果最好&#xff0c;但占用内存 2.Filter Mode&#xff08;过滤模式&#xff09;&#xff1a;可以选择Point&#xff08;no filter&#xff09; 3.Pixels Per Unit&#xff1a;是…

MAD-TD: MODEL-AUGMENTED DATA STABILIZES HIGH UPDATE RATIO RL

ICLR 2025 spotlight paper 构建能够在少量样本下学习出优良策略的深度强化学习&#xff08;RL&#xff09;智能体一直是一个极具挑战性的任务。为了提高样本效率&#xff0c;近期的研究尝试在每获取一个新样本后执行大量的梯度更新。尽管这种高更新-数据比&#xff08;UTD&am…

Dia浏览器:AI驱动浏览网页,究竟怎么样?(含注册申请体验流程)

名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。——苏轼《稼说送张琥》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、Dia浏览器简介1. 什么是Dia浏览器2. 开发背景与公司简介3. 与传统浏览器的区别 …

SSL/TLS 证书与数字签名:构建互联网信任的详解

在浩瀚的数字世界中&#xff0c;信任是安全通信的基石。当我们通过浏览器访问一个 HTTPS 网站、进行在线支付&#xff0c;或者下载一个重要的软件更新时&#xff0c;我们如何能确信自己正在与合法的、未被仿冒的对方进行交互&#xff1f;我们又如何能保证传输的数据没有被中途窃…