【技术美术图形部分】纹理基础2.0-凹凸映射

目录

凹凸贴图/映射 bump mapping 概念

What——通过纹理的方法产生表面凹凸不平的视觉效果

Why——假装视觉效果,可以节省性能

How——高度贴图/法线贴图

1 高度贴图 height mapping

优点

缺点

2 法线贴图 normal mapping

2.1 模型空间

模型空间储存法线的优点

2.2 切线空间

切线空间储存法线的优点

2.3 世界空间

3 制作中如何使用法线贴图

3.1 实际中法线贴图的使用流程

3.2 法线烘焙

4 如何从高度图/纹理生成法线纹理

5 光照计算中的坐标转换


学习的教程

【技术美术百人计划】图形 1.3 纹理的秘密_哔哩哔哩_bilibili

辅助书籍参考

《Real-Time Rendering 3rd》提炼总结 -毛星云

《Unity Shader入门精要》-冯乐乐

上一篇博客链接

【技术美术知识储备】纹理基础1.0(结合RTR4)

1.0中过了一遍单张纹理如何应用——纹理管线的内容,2.0这部分继续来说说凹凸映射这部分内容。


凹凸贴图/映射 bump mapping 概念

涉及凹凸贴图,我在之前学习Games101的时候就写过一篇学习法线贴图的文章,内容很简单:GAMES101学习-法线贴图学习笔记

What——通过纹理的方法产生表面凹凸不平的视觉效果

凹凸贴图思想最早由Jim Blinn提出的,后来的Displacement Mapping(位移贴图),Norma Mapping(法线贴图),Parallax Mapping(视差贴图)和Relief Mapping(浮雕贴图)等都是基于凹凸贴图思想进行的改进,考虑的越来越全面,效果越来越好。

在一切之前,必须要提醒的是:

凹凸贴图(无论是高度贴图还是法线贴图),它不会改变模型的细节,只是增加光照互动的细节!因此,对于不受光照的物体,凹凸贴图并不起作用

原理

通过改变表面光照方程的法线,而不是表面的几何法线(法线贴图),或者对每一个待渲染的像素在计算光照之前加上一个高度图中找到的扰动(高度贴图),来模拟凹凸不平的效果。

目的

给光滑的表面在不增加顶点的情况下,仅使用一张纹理来修改模型表面的法线,增加一些凹凸的细节变化。

Why——假装视觉效果,可以节省性能

为什么要用凹凸贴图?

我认为很多时候,想要实现一些褶皱、波浪、碎石地面的凹凸不平等粗糙表面的效果,如果不需要精确到物理效果的细节,可以让他们只是视觉上看上去是真的,不需要真的做出来(节省性能)。那就很容易想到:可以用一个贴图去假装这样的视觉效果。

How——高度贴图/法线贴图

值得注意的是,《Unity Shader入门精要》里描述实现凹凸贴图bump mapping有以下两种方法:

  • 高度贴图 height mapping
  • 法线贴图 normal mapping

但正常发展认为Bump mapping思想是法线贴图的鼻祖,高度贴图是属于最早开始提出的一个实现凹凸效果的一种方法。

这两种表述方法并不影响凹凸贴图的学习,本篇博客采用《入门精要》里的描述方式进行接下来的叙述。

其次,很多地方在描述贴图时就指的是某张纹理(例如“切线空间的法线贴图一般是蓝色的...”这种 描述),也不必钻牛角尖,但本篇博客是将纹理map和贴图mapping分开描述了,提前说一下以免产生困惑。

1 高度贴图 height mapping

是实现凹凸效果的一种方法,比较古早了。使用高度图来实现凹凸贴图,高度图中储存的是强度值(intensity),表示表面的局部高度。例如《提炼总结》中列举的波浪高度纹理:

优点

很直观,它就是一张储存了256种不同黑白灰的灰度图,只告诉软件一件事:凸起还是凹陷。

颜色越白(灰度大于50%)表示越凸,越黑(灰度小于50%)表示越凹进去,灰度为50%则不会有凹凸效果。

缺点

