浅谈游戏中3种常用阴影渲染技术
版权声明
本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
更多学习资源请加QQ:1517069595,获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
众所周知,在游戏当中,阴影是无处不在的,如果一款游戏没有阴影,那么不光画质会大大折扣,游戏性也会大大降低,因此,我将通过这篇文章给大家谈一谈关于三种阴影渲染方式相关的知识,由于篇幅所限,我将着重讲解一种基础的渲染方式即平面阴影的实现。
一、平面阴影

1.1 实现步骤
对一个角色模型进行了两次绘制(两个Pass):
第二次是利用模型数据绘制角色阴影,我称这种绘制方法为两遍绘制。
首先要给大家介绍一下图形着色器,图形着色器由两个部分组成:
第一部分为顶点渲染,确定顶点位置


首先,我们在顶点程序里面需要干两件事情,第一件事情,就是把所有的顶点变换到世界空间,同时在地面上产生一个垂直的投影,第二件事,我要计算我的光线,根据光线的投射方将对地面的投影做一个平移。
其次,当我们的模型投影好之后,就要对阴影进行一个着色,通过rgb和透明度的设置,也就是半透明混合,来达到本身的颜色和阴影的颜色进行混合,最后得到一个“五彩斑斓的黑“的阴影效果。
1.2 平面阴影渲染所存在的问题
阴影重叠
阴影是半透明的,在渲染前,我们会开启阴影渲染的透明混合状态,模型的正面和背面的三角形可能重复渲染,造成不透明度的叠加,这种的叠加是非常杂乱无章的。如图所示,阴影非常地杂乱。
什么是阴影重叠?:


模板缓冲区对阴影进行渲染时,我们会在每一帧渲染时,将像素点的值设置为零,我们用零与特定的参考数值进行比较,当他满足比较条件即通过我们的模板测试时,对于通过测试的像素点,我们将他的模板值替换为参考值,当下一次在相同的位置进行渲染时,就无法通过模板测试,我们就舍弃了该片元,从而保证一个像素点只被渲染一次。
除了阴影重叠的问题之外,还存在着两个问题:

2.由于阴影是物体本体压扁形成的,所以,在地面边界处,物体的阴影可能超出边界

不需要打灯
渲染速度快
劣势
只适用于平面表面

二、阴影锥
原理:

三、阴影贴图
3.1阴影贴图的特点
阴影贴图是Unity官方所采纳的一种阴影渲染方式,官方为了集成阴影贴图的方式,已经做了很多的工作,我们作为开发者只需要在场景中设置好灯光,并且设置游戏中的gameobject是否能够产生阴影就能够完成
需要一个额外的ShadowCaster通道
3.2阴影贴图的实现
第一步:在灯光的位置生成一张深度图,将场景中的深度值渲染到深度图里面,如下图,地面的部分和方块被光线照到的地方需要被渲染,那么我们就把他们的深度值渲染到我们的深度图里面。这些场景的信息会被存储到一个额外的pass即ShadowCaster。
ShadowCaster是专门用来取得场景的深度信息的pass,这个Pass的深度信息是从灯光的位置取得的
第二步:
假如我们要渲染地平面,而地平面是由一个个点组成的,假如我们要渲染点P,如果用我们的肉眼去看,那么很容易就可以看出点P是在阴影中,但是计算机如何知道点P是否应该被渲染呢?
将渲染的深度图,与点P在灯光空间中的深度值做比较,这里涉及到将点P的摄像机空间的深度值转换到灯光空间中。将点P转到灯光空间后,可以理解为点P距离灯光0.9,距离摄像机0.4,因为0.9>0.4,所以点P位于阴影之中,不用渲染。
3.3软阴影
ShadowMap也能实现软阴影的效果,软阴影是游戏中重要的阴影效果,一个阴影是由本影和半影组成的,软阴影就是所谓的半影,如右下角的图,阴影的周围伴随着虚化的阴影。

如果场景中有多个光源,会对同一个物体造成多个阴影,如何实现多光源的实时阴影以及他的性能优化,可以继续关注我们的课程。
如图左边一个飞机停在飞机跑道上,因为跑道贴图和飞机阴影的深度值相同,因此会出现抖动。
深度抖动问题的解决。
多光源实时阴影及其性能优化 。

作者:优梦创客