3D模型贴图算法归纳讨论,以及OpenGL渲染器中的数据格式——篇1:模型展开算法与UV贴图

作者:林楚堑

【更新中】


前言

算法or设计行业的老手们可以跳过了,曾经我作为一名刚刚了解贴图的小白的时候真的走了很多很多很多弯路。我相信很多人刚刚接触各类软件的贴图功能的时候一定有跟我一样的各种问题与疑惑。
什么是贴图?
为什么贴图的形状总会变形呢?
有没有什么办法可以贴成每个地方的纹理团都一样大的呢?
为什么Minecraft等很多游戏中的材质包,渲染得又快立体感又强呢?
为什么一张图片进了显卡就变立体的呢?
在经过大量的度娘或谷歌后,几乎每一篇文章一上来就啪一脸的UV、UVW、XXX展开。。。
呸!!!
都不说清楚UV是什么鬼,哪来的展开?!


.

一、首先思考原理

地球是球体,如何在一张纸上画出世界地图?

在这里插入图片描述
<图片选自网络>

如果你在心里嘀咕:“不就是这么画出来的么?” 你再问问自己:“这么是怎么?你能把每一个细节说出来么?上北下南左西右东,一定很简单。北极极点向西平移1米的位置,要画在哪里?本初子午线向东1米的经线,又要怎么画?”
思考到这里,你有没有发现,赤道上的东西1米宽度与极点上的东西1米的宽度,画在纸上完全不一样宽!格陵兰岛跟中国看起来居然差不多大?!?!然是实际是格陵兰岛216.6万平方千米,中国960万平方千米。这是地图画错了么?还是我们眼睛有毛病?!

看到这里,其实你已经开始入门了,我相信你已经看出了画地图的真谛。
这就是一个从3D到2D转换的过程,而且不论我们怎么努力,
一个曲面想要画到平面上,肯定存在着畸变!!!

.

二、贴图

1. 是什么?为什么?怎么做?

任何一个问题拿到手,先解决这三个大麻烦。
贴图是什么
将一个二维的图形,按照一定规律贴合到三维的平面或者曲面上,这就是贴图。就好像我们玩的贴纸一样,或例如身体彩绘、纹身、笔记本贴膜等等。
为什么这么做呢
在计算机中,纯三维的数字模型,没有色彩的信息(3MF、3DM等一些牛逼的除外)只有形状,也就是白模。如果需要一些纹理材质的效果,例如衣物、头发、皮肤、刀疤,这时候就需要用到贴图功能了。它的存在可以节省大量的三维建模占用的计算机资源,而让用户在享用三维模型的时候,也能通过图片,近似地感受到创作者想要传达的立体信息。
那要怎么贴呢
贴图就是一个把世界地图重建成地球仪的过程,与上一章说的绘制地图的过程正好相反。一个纯白色塑料球,按照一定的规律,把世界地图一块块地贴上去,就成了地球仪。这就是贴图的最直观也是最常用的做法——地球仪的制作。还有不太理解的,买几个地球仪回家,把贴纸撕下来再贴上,反复几遍就懂了。

2. 要点难点

在这里插入图片描述
<图片选自网络>

所以我们不难发现先,贴图是一个二维到三维重建的过程,通过对二维图片的折叠、弯曲、拉伸,像折纸那样,折成了一个三维物体。
同理,从刚刚的地图的例子中可以看出:任何一个二维图像贴到曲面上,不可能没有变形!!!不可能没有接缝!!!也不可能没有折痕!!!
你说:“我看着感觉没变形啊!” 那只是你的眼神不太好而已。醒一醒!别活在童话世界里,大家都是成年人或者是准成年人了。


.

三、图片的坐标——UV

全世界的科学家,穷尽几代人几个世纪,只为了解决:如何欺骗你的眼睛,让你感觉没变形同时又有立体感。进而延伸出了当今的各个学科和各种工作岗位:计算机图像处理、特征点识别、人工智能等等;3D建模设计师,平面设计师等等,
这篇我们先来讨论两种最传统简单的贴图方法:投影、拉伸扭曲(UV贴图)
其他的方法例如特征点识别、图像分割拼接、泊松形变等,后续再慢慢讨论。

1. 万事开头难,只要有例子:

