three.js UV映射简述
今天郭先生来说一说uv映射,什么是uv映射?uv映射就是将二维的贴图映射到对象的一个面(或者多个面)上。说到这个问题,我们就不得不了解一下Geometry的点、面和uv的结构。我们以BoxGeometry为例。
new THREE.BoxGeometry(20, 20, 20); //创建一个边长为20的正方体。
捕获2222221.PNG
我们可以发现一个长方体由八个点和12个三角面组成,就拿0-1-2-3这个面来看,两个面的face3分别是:
捕获444444444.PNG
也就是faces0对应顶点0-2-1,faces1对应顶点2-3-1,这个顺序可以记一下。
Face3里面有一个很重要的属性materialIndex,这个索引是当使用数组材质的时候指定使用哪个材质作为当前Face3的材质,对于BoxGeometry来说,前面的两个三角面的materialIndex为0,后面的两个为1,上面两个为2,下面的两个为3,左面两个为4,右面的两个为5,即使数组中只有两个材质,那么也是按照这个顺序(既只显示前后两个面)。
再说说uv映射,一个纹理图的原点在其左下方,坐标为(0,0),右下方为(1,0),左上方为(0,1),右上方为(1,1)
未标题1.png
在Geometry中,faceVertexUvs决定了uv映射的关系,如下如就是uv映射关系
捕获555555555.PNG
我们可以看出第一个三角面对应一个二维点数组new THREE.Vector2(0,1), new THREE.Vector2(0,0), new THREE.Vector2(1, 1),他默认将face30的第一个点对应纹理的第一个点,face30的第二个点对应纹理的第二个点,,face30的第三个点对应纹理的第三个点,最后的到的如下图,
捕获111111111.PNG
我们稍微改变一下new THREE.Vector2(0.25,0.75), new THREE.Vector2(0.25,0.25), new THREE.Vector2(0.75, 0.75),看看会发生什么,
捕获77777777.PNG
就变成这个样子了,原因看下图
未标题2.png
接下来我们以数组材质的方式和单张纹理图的方式说一下如何将6个面赋予不同的贴图(默认六个面是相同的贴图)。
1. 数组材质的方式
这种方法十分简单,只需要创建6个贴图材质即可
var geom = new THREE.BoxGeometry(20, 20, 20);
var mate1 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/kaola.png')});
var mate2 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/mao.png')});
var mate3 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/quan.png')});
var mate4 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/shi.png')});
var mate5 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/tuboshu.png')});
var mate6 = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/xiongmao.png')});
var mesh = new THREE.Mesh(geom, [mate1, mate2, mate3, mate4, mate5, mate6]);
scene.add(mesh);
捕获2222222.PNG
2. 单张纹理图
如下图所示,将六个面的纹理贴图绘制到一张
捕获1212122.PNG
var geom = new THREE.BoxGeometry(20, 20, 20);
var mate = new THREE.MeshBasicMaterial({map: new THREE.TextureLoader().load('/static/images/animal/an-uv.png')});
var mesh = new THREE.Mesh(geom, mate);
geom.faceVertexUvs[0][0] = [new THREE.Vector2(0,1), new THREE.Vector2(0,0.66), new THREE.Vector2(0.5, 1)];
geom.faceVertexUvs[0][1] = [new THREE.Vector2(0,0.66), new THREE.Vector2(0.5,0.66), new THREE.Vector2(0.5, 1)];
geom.faceVertexUvs[0][2] = [new THREE.Vector2(0.5,1), new THREE.Vector2(0.5,0.66), new THREE.Vector2(1, 1)];
geom.faceVertexUvs[0][3] = [new THREE.Vector2(0.5,0.66), new THREE.Vector2(1,0.66), new THREE.Vector2(1, 1)];
geom.faceVertexUvs[0][4] = [new THREE.Vector2(0,0.66), new THREE.Vector2(0,0.33), new THREE.Vector2(0.5, 0.66)];
geom.faceVertexUvs[0][5] = [new THREE.Vector2(0,0.33), new THREE.Vector2(0.5,0.33), new THREE.Vector2(0.5, 0.66)];
geom.faceVertexUvs[0][6] = [new THREE.Vector2(0.5,0.66), new THREE.Vector2(0.5,0.33), new THREE.Vector2(1, 0.66)];
geom.faceVertexUvs[0][7] = [new THREE.Vector2(0.5,0.33), new THREE.Vector2(1,0.33), new THREE.Vector2(1, 0.66)];
geom.faceVertexUvs[0][8] = [new THREE.Vector2(0,0.33), new THREE.Vector2(0,0), new THREE.Vector2(0.5, 0.33)];
geom.faceVertexUvs[0][9] = [new THREE.Vector2(0,0), new THREE.Vector2(0.5,0), new THREE.Vector2(0.5, 0.33)];
geom.faceVertexUvs[0][10] = [new THREE.Vector2(0.5,0.33), new THREE.Vector2(0.5,0), new THREE.Vector2(1, 0.33)];
geom.faceVertexUvs[0][11] = [new THREE.Vector2(0.5,0), new THREE.Vector2(1,0), new THREE.Vector2(1, 0.33)];
scene.add(mesh);
结果同上图。这里faceVertexUvs数组的第一维度是材质的索引,第二维度才是面的uv贴图映射关系,由于只有一个材质,所以这里的索引都是0。
这节说了一下uv的使用,下一节说一说关于它的小应用。
转载请注明地址:郭先生的博客
- 使用 Serverless 进行 AI 预测推理
- Dubbo学习1-Hello world
- 用线性判别分析 LDA 降维
- Bagging 简述
- 机器学习中常用评估指标汇总
- 用 Grid Search 对 SVM 进行调参
- PCA 的数学原理和可视化效果
- 用 Pipeline 将训练集参数重复应用到测试集
- 什么是 ROC AUC
- SSE(Server-sent events)技术在web端消息推送和实时聊天中的使用
- 详解 Stacking 的 python 实现
- RESTful接口设计原则和优点
- 用 Doc2Vec 得到文档/段落/句子的向量表达
- 手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android 动态加载二维码视图生成快照的示例
- 使用Mybatis反配置逆向工程,错误eg:This is not a MyBatis Generator Configu
- DTS(数据库传输服务)
- R语言关联挖掘实例(购物篮分析)
- 用R语言中的神经网络预测时间序列:多层感知器和极限学习机
- 基于R语言股票市场收益的统计可视化分析
- Mac系统R语言升级后无法加载包报错 package or namespace load failed in dyn.load
- 如何从xml文件创建R语言数据框dataframe
- Matlab马尔可夫链蒙特卡罗法(MCMC)估计随机波动率(SV) 模型
- 如何从xml文件创建R语言数据框dataframe
- R语言POT超阈值模型和极值理论EVT分析
- R语言使用灰色关联分析(Grey Relation Analysis,GRA)中国经济社会发展指标
- R语言中的模拟过程和离散化:泊松过程和维纳过程
- R语言Lee-Carter模型对年死亡率建模预测预期寿命
- R语言有极值(EVT)依赖结构的马尔可夫链(MC)对洪水极值分析