在 上篇 中铺垫了顶点和三角形这些基本概念。稍微回顾一下:顶点是模型的基本数据单位;顶点组成三角形,三角形组成面,面组成模型。 有了这些构成模型的数据框架后,就可以向里面填充数据了。在上篇中讲过了UV,然后在这篇,讲讲另外两个十分重要的数据:法线、顶点色。
【头图为Substance Painter示例文件】
在讲解法线时,会无法回避地需要一些线性代数的概念,但也绝不会那么深奥——也就是向量的基本定义和概念。
如果有想再复习一下的读者,可以参考这个关于线性代数的视频——by:3B1B
法线,是一个基于立体几何的数学概念,扒一下wiki定义的话:
三维平面的法线是垂直于该平面的三维向量
这是从几何上的定义,但是在计算机渲染/建模的语境下,可以从另一个角度来理解法线——法线是用来从数学角度上表达平面朝向的向量。
在计算机渲染中,一个基本任务就是计算光线反射或折射的方向,在光线反射的过程中,就需要知道光线抵达平面的朝向(想象一下镜子)。此时,从数学上讲,法线就可以帮助我们计算光的反射方向。
如果往回一步,退到纯粹的几何,一个三角形(平面)的法线可以用公式计算出来的。
考虑到有这个公式,那么数学上的法线其实不含任何的“新”信息,因为其实都可以用现有顶点信息算出来。如果不太能理解这个推论,可以想一下这两句话:【在1987年时我23岁】和【我出生于1964年】。这两句话对于年龄这个事实来说是一样的,只不过之间差一个换算。
既然法线不含有任何“新”信息,那么为什么它在计算机图形/建模/渲染等等这些技术领域中还如此重要呢?有一个角度是:这是储存换算力的一种代偿策略,说白了就是能存下来的信息就没必要重新再算一遍。
但是!法线在建模和渲染中最重要的作用倒也不是这个。下面慢慢讲:
之前(在上篇中)也讲到,模型面的基本单位都是三角形。这种策略的优势之一是每个三角形都是平的,在渲染时会避免很多问题。可是阿喀琉斯还有一个脚后跟儿呢,这种策略的“致命”问题就是——它无法建立曲面。
这里就会有读者说了:欸不对啊,又不是所有的游戏都是《Minecraft》,其他游戏里面又大又圆的模型有的是啊!
对,没错,但是如果三角形足够小,就可以用一个个平面堆出“曲面”。
从上图就可以看出,在CG建模中,所有的“曲面”其实都是由大量的三角形(平面)组成的。
文章中提到的基于网格(Mesh)/三角形的建模策略只是无数策略中的一种。以数理几何曲线/曲面为基础的策略也存在——基于贝塞尔曲线的建模策略(两种策略可以粗略地用位图和矢量图进行类比)。但是咱们今天就不展开了,之后希望有时间讲到。
此时三角形的数量和曲面的精细度,和像素数和屏幕的表现可以进行类比,用来堆砌曲面的三角形越多,曲面就越”真实“。下面这张图可以清楚地看到三角形数量对于视觉效果的影响:
可是之前也提到过三角形(顶点)计数对于计算机在处理模型的性能消耗(包含但不限于容量、处理速度等等)粗略来看是一个线性的正相关关系。所以伟大的前辈就开始考虑有没有办法缓解这个问题。
此时,就可以具体地聊聊CG领域中的法线了。它派生于几何法线,但也有一些不同。
为了方便,下文说的法线将直接指代“CG领域中的法线”,如果需要退回到数理上的平面法线,会明确地由“几何法线”来指代。
中间的球体视觉上蛮接近右侧的球体,但是它和左侧球体的顶点计数是一样的——右侧球体的【1/16】,做到这一点的功臣就是法线。当然,眼尖的读者能明显地看出中间和右面球微妙的区别,这也是只使用法线的弊端,有什么替代的技术吗?在后面一点会提到。
此时理解的关键点是:渲染时所用的法线不一定是几何法线。这体现了计算机空间中的一个优势,这里可以时不时的扭曲一些物理规则——让一个平面“看上去”是一个曲面。
从另一个角度看,之前也说过:“法线是用来从数学角度上表达平面朝向的向量。” 如果反过来想,我们可以反过来利用这一关系:“通过调整法线来‘操纵’这个面的朝向。”
然而,一个三角形有且只有三个顶点,每个顶点只有一个法线,那么这个面只能有三个法线吗?
之前也说过,需要法线的原始目的是要计算光线的在平面上的反射,但是我们不能只考虑光线射中顶点的可能,我们也要考虑光线在这个面上其他位置(而不在顶点上)的情况。
如果需要位于这个三角形上,却不是顶点的其他位置的数据时,就要进行一个“插值”的操作。简单来说:就是根据所需位置对顶点的距离求加权平均值,离哪个顶点越近,顶点的权重就越大。如果这个点恰好在三角形的重心上面,那么这个值就是恰好三个顶点上的平均值。 通过插值这一工具,就可以在面上任意一个位置计算出一根法线,以至于可以认为是法线在面上的分布是连续的。
在下图中,只有标号为n0、n1、n2的三根深绿色的法线是需要制作者进行制作的。其余橙色的法线和无数的连续法线都可以通过GPU计算出来。基于这个前提去渲染,就可以得出“看上去是曲面的平面”了。
当然,只这么看相当的抽象,咱们看下下面这个具体的例子:
左上侧有若干成对的蓝色法线,它们体现为下侧一条条的棱。然而在右上侧的情况下,我们通过调整法线并通过插值,令所有法线(粉蓝作为整体)都是连续的,这就使得右下角的结果从视觉上也是连续的,原本左下的一条条棱消失了。
可是严格来说,插值出来的法线是由数学决定的。换句话说,从制作者的角度看其实没法直接操纵它们(那些粉色法线)。
十分想深入地讨论法线贴图的细节,还需要切线、切线空间、压缩等等,今天按下不表,之后希望有机会展开。
法线贴图就能让制作者在制作模型的时候不仅仅操作顶点上的法线,还可以更加精细地“操控”一根根法线(当然也不是字面意思上的一根根调整)。让制作出的模型可以有高得多的细节。
只使用法线的话,在视觉上还有很多东西无法处理。如果上面这张图还是有些看不出来的话,咱们就再弄一张稍微夸张点的图:
在剪影的视角下,低三角形计数的两个球无可遁形——可以清晰地看出中间那个球和右侧球的不同。右侧剪影的边界仍然是“圆滑”的,可是中间剪影的边界也能看出是一节节的。
这就是仅使用法线的一个缺憾了,仅使用法线无法改变模型的剪影。法线只能改变模型表面的效果,如果一个“假曲面”更多由侧面观察,而不是从正面的话,那么法线此时帮不了忙。有没有其他的解决方案呢?
上面这个模型只是一个球——从左侧可以看出来,但是右侧的剪影很明显经过了修改。当然,这个效果只通过了材质渲染,没有重新建模。
这种仅使用材质就可以对剪影进行修改的技术就是:曲面细分(Tessellation)加上一张位移(Displacement Map)或者高度贴图(Height Map)。如果要说的很细的话,还需要辨析VTG流程,留一个坑在这儿。
VTG流程是【Vertex-Tessellation-Geometry】管线流程的简称(不同API中名称不尽相同)。大体来说,这就是描述一个CG模型在显卡中怎么处理的。但是,近期这个流程被UE5所支持的MeshShader流程挑战了,咱们拭目以待——希望之后有机会讲讲MeshShader。
简而言之,显卡可以通过一定的操作将模型进行再切分,并且对切分后的模型再通过贴图进行修改。因为修改了模型本身,那么自然就可以修改剪影了。这种技术虽然本身比不使用开销提高了不少,然而曲面细分流程可以通过程序角度上优化,所以总体来说,还是比往游戏里放一个极高精的模型开销低。
这个概念放在法线后其实可能会显得有些头重脚轻,但是这也是十分重要且有趣的一个概念。
顶点色和法线不同,它没有特别深厚的数学基础,而且顾名思义,顶点色就是顶点的颜色。
说的再具体一点,顶点色就是在每个顶点储存的一个四通道(RGBA)颜色。同样,和法线的情况类似,对于模型上的非顶点位置,会用上面提到的“重心插值”算法进行“填充”。于是使用顶点色就可以将一整个模型上色。
在游戏行业的“上古时代”(千禧年左右或更早),那时顶点色还是美术表现本身关键一环。因为那时候无论是从制作角度还是性能角度上看,贴图的使用没有今天这么宽松。然而,即使到现在,顶点色仍有很多应用。例如这样:
无论何时,节省贴图的数量都是好的。看到上面最右面的两张图,贴图的纹理本身相同,只有色相/明度等颜色不同,那么就可以利用顶点色进行优化了。如果只使用一张中性色相的贴图,然后在不同模型上使用不同的顶点色进行混合,最终就可以得出不同的结果。
想象一下,如果一个大场景中同时拥有高温和雪地的区划,并且都有数量可观的木质材料。此时从美术角度上,就可能有需求要高温区的木头颜色偏暖,雪地区颜色偏冷。对于这种需求,在实际开发时,就往往会使用上述流程进行优化。木质材质只有一套,同时借用顶点色进行混合。诚然,这只是一种方案,也有它的弊端,这无非是一种可用的流程。
然而在现代开发语境下的顶点色,除了优化美术的一些需求,还有另一种思路。那就是用来传递一些额外的信息,其中比较常用就是模型本身的区划。
在实际制作时,一个模型往往因为各种不同的原因需要被进行“分割”。例如需要使用不同的材质。此时最直接的想法就是实际上将这个模型字面意义上分割成若干部分,但是这样的话制作上会变麻烦,性能上也会有一些损失。
此时如果利用顶点色,就会像上图。模型仍然是完整的,将不同的模型区划涂上不同的顶点色即可。同时只需要令处理模型的工具清楚不同颜色代表不同区划就可以了。
而且顶点色作为颜色的数值,不像通常图像中会经过压缩,所以理论上,这种区划允许的区间数量高达一千六百万。自然这仅是理论上的,并且开发者往往会通过这特点玩“花活”,传输一些其他种类的数据之类的。
通过上下这两篇文章,大致详解了模型的基本架构,以及UV、法线、顶点色这些基于模型本身的“额外”数据。当然,在实际开发和制作中,一个模型上会根据各个项目流程不同,添加很多其他的数据。而且根据不同的文件结构,可以存储的数据也不尽相同。例如原生的obj文件格式就不能存储原生的顶点色。
模型本身就像这样,会有很多数据,但是只有这些是不够的。不同的材质、贴图甚至渲染引擎都会有结果显著的影响,之后就会专注这些继续慢慢展开。
虽然这里主要是科普一些CG相关的知识,但是毕竟我现在还是一个独立开发者,这里做一些小小的广告!~
Itch.io, 主力的游戏发布,但是考虑到国内用户,在B博上也会有对应的更新。 B站,主要是当作B博去用,会有一些现在开发游戏的小更新什么的,未来稳定后可能会有一些视频之类的。
评论区
共 15 条评论热门最新