前言
视差贴图技术是相对于传统的法线贴图技术所做的一项改进
视察贴图技术可以给场景里要渲染的游戏物体增加物体表面的凹凸细节,在过去为了表现物体的表面细节,通常会使用法线贴图,那么为什么又要使用视差贴图呢?它跟法线贴图有什么区别呢?下面来为大家讲解
版权声明
- 本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
- 更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
- 点赞、关注、分享可免费获得配套学习资源
- 点击观看完整视频
视差贴图与其他贴图
- 上图是本文的封面,封面上的三张图片是采用不同渲染方法渲染出的墙体
- 最左边的图片是不采用任何增加表面细节的方法渲染出的墙体
- 它虽然有一张基本的细节贴图,但这张贴图并不能够真实的反映物体表面的凹凸细节
- 中间的图片贴了一张法线贴图
- 法线贴图可以增加物体表面的凹凸感,所以可以明显看出中间的墙体比左边墙体有更多的凹凸细节
- 第三个图片是在法线贴图的基础上增加了一张视差贴图,并通过视差映射渲染算法处理进一步增强了凹凸细节表现
- 视差贴图只是一张图,视差映射是利用视差贴图的图形学算法
视差映射算法的各种效果
- 视差映射算法除了可以用来增加物体表面细节以外,还能做出来很多有意思的效果
- 上图就是利用视差贴图技术把2D图片3D化
- 上图中的小猫是一张2D图片,不是模型,把这张图片导入到Unity后,利用视差贴图技术,就可以让小猫动起来
硬币会随着鼠标的摆动往不同的方向进行一定旋转,但旋转角度不能太大,因为其本身只是一张2D图片,并不包含一个3D物体的完整信息,旋转角度太大就会出现一些失真和穿帮
右图本身是一幅画,在经过处理后看上去就像是在3D场景里一样
- 视差贴图技术在实际环境中也有广泛应用,大名鼎鼎的FaceBook网站就使用了视差映射技术来实现2D图片的3D化,在FaceBook网站里只要上传一张2D图片就能够把它做成一张3D效果图
- FaceBook网站在你上传一张图片时会自动运用一些人工智能算法生成一张视差贴图,然后利用这张视差贴图来对图片进行视差运算以实现2D图片的3D化
- 视差映射技术不仅仅可以用来操作图片,它也能用来操作一些视频
- 上图是一个抖音短视频,可以看到场景里的人物面部突出来了,这也是利用了视差贴图技术,而且只需要两个步骤就能实现
- 1,利用人工智能技术识别视频里的人眼和嘴巴的区域
- 这和FaceBook里运用的识别图片是一个道理,但它做的更多一些,因为它不仅仅是做出人物的视差效果,还区分了人物的不同的区域
- 2,利用视差贴图技术把识别出的两块区域抬高
视差贴图究竟长什么样
- 左边的贴图没有任何的凹凸细节表现,只是贴了一张普通的漫反射贴图
- 漫反射贴图只能用来表现物体表面细节,无法没有表现物体的受光,它的受光只是一块灰蒙蒙的平面,正常的物体受光应该是凸的地方受光多一点,凹的地方不怎么受光
- 第二张贴图是漫反射加法线贴图,可以明显看出它的受光效果,物体表面凹进去的部分受光会比较暗,凸出的部分受光比较明显
- 但漫反射加法线贴图只是在受光上有了一些明暗变化,物体的凹凸细节并没有表现出来,想要表现物体的凹凸细节需要再增加一张视差贴图
- 右边的贴图就是在漫反射加法线贴图的基础增加了一张视差贴图,它不仅仅能够反映光照带来的变化,还能反映出物体表面的凹凸细节
如何表现物体表面凹凸
-
方法1,给模型增加更多顶点
- 如果想要做出右图这样的地平面,仅仅是用一些顶点去做的话,需要有非常非常多的顶点,也就是使用高模,但在游戏的实时渲染中,根本不可能用面数、三角形、顶点数量这么多的模型来进行实时渲染
- 显卡能进行实时渲染的性能指标是有限的,所以我们一般会使用另外一种方式
-
方法2,低模加上一张贴图
- 用一张专门表示物体表面细节的贴图来绘制物体细节,物体表面只需要用一个平面模型就可以了,剩下的细节全部通过这张贴图来进行表现(如上方右图)
- 但这种方式做出的细节非常有限,因为这张贴图只是把这些凹凸画上去了,光照在物体表面产生的反射比较粗糙,只是白花花的一片光亮
- 一束灯光照射在贴图上产生不同方向、不同强度的反射,才能使渲染出的结果更加真实、细腻,只是贴一张贴图,没有基于每一个像素点来计算光照,只是基于整个大三角形进行计算,肯定无法得到细致的物体表面细节
-
方法3,方法3仍然是使用低模,保留漫反射贴图,只是增加了一张法线贴图
- 前面的方法只是贴一张图上去,因为物体表面的方向统一都是朝上的,自然表现不出细节,所以要增加一张法线贴图,法线贴图里存放的是物体的每一个像素点的方向信息
- 比如上图贴图中的泥土的法线方向可能是朝着地面的,石块表面因为比较光滑,它的法线方向就可能是朝上的,有了所有物体的表面细节后再进行渲染就能得到更加精细的光照的效果
- 灯光方向虽然是一致的,但它会根据物体表面的法线方向来计算反光,由于每个像素点的法线方向都不一样,计算出的反射方向自然也不一样,所以它能够表现出更细致的光照细节
-
这就是法线贴图的原理,但不是法线贴图的全部,只是一些皮毛,法线贴图的知识点还有很多,比如
- 法线贴图是怎么样生成出来的?
- 法线贴图为什么是蓝色的?
- 为什么法线贴图除了大部分都是蓝色以外,还会出现有红色、绿色,它们都代表什么?
-
法线贴图有一个约定:如果一个物体表面的方向是垂直朝上的,那么它在法线贴图里就会用蓝色表示,为什么会用蓝色呢?
- 这个规定是有一定原因的,因为法线贴图使用了切线坐标系,切线坐标系规定物体的平面是由切线坐标和负切线坐标构成的,垂直于这个平面的就叫做法线(如上方最右方图)
- 法线的坐标刚好与平面垂直,它的坐标是(0,0,1),如果把它转换成一张图片里的颜色那么(0,0,1)就相当于RGB里的B,也就是Blue,因此使用蓝色来表示一个物体的表面法线方向
- 比如左边的贴图中有些地方是石块,这些石块的表面方向是朝上的,但它的边缘方向要么朝左、要么朝前,要么就是朝右,因此它的颜色就可能是绿色或者红色,如果是绿色,就表示它的法线方向朝着负切线法线的方向,如果是红色,就表示物体表面的方向是朝着切线方向
-
这仅仅只是理论上的了解,当你要落到实处写代码时就会发现:
- 在Unity里直接导入一张图片,并对它进行纹理采样,所得到的采样结果又会是不正确的,这就跟Unity对法线贴图的编码和压缩有关系了
-
使用法线贴图渲染出的结果就会更加贴近真实,但还不够,法线贴图只能模拟表面上不同的法线方向带来的明暗变化,并不能模拟凹凸
-
假设上图中的眼睛图标是Unity里的摄像机,蓝色的箭头是摄像机观察的前方向,在现实世界中,我们用眼睛看这块砖块时,砖块有一些背面是不能被眼睛看见的,这部分就处于阴影区域
-
如果用法线贴图的话,那么这部分就不处于被遮蔽的阴影区域,它仍然是可见的,为什么呢?
- 因为法线贴图里不包含物体的高低信息,它只有每一个像素点的法线方向,所以只能计算出来物体表面的明暗信息,不能计算出这一块区域是否被遮挡,体现不出来凹凸感
- 从之前的使用法线贴图的地面效果中也可以看出砖块后面的阴影区域只是比较暗,并没有被遮挡
-
如果使用低模的话,那么物体表面的法线方向都是跟这个物体的表面垂直的,就是我们现在看到这个呃紫色或者蓝色的,因此一束光照射过来时产生的光线反射也是一样,并不能反映物体表面的明暗变化(如上方1号图)
-
上面的第3号图是法线贴图,每一条物体表面的法线朝向都不一样,在计算物体光照的公式里会根据反光的夹角计算反光强度,由于每一个物体的表面的法线方向都不一样,那么夹角的大小也不一样,计算出的反射也不一样,物体每一个像素点的光照强度系数也都不一样
-
但这并不是正确的结果,正确的结果是什么呢?
-
由于物体表面是凹凸的,那么一束光照射在凹陷区域前方的平面上,那么凹陷区域应该是不受光的,这是真实的凹凸效果模拟
视差贴图的具体实现细节可以加文末联系方式领取
思考
什么时候要用到切线空间?
什么时候用物体的局部空间?
什么时候用世界空间?
切线空间的概念是什么样的?
如何通过书写算法调用Unity里的法线贴图资源?
写在最后