缺点还是很明显的,它计算复杂!在渲染中不能直接获得表面法线,还需要根据灰度值再计算一次才能得到法线——需要消耗更多性能。

2 法线贴图 normal mapping

法线贴图储存表面的法线信息,法线贴图需要的这些法向量信息可以由高度图得到。法线纹理直接储存为常规的RGB图像,RGB通道分别对应着表面法线方向的X、Y、Z坐标。

但由于法线方向分量的范围在[-1, 1],但像素的分量范围在[0, 1](RGB值,0->0, 1->256),因此储存法线信息在法线纹理中会做一次映射

pixel=\frac{normal+1}{2}

例如,模型空间(法线纹理的三种空间之一,后续会讲述)中的法线normal(0, -1, 0)映射后就成了像素pixel(0.5, 0, 0.5)紫色。

当纹理管线中采用Shader通过采样纹理图像获取纹理值的步骤时,会再次将采样得到的结果值反映射回法线方向:

normal=pixel\times 2-1

 既然涉及到法线,不难想到该如何定义法线方向坐标?

事实上,法线有三种不同类型空间,又分别对应着三种不同类型空间的法线纹理。

2.1 模型空间

模型空间(object space)有时又被叫做对象空间,它俩一个意思。建模师们建立的模型默认的顶点信息都是模型空间的,基于模型空间储存的法线信息就很直接了——把修改后的模型表面的法线信息储存在一张纹理中

模型空间储存的法线信息是绝对的,它不会随着模型在场景中旋转、缩放而有所改变。

模型空间储存法线的优点

  • 更直观

