图形 2.5 BUMP图改进
BUMP图改进
Bump Mapping介绍
凹凸贴图映射技术是对物体表面贴图进行变化然后再进行光照计算的一种技术。例如给法线分量添加噪音,或者在一个保存扰动值的纹理图中进行查找。这是一种提升物体真实感的有效方法,但却不需要额外的提升物体的几何复杂度。这种方式在提升物体的表面细节或者表面的不规则性方面有显著效果。
Bump Mapping的种类主要有:法线映射、视差映射、浮雕映射。这几种方法或者贴图。都是广泛的被使用,来增加模型的细节效果,或者用来做特殊的画面表现效果。
最常用的是法线映射,一般的增加法线贴图后,会对局部的物体表面进行法线扰动,进而改变明暗关系,从而达到增加表面细节的效果。其中三种映射中都用到的法线贴图也是本次介绍的重点内容。
Normal Mapping
法线贴图记录了pixelshading过程中每个pixel的法线信息,用来描述像素级的法线信息,而不是直接使用顶点和面法线插值得到的pixel法线,从而得到更好的细节表现,法线贴图中储存的是以当前像素为原点的法线向量。
在计算光照的时候,程序会去读取法线图,并获取到当前像素点的法线信息,结合光线信息进行光照计算。使用法线贴图计算光照,可以让物体表现出更加丰富的细节,并随着光照方向的变换实时变化。这是普通纹理贴图不能表现出的。
法线贴图一般由高模映射到对应的底模上来生成。但像金属,木头等这些细节丰富的物体,可借助程序化的软件如:Photo Shop,Substance Designer等生成对应法线贴图。
切线空间
法线的储存,一般会放在模型的切线空间中。
切线空间是以物体表面的切线,副切线和法线组成的几何空间。
当我们计算光照时,需要把光照运算的向量放到统一坐标系下。读取切线空间法线,需要世界坐标转切线空间的转换矩阵 或 切线空间转世界空间的转换矩阵,将向量统一到同一坐标系后再进行光照操作。
我们将顶点法线、切线、副切线构成的矩阵叫做TBN矩阵,这个矩阵可将切线空间转换到世界空间下,其矩阵的逆TBN-1则是世界空间转到切线空间。
那么切线空间对比模型空间下有什么优点呢?我们为什么要使用切线空间?
1.使用切线空间自由度高,如果是模型空间下,每次换个模型就需要改变,而切线空间是相对的这个点。
2.使用切线空间方便制作uv动画。
3.便于压缩,法线只会在[0,1]之间。而且只需要对(1 - 切线的平方 - 副切线的平方)的值开根号就能求出法线的值。而模型空间的法线在[-1,1],就不能用TB来求取了。
Unity中法线贴图的压缩格式
在非移动平台上,Unity会把法线贴图转换成DXT5nm格式。这个格式只有两个有效通道GA通道,这样可以节省空间,而移动平台使用传统的RGB通道。在DXT5nm格式中,GA储存对应的法线X,Y分量,通过sqrt(1-x2-y2)就可以算出z。
Parallax Mapping
但是法线贴图存在一个问题,法线贴图虽然能够模拟明暗关系,但是却不能模拟出一种遮挡的关系,顶多将被遮挡的物体来做一个背光的处理。因此我们引入了视差贴图,它可以让背面被遮挡住的部分完全不显示出来,除此之外还能在一定范围内调整砖块凹凸的程度。当然,这也只是用于模拟视差效果,而非真正的改变模型的表面。
视差映射技术主要利用模型表面的高度信息来对纹理进行偏移,低位置的信息会被高位置的信息遮挡掉,因此从而会去采用高位置的信息来显示。
// 计算 uv 的偏移 delta inline float2 ParallaxUvDelta(v2f i) { // 视差贴图中描述的高度数据 half h = tex2D(_ParallaxMap, i.uvMain).r; // 切线空间中的视线方向 float3 viewDir = normalize(i.viewDir); // 将三维的视线向量投影到二维的 uv 平面,乘以高度数据 // _ParallaxScale 是一个用户可调节的值,根据效果需要进行调节,防止数值太大造成视觉上的严重错误 float2 delta = viewDir.xy / viewDir.z * h * _ParallaxScale; return delta; } float2 uvDelta = ParallaxUvDelta(i); i.uvMain += uvDelta; i.uvBump += uvDelta;
为什么这里要除以一个z分量,因为这里的z分量代表着的是法线方向,法线值越大,就说明视线越垂直于平面,也就说明偏移量小,所以需要除以z来判断偏移量的大小,然后乘以高度影响,高度值越高偏移越大。
Steep Parallax Mapping
Steep Parallax Mapping(陡峭视差映射)。因为视差映射往往是近似值,因此计算结果并不是准确的。在此基础上想获得更加准确的结果就需要陡峭视差映射,陡峭视差映射一个近似的解,但相比于普通视差映射要精确的多,效果表现上也更好。并且会对纹理坐标偏移进行合理性检查。
陡峭视差映射的基本思想是将深度分为等距的若干层,然后从最顶端开始采样,并且每次沿着视角方向偏移一定的值,若当前层的深度大于采样出的深度,则停止检查并返回最后的结果。不过虽然效果好,但是分层过多,性能开销大。
Relief Mapping
浮雕映射,对比与视差映射,想要有更好更准确的表现效果,视差映射是不够的,使用更大的uv偏移,视察映射就会失真,因此我们使用浮雕映射来表现更多的细节,浮雕映射更容易提供更多的深度,还可以做自阴影以及闭塞效果。
实现方法:
1.先射线步进,这一步同陡峭视差。
2.然后再二分法找到。
为什么不直接使用二分查找?因为直接用二分查找可能会漏掉较薄的区域导致结果不准确。所以第一步才需要射线步进,我们才能再使用二分查找来再确认交点位置。
扩展作业
观察Bump图用在自己写的光照模型中的效果。
_BumpScale为1.2:
_BumpScale为-1.2:
参考