基础感念
凹凸贴图技术是对物体表面贴图进行变化然后再进行光照计算的一种技术。例如给法线分量添加噪音,或者在一个保存扰动值的纹理图中进行查找,这是一种提升物体真实感的有效办法,但却不需要额外的提升物体的几何复杂度。这种方式在提升物体表面细节或者表面不规则形方面有显著效果。
凹凸映射分类
Bump Mapping 的种类主要有:法线映射、视察映射、浮雕映射。
最常用的是发现映射,一般的增加法线贴图后会对局部的物体表面进行法线扰动,进而改变明暗关系,从而达到增加表面细节的效果。
Normal Mapping 法线映射
normal map是一张存有物体局部表面法线信息的一张贴图。在计算光照的时候,程序会去读取法线贴图,并获取到当前像素点的法线信息,结合光照信息进行光照计算。使用法线贴图计算光照可以让物体表现出更加丰富的细节,并随着光照方向的变化实时变化。
*法线贴图一般由高模映射到对应的底模上来生成;但像金属,木头等这些细节丰富的物体,可借助程序化的软件:Photo Shop、SD等生成对应的法线贴图。(而法线一般储存在模型的切线空间中)
什么是切线空间?
切线空间是以法线向量为Z轴以顶点为原点定义的坐标系,另外两个坐标轴就是和该点相切的两条切线(Tangent)
这样的切线本来有无数条,但模型一般会给定该顶点的其中一个Tangent。
Normal:法线,软件生成可编辑。
Tangent:切线,引擎生成
B-Tangent:根据N和T的叉乘计算得到
为什么要用切线空间?
实际上,法线本身储存在那个坐标系中都是可以的。例如世界空间、模型空间、切线空间。
但问题是,我们并不是单纯的想要得到法线,后续的光照计算才是我们的目的,不管使用那个坐标系都面临着一个选择,就是最后光照计算使用的坐标系究竟是哪一个?
对于切线空间,我们需要把视线方向、光照方向在顶点着色器中转换到切线空间中,然后在片元着色器对法线纹理采样后直接进行光照计算。
世界空间和切线空间如何转换?
将世界坐标系下的顶点法线(normal)和切线(Tangent)以及副切线(Bitangent)作为切线空间坐标系的正交基。
并用这三个向量的标准正交基来构建转换矩阵,对应关系为法线作为z轴,切线作为x轴,副切线作为y轴。
构成一个3*3的矩阵空间来做空间向量的坐标系转换,一般叫该矩阵为TBN矩阵,其逆矩阵就是从切线空间到世界空间的转换矩阵标记TBN^-1,因为TBN是正交矩阵,所以其逆矩阵就是TBN的转置矩阵。
使用切线空间有什么好处?
自由度高,切线空间记录的是相对法线信息,这意味着即便吧纹理应用到一个完全不同的网格上,也可以得到一个相对合理的结果。
可进行UV动画,例如我们可以移动一个纹理的UV坐标来实现一个凹凸移动的效果,这种uv动画可以在水或者火山熔岩这种类型的物体比较类似。
可以重用normal map,例如一个砖块我们可以仅使用一张normal map 贴图就可以用到所以的六个面上。
可压缩,由于切线空间中法线z方向总是正方向,因此我们可以仅储存xy方向,通过叉乘得到z方向。
unity中法线贴图的压缩方式
在unity中非移动平台上unity会把法线贴图转换成DXRT5nm格式。这种格式只有两个有效通道:GA通道。这样可以节约空间,而移动平台unity使用传统的RGB通道。在DRXTnm格式中,GA储存对应法线的x、y分量,z分量需要简单计算得到
关于切线空间的补充
通常我们所见的那种偏蓝色的法线纹理,其实就是储存在切下空间中每个顶点法线的扰动方向。
也就是说,如果我们一个顶点的法线方向不变,那么在他的切线空间中新的normal值就是z轴方向,也就是说值为(0,0,1)。但这并不是法线纹理中储存的最终值,因为一个向量每个维度的取值范围在(-1,1),而纹理每个通道的值范围在(0,1),因此我们需要做一个映射变化,即pixel = (normal + 1)/ 2。这样,之前的法线值(0,0,1)实际上对应了法线纹理中RGB的值为(0.5,0.5,1),而这个颜色也就是法线中那大片蓝色。
parallax mapping视差映射
法线映射虽然能展示较为逼真的模型表面细节,但毕竟发法线映射只能改变法线,并不能让模型表面产生让人信服的遮挡效果。所以我们引入视差映射。
原理:我们制作的模型在一个三角面即为切线空间下,所有点都位于切线和副切线组成的平面内(下图水平0.0),但实际物体要有更多的细节。
如下图当计算我们当前视角的片元A时,真正应该计算的点是视线与物体表面的实际交点,即B点。
如何计算B点?需要知道A,B两点在平面上uv的偏差。更具高度图以及切线空间下的视角方向,近似的求解偏移量。视角方向(v),A点的高度值来近似的求解,并可以通过一个缩放值(scale)来控制。
Steep Parallax Mapping陡视差映射
陡视差映射的基本思想是将深度分为等距的若干层,然后从最顶端开始采样,并且每次沿着视角方向偏移一定的值,若当前层的深度大于采样出的深度,则停止检查并返回最后的结果。
*陡视差是一个近似的解,但相比于普通视察映射要精确的多,效果也更好。并且会对纹理偏移进行合理性的检查。但如果分层多,开销会较大;分层少,则容易出现锯齿。
Relief Mapping浮雕映射
想要更你更精确的效果,视察映射是不够的,使用更大大uv偏移,是擦汗映射就会导致失真。于是引入浮雕映射,浮雕映射更容易提供更多的深度,还可以做自阴影以及闭塞效果。
a,b使用的视察映射;c,d使用了浮雕映射
原理:浮雕映射一般采用射线步进,和二分查找来决定uv偏移量。
为什么不直接使用二分查找?
因为直接用二分查找可能会漏掉较薄的区域导致结果不准确。所以第一步,使用射线步进来确定交点位于那个步进内。然后在该步进内使用二分查找,快速确定交点位置,最后返回结果,偏移贴图。
Parallax Occlusion Mapping视差遮蔽映射
视差遮蔽隐射(POM)是浮雕映射的另外一个版本,计算出的视差效果更加真实
作业
未加法线贴图
加入法线贴图
视差暂时有点儿问题,没有成功。