实现起来简单、直观。模型空间储存的法线纹理往往是五颜六色的,因为模型表面的法线方向往往是各个方向的,如下图模型空间和接下来要介绍的切线空间的法线纹理对比(左侧):(图源法线贴图那些事儿 - 知乎 (zhihu.com)

  • 突变少

UV缝合处以及尖锐的边角部分更加的平滑,这是由于模型空间下储存的纹理信息是同一坐标系下的法线方向,边界处可以通过插值获取,可以平滑变换;

  • 自由度低

仅能应用于创建基于的模型,因为模型空间下储存的法线方向是绝对的;

2.2 切线空间

切线空间(tangent space)其实也是我们实际制作中最常用的坐标空间。切线空间是基于模型每个顶点为原点构造的一个局部坐标系,位于表面之上。表面除了储存顶点和法线外,还储存了切线tangent和副切线bitangent:

  • z轴是模型顶点本身的法线方向(n)
  • x轴是顶点的切线方向(t)
  • y轴是顶点的副切线方向(b,可由z和x轴叉积得到)

由这三个轴组成了切线空间的空间基TBN矩阵(在后续计算光照进行空间转换时会用到)。

这么一看,切线空间的法线纹理其实就是储存了每个顶点各自切线空间中法线的扰动方向

如果顶点没有什么凹凸效果,那么顶点在切线空间中的法线就是z轴本身(0, 0, 1)经过映射后得到(0.5, 0.5, 1)->(128, 128, 256)就是浅蓝色:

由于凸凹效果其实就是对顶点原法线施加一个微妙的扰动,大部分顶点法线都是原法线。因此,我们看到的切线空间的法线纹理都是呈现大片的浅蓝色,例如上面模型空间已经出现过的(右侧):

切线空间储存法线的优点

  • 自由度高

相比于模型空间的法线纹理,切线空间都是基于顶点自己的,都是相对的法线信息,这就意味着这张纹理可以应用于多个完全不同的网格上。

  • 可重用

使用一张切线空间的法线纹理,就可以用到同一个模型的不同面上,例如一块砖的六个面可以共用同一张法线纹理。

  • 可进行UV动画

可以通过移动一个纹理的UV来实现凹凸移动的效果,可以用于水、岩浆等流动的物体简单动画。

  • 可压缩

上面已经讨论过,Z轴永远是正向的,那么我们就可以只储存每个点的XY信息,Z通过推导得到即可,这一点模型空间就没办法做到。

因此,一般我们都选择切线空间下的法线贴图

2.3 世界空间

对于法线纹理的储存坐标空间来说,基于世界空间的法线纹理一般只适用于静态、大型的模型,比如宏大的地形等,不做太多的转换。

但对于后续进行的光照计算,世界空间和切线空间一起是最为常用的两种空间。

进行光照计算时,我们需要将法线纹理储存的法线和顶点坐标信息,以及光照方向、视角方向信息等变换到同一个空间下,基于同一套坐标系再进行光照计算。这时候世界空间就参与进来了。


 目前为止的一些困惑

纹理知识学习到这里,我自己有这样两点困惑:

  • 目前为止获取的信息很散,所以,法线贴图到底在哪个流程参与到渲染中的?
  • 假设我现在搜索得到了一张墙的纹理图片,我怎么给他加上法线纹理?

下面就大概来说一说这两个问题,首先是法线贴图如何使用?

3 制作中如何使用法线贴图

前面说的都是一些理论的东西,这次让我们结合实际制作看看法线贴图的使用过程。

一开始我们怎么介绍法线贴图的目的来着?——作为凹凸映射的一种方法,为了让模型渲染的更加真实好看,有凹凸感。

当然了,法线贴图并不是必须的。如果不使用法线贴图,为了让模型渲染的更加真实,一般会选择制作成面熟比较多的高模(这里尚且不探讨用面数界定高、低模正确与否),但这会带来一个问题——计算量大,消耗性能。因此,采用法线贴图能达到即渲染更加真实,又节约性能的目的。

3.1 实际中法线贴图的使用流程

建模师们会制作面数较少的低模和面数较多的高模,低模用来正常走纹理管线——展UV,高模用来获取法线纹理——记录下这个高面数模型的表面法线信息并储存在一张纹理中,此时得到了法线纹理。接下来,真正参与渲染的模型本体其实是低模,渲染时用上高模的法线信息,就达到了让低模具备高模渲染效果的目的。

描述成一个流程大概就是:

制作低模、高模 -> 低模展UV(1.0纹理管线已提到)-> 高、低模烘焙法线 -> 渲染

3.2 法线烘焙

这部分的叙述参考了法线2:烘焙法线贴图 - 知乎 (zhihu.com)

烘焙法线就是把高模的法线方向以像素的形式储存在低模的表面上,也就是上述流程中后面低模获取高模信息的过程。烘培程序从低模开始投射基础光线,跟随顶点法线搜索高模。

随意找了一篇blender中进行法线烘焙的文章简单几步搞定Blender法线烘焙! - 知乎 (zhihu.com)

读完后就能对建模软件中进行法线烘焙的流程有了个大致的了解,至于法线烘焙遇到的一些问题以及细节的过程,这里就不做过多的介绍了。

4 如何从高度图/纹理生成法线纹理

这就是上面提到的第二个问题: 假设我现在搜索得到了一张墙的纹理图片,我怎么给他加上法线纹理?

其实就是拿到了一个仅包含基础色信息的纹理,我想要捏造出来他的凹凸信息。

随手一百度,其实有很多种不同的方法了:有从PS里滤镜->转法线图的方法、有把灰度图直接当成高度图再转法线纹理的方法、有先给图片去色转成灰度图,再转成法线纹理的方法。

以上是手动的方法,还有一些图片转纹理的软件,例如Texture Maker、Normal Map Generator等。

5 光照计算中的坐标转换

在讲世界空间时就提到了:进行光照计算时,我们需要将法线纹理储存的法线和顶点坐标信息,以及光照方向、视角方向信息等变换到同一个空间下,基于同一套坐标系再进行光照计算。

法线纹理基于切线空间,那么可选的光照计算方法无非这两种:

  • 在切线空间下计算光照
  • 在世界空间下计算光照

这部分我认为实践记录更清晰,因此后续会单独开一篇博客来讲二者的计算过程(涉及到了TBN矩阵等内容),这里仅谈谈渲染光照计算中需要涉及到坐标转换这么一个事情。

猜你喜欢

转载自blog.csdn.net/qq_41835314/article/details/126558410