专栏首页郭先生的博客three.js UV映射简述

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的使用,下一节说一说关于它的小应用。

转载请注明地址:郭先生的博客

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)

    通读完上一篇博文中提及的教程,觉得应该搞个大作业巩固一下所学的知识,想起刚上映的漫威宇宙第三阶段收官之作《蜘蛛侠·英雄远征》,于是决定仿一个MARVEL的片头动...

    大史不说话
  • 现在做 Web 全景合适吗?

    villainhr
  • 现在做 Web 全景合适吗?

    Web 全景在以前带宽有限的条件下常常用来作为街景和 360° 全景图片的查看。它可以给用户一种 self-immersive 的体验,通过简单的操作,自由的查...

    企鹅号小编
  • 用three.js渲染上海外滩模型

    天空的实现有多种方式,最常见的是一个包围全部的天空球,通常是UV球,也叫经纬球,其UV很方便映射到一张天空图片,比如:

    Jean
  • Shader基础技巧整理

    自从接触了shader之后我便深深得爱上了它,因为它独特的编程思考方式冲击着我这十几年的惯性认知。 在向各位大佬学习的过程中,每学到一个新的技巧,我都不禁感叹:...

    白玉无冰
  • 解剖 WebGL & Three.js 工作原理

    本文主要通过两方面来解剖 WebGL & Three.js :WebGL背后的工作原理和以Three.js为例,讲述框架在背后扮演什么样的角色,希望对大家学习有...

    万技师
  • BAT 要的是什么样的前端实习生?

    villainhr
  • three.js 制作机房(上)

    three.js使用的人太少了,一个博文就几百个人看,之前发js基础哪怕是d3都会有几千的阅读量,看看以后考虑说一说d3了,哈哈。吐槽完毕回归正题。前几天郭先生...

    郭先生的博客
  • Web H5视频滤镜的“百搭”解决方案——WebGL着色器

    视频滤镜,顾名思义,是在视频素材上duang特效的一种操作。 随着H5页面越做越炫酷的趋势,单一的视频播放已经不能满足我们的需求,视频滤镜在Web页面上的应用越...

    WendyGrandOrder
  • three.js 实现火花特效

    上周末刚在原神里抽到了“火花骑士”可莉,于是就心血来潮,想用three.js来实现一种火系的特效,不是炸弹的爆炸,而是炸弹爆炸后在草上留下的火花效果

    落落落洛克
  • ECCV 2020 | 基于分割一致性的单目自监督三维重建

    本文主要从二维图像及其轮廓的集合中,学习一个自监督的、单视图的三维重建模型,预测目标物体的3D网格形状、纹理和相机位姿。提出的方法不需要3D监督、注释的关键点、...

    计算机视觉
  • 一张照片获得3D人体信息,云从科技提出新型DenseBody框架

    多年以来,如何从单一图像估计人体的姿势和形状是多项应用都在研究的问题。研究者提出不同的方法,试图部分或者联合地解决此问题。本文将介绍一种端到端的方法,使用 CN...

    机器之心
  • Three.js - 走进3D的奇妙世界

    随着人们对用户体验越来越重视,Web开发已经不满足于2D效果的实现,而把目标放到了更加炫酷的3D效果上。Three.js是用于实现web端3D效果的JS库,它的...

    宜信技术学院
  • three.js 着色器材质之纹理

    今天郭先生说一说如何在three.js着色器中添加纹理,先看看今天要完成的效果,在线案例请点击着色器纹理。

    郭先生的博客
  • Three.js - 走进3D的奇妙世界

    随着人们对用户体验越来越重视,Web开发已经不满足于2D效果的实现,而把目标放到了更加炫酷的3D效果上。Three.js是用于实现web端3D效果的JS库,它的...

    用户7118204
  • OpenGL ES 相机 LUT 滤镜

    什么是 LUT ? LUT 是 Look Up Table 的简称,称作颜色查找表,是一种针对色彩空间的管理和转换技术。

    字节流动
  • NDK OpenGL ES 3.0 开发(十八):相机 LUT 滤镜

    什么是 LUT ? LUT 是 Look Up Table 的简称,称作颜色查找表,是一种针对色彩空间的管理和转换技术。

    字节流动
  • 进阶渲染系列(七)——三向贴图(任意表面纹理化)【进阶篇完结】

    执行纹理映射的通常方法是使用网格中每个顶点存储的UV坐标。但这不是唯一的方法。有时,没有可用的UV坐标。例如,当使用任意形状的过程几何时。在运行时创建地形或洞穴...

    放牛的星星
  • 随便聊聊水面效果的2D实现(一)

      一直想随便写写自己关于水面效果2D实现的一些了解,可惜各种原因一直拖沓,幸而近来有些事情终算告一段落,自己也有了一些闲暇时间,于是便有了这篇东西 :)

    用户2615200

扫码关注云+社区

领取腾讯云代金券