如何实现更真实的软阴影效果

如何实现更真实的软阴影效果

这是侑虎科技第325原创文章,感谢作者Luisa供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

作者知乎:https://zhuanlan.zhihu.com/taiyouxi,同时,作者也是U Sparkle活动参与者哦,UWA欢迎更多开发朋友加入 U Sparkle开发者计划,这个舞台有你更精彩!


现实中,在地面上的人影往往因为被投射的物体是粗糙不光滑的,所以影子的轮廓也是有些模模糊糊,没那么棱角分明。在最新的游戏项目中,美术提出我们应该也做一个更柔和、更真实的实时阴影(本文中提到的阴影都是投射在其他物体上的影子,区分于自身的阴影)。

对于这个需求,并没有自造车轮,而是找了一个很好的轮子让它转了起来,我们可以先看一下目前我们项目中影子的效果:

请输入图片描述
PK沙滩1中主角与小怪带着柔和的实时影子

其实Unity本身自带了Soft Shadow的选项,但是有些缺点(下文会具体比较说明)。 在我们的工程里,选用的是NyanHoon Games的「Dynamic Shadow Projector」
官网:http://nyahoon.com/products/dynamic-shadow-projector,在Asset Store就有,免费下载。

这里将这个插件的软阴影与Unity自带的软阴影做一些比较。本篇文章所有测试的条件如下:手机为OPPO A37m(CPU:1.5Hz,内存:2GB,GPU:Mali-T860),目前是一款中低档的手机;场景中放置共13个人物模型;使用白色Directional Light;如无特殊说明,截图和数据皆来自手机。


一、Unity自带Soft Shadow的情况

参数:
参考我们现在的项目,Directional Light,选择Soft Shadow,Quality Settings中的Shadow设置为High Resolution, 70 ~20, Two Cascades。 有一个选项,Shadow Projection,它对于影子的质量影响很大(官方说明:平行光投射阴影有2种方式:Close Fit渲染较高分辨率的阴影,但是如果相机移动时,有时阴影会轻微摆动。Stable Fit渲染的阴影分辨率较低,不过相机移动时不会发生摆动。)

真机情况:

请输入图片描述
左侧为Unity自带Stable Fit真机表现,右侧为Close Fit真机表现

最开始我尝试的是Stable Fit选项,出来的效果不忍直视(左图)。换成Close Fit后,锯齿问题相当明显的被改善了,但这样造成的问题是性能开销上大幅度的上升。仅从SnapGragon的CPU利用率来看,从比较稳定的40%,增长到了60%左右,而且十分不稳定,有时甚至会跳到70%。

请输入图片描述
Stable Fit的SnapGragon截图

请输入图片描述
Close Fit的SnapGragon截图


二、使用Dynamic Shadow Projector 且不开启任何Blur或重采样选项的情况

请输入图片描述
左侧为插件512分辨率,右侧为1024分辨率

第二组以及下面的第三组测试,都是同时处理区域范围内所有的人物(13个模型),将其渲染到同一张Texture上进行处理。本组实验使用了插件,但是并没有开启附加功能,例如Blur或Mipmap。

上图左侧是分辨率512,右侧是1024,我们目前的项目里用的就是1024的分辨率。可以看到锯齿情况有所改善,但如图所见,依旧有着明显的锯齿,因此个人认为单纯提高分辨率意义不大。不过性能上,真机的CPU利用率,512的为44%左右,1024为53%左右,增长都不多。下图是1024的SnapDragon截图。

请输入图片描述
插件1024分辨率的SnapGragon截图


三、Dynamic Shadow Projector开Blur的情况

第一张手机截图是512分辨率开Blur,第二张为1024的Blur效果。1024的情况下,影子会多很多细节,但是若追求的是比较模糊的软边影子。其实512的就足够好了。对比第一组的Unity自带软阴影可以感觉到,Unity的Soft Shadow真的是一点都不Soft。

再比较一下性能。可以看到512的时候开了Blur,CPU占用率也是44%左右没什么太多。但是1024的时候CPU性能一下子升到了70%,不过跟Unity的SoftShadow的Close Fit形态比,也就多了10%。

请输入图片描述
分别为插件512分辨率开Blur,和1024分辨率开Blur的真机效果

请输入图片描述
插件512分辨率开Blur的SnapGragon截图

请输入图片描述
插件1024分辨率开Blur的SnapGragon截图

这个插件的Blur选项主要是多做了一步Graphics.Blit。针对这个函数,在Profiler上查看了一下手机GPU的情况。可以注意到从10%占用率,4ms左右增长到了24%占用率,13ms左右。

请输入图片描述
上下两张分别为插件在512分辨率和1024分辨率开Blur时,Blit函数的真机GPU使用情况

这里附上一下改变了光照颜色后的效果:

请输入图片描述

左右图分别为Unity自带软阴影与插件512分辨率开Blur时,在黄色Directional Light下的效果。可以感觉到,右侧插件带着Blur的效果,软边将光照的颜色很好的融合在了一起,非常的自然,而Unity的自带阴影可以说完全没有融合环境光。


小结

横向对比以上测试结果,在同为较低损耗的分辨率下,插件+Blur的效果很理想地达到了美术期望的软边阴影效果;高分辨率情况下,Unity自带阴影的锯齿很小,但几乎感受不到边缘的“软”,而插件+Blur,有软边有细节,当然性能略耗。

PS. 针对有性能损耗的blit函数,也可以尝试改写Blur的方式来提高性能。


文末,再次感谢Luisa的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)
也欢迎大家来积极参与U Sparkle开发者计划,简称"US",代表你和我,代表UWA和开发者在一起!