一张图片,和一个正方体。
牺牲一点个人形象来举个栗子,这是一个正方体的两个面,贴好了一张图片。这2个面包含了4个三角形,共6个顶点。6个顶点上,已经清楚标识除了对应的UV值,和其对应的像素坐标。
在这里插入图片描述
思路:
若想让电脑知道,一个3D的模型怎么贴图片。就需要告诉电脑:每个三角形的顶点对应在图片上的具体坐标位置——UV坐标。
UV坐标:
UV坐标不同于像素坐标,图片的最宽处,U = 1,图片的最高处 V = 1。也就是说,即使一张图片的像素是:1*1000000000,这张图的UV坐标在右上角的位置依然是(1,1)。所以,在编写程序的时候,一定会遇到UV值的换算问题,具体为:
U = 像素X / 图片宽;
V = (图片高 - 像素Y) / 图片高。

如何告诉电脑,3D模型上每个点的UV坐标?
大家一定拆过包装盒,没拆过的就去拆一个再继续看。拆完后,我们会发现,任何一个3D模型,都是可以像包装盒那样给拆开的,包括球体。因为他们都是三角形。同通俗点的话说就是——降维。把一个3D模型的表面,根据其原始拓扑关系割开,并平铺到一个平面上。这样,就有了一个可以和图片“对话”的方法了
在这里插入图片描述
<图片选自网络>

这时候,我们把图片拿过来贴在刚刚被 “降维打击” 的模型上,这样,每个模型的顶点和图片的像素坐标就有了一个对应关系。如图,左边就是刚刚的正方体模型,被拆开后的样子,右边就把这个拆开并铺平的正方体放在图片上。这样,正方体各个点的UV坐标值就有了。在这里插入图片描述
你们肯定会发现一个问题!图中标红的顶点,是同一个顶点,但是拥有不同的UV坐标。这是对的!!!
我们人类认为这两个顶点是一个顶点,但是在计算机中,这是两个三角形的两个不同的顶点,虽然坐标相同,当他们不是同一个点。所以,UV坐标对应的顶点,对于两个三角形而言,也是不同的。

2. UV展开

与其叫做UV展开,我更想把它叫做——“3D模型降维展平”,因为这个真的跟图片的UV一点关系都没有!!!网络上有太多展开的例子了,这里就不一一赘述了。放几个图片给大家直观感受一下。
任何3D模型,通过切割、压平的方式,化整为零地都可以变成一块块的独立的2D平面。

在这里插入图片描述
<图片选自网络>
在这里插入图片描述<图片选自网络>

3. UV数据格式实例

所以,看到这里,我想再进一步讲细致一些,计算机中常用的UV表达方式。同样,举个简单的例子直观感受一下:以OBJ格式的文件为例
v 31.5 47.1 0 # 点坐标 V_0
v 28.9 48.1 0 # 点坐标 V_1
v 28.9 48.1 50.7 # 点坐标 V_2
vt 0 0 # UV坐标 vt_0
vt 0.125 0 # UV坐标 vt_1
vt 0.125 2.25791 # UV坐标 vt_2
f 1/3 2/1 3/2 # 三角形 f_0

其中,三角形中记录的分别是 :点ID / UV点ID,所以,一个三角形包含着三个顶点和三个可能不同的UV值。当然这个三角形也可以写成 f 1/1 2/1 3/1,这样,三角形的三个点的UV值就是相同的,也就会出现一个纯色的三角形,因为整个三角形就只被贴上了图片的一个像素的一个颜色。


.

四、3D模型降维展平

我们在点二中已经提到过:任何一个二维图像贴到曲面上,不可能没有变形!
所以我们要学习与研究的就是:如何用更加理想的降维展平算法,让最后贴上模型的图片变形得最小,以至于我们感觉不到变形。
先从最简单的开始讲起

1. 平面投影贴图

在这里插入图片描述
顾名思义:投影。
任意一个曲面,拿到手后,选一个自己满意的角度,摆好在XY平面上(水平面),对所有三角形上的顶点遍历,删除所有Z值,这个平面就被平贴在地上了。举例:
原始点 :
A(14,14,588888)
B(14,0,20)
C(0,14,999999999999999999999)
根据方向 N(0,0,1)将这个三角形压平得到:
A(14,14,0)
B(14,0,0)
C(0,14,0)
这时候的三角形顶点坐标还是原始的坐标比例,遂对所有三角形的顶点做归一化,ABC三点坐标变换为如下:
A(1,1,0)
B(1,0,0)
C(0,1,0)
这时候,将ABC三个点的XY值区出来,定义为其对应的UV值,
A uv(1,1)
B uv(1,0)
C uv(0,1)
一张图片就会被压成正方形,并刚刚好贴满这个三角形,如下图左。如果你不想做归一化直接取为uv坐标,也可以,那么贴图的样子就会变成下图右。

在这里插入图片描述

2. 最小二乘法贴图

LSCM最小二乘法贴图,适用于曲率不大的曲面,对贴图的几何形状有较好的保持作用,但是对其花纹大小无法保证。

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值