查看: 106|回复: 0

大世界树木阴影方案集合

[复制链接]

7

主题

1

听众

28

积分

问题学生

Rank: 1

升级   14%

TA的排名榜

积分:暂未上榜

发帖:NO. 160 名

在线:暂未上榜

发表于 2021-4-7 18:03 |显示全部楼层
这是侑虎科技第909篇文章,感谢作者偶尔不帅供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

作者主页:https://zhuanlan.zhihu.com/p/349282312,作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!
一、需求


Unity引擎对Terrain上的树阴影处理的稍显简易,常常满足不了项目需求。当动态物体采样Light Probe,默认是不给树烘焙Lightmap的。但我们知道这种大型的动态物体即便light probe proxy volume(不支持,改支持也卡) 也仅仅是更丰富间接光和大型遮挡,无法有效地表达自阴影效果。一旦出了实时阴影距离,画面就差了很多。而且手上的《生死狙击2》是一款投入4亿研发的大型项目。我作为负责图形渲染技术的人,自然是需要做大量的技术方案尝试与对比的。

具体需求是50米内用Shadowmap,50-1500米都要有平行光阴影,平行光是静态的。

以下是我尝试过或了解过可以满足这个需求的7种方案。
    烘焙可实例复用的无方向性间接光阴影烘焙可实例复用+可旋转的平行光阴影低精度预计算静态Shadowmap阴影稀疏八叉树体素化静态阴影屏幕空间接触实时阴影基于低精度高度图实时阴影距离场加速Ray Marching阴影
方案1:烘焙可实例复用的无方向性间接光阴影


这是最简单粗暴的一种做法,就是在3DsMax下利用天光烘焙一个类似AO一样的阴影,这样树木在旋转任意角度后和在任何角度的阳光下都兼容,资源复用率最高,但没有考虑到平行光阴影有点不真实和符合要求不高的问题。得到类似这样的烘焙图,作用在树的两套UV上。代码也很简单,只需要在SpeedTreeCommon.cginc内加入UV1传递,最后*到Albedo上,因为仅仅像AO一样作用间接光影响不够大。

Max烘焙的AO图绑定树的Prefab复用,Unity烘焙无法复用且带方向


实时阴影内


实时阴影外


本方案效果



优点:简单好用,用4行代码实现,性能很高,一张低分辨率图采样1次。

缺点:没考虑方向光,只能自己改善阴影,不能遮挡树下动态物件(静态可以烘焙Shadowmask)。
方案2:烘焙可实例复用+可旋转的平行光阴影


与上一个方案很像,但加上了方向考虑,烘焙这样的8个平行光烘焙图。


根据树实例不同的朝向,设置不同的AO图,但由于树在地形上设置起来不方便,可以做成数组或图集。Shader内根据朝向自己取Index或Offset,因为效果和上一个类似,但带了更好的方向性。每个方向都比较正常。如果觉得8个方向不够可以用2个方向插值或做16个朝向的图。
本方案效果



优点:简单好用,性能很高,一张低分辨率图集采样1次或2次,支持旋转,带有方向性阴影。

缺点:不同角度太阳的地图可能都需要一套独立的贴图, 只能自己改善阴影,不能遮挡树下动态物件(静态可以烘焙Shadowmask)。
方案3:低精度预计算静态Shadowmap阴影


先对比下实时阴影内的效果,树叶自阴影还不错,但第二张,在实时阴影外就惨不忍睹了。


用4M静态Shadowmask效果:


原理:离线对场景拍一张记录深度图的Shadowmap且记录灯光相机的matrix_vp。但因为这种大范围的拍摄,深度精度或许会不足,所以我没用16位的,而是用RGBA32自己压缩了深度,所以看起来是条纹的。

优点:不仅自己有阴影还能遮挡远处的人物等动态对象,实现简单,运行时省Draw Call,不用反复拍摄远景。

缺点:显存大。

继续升级的方案:基于虚拟贴图的静态Shadowmap或Texture streaming的Shadowmap。

之前工程:https://github.com/jackie2009/ScrollingStaticShadowmap
方案4:稀疏八叉树体素化静态阴影


用0.9M体素化阴影的效果:


原理:每0.5米一个立方体,记录0或1,表示是否在阴影内,作为八叉树节点。然后通过树的压缩节省内存。

要研究压缩的可以看我另一篇全面压缩的4种算法。

《四叉树阴影高级压缩技巧》

优点:不仅自己有阴影还能遮挡远处的人物等动态对象,运行时省Draw Call,不用反复拍摄远景,相比Shadowmap省显存。

缺点:实现复杂些,预计算写高并发才能够快。Shader需要多次采样才能查询到结果。

原理引用:《Shader内用八叉树实现体素化阴影》

工程文件:https://github.com/jackie2009/ocTreeVoxelizedShadows/

方案5、6、7 :每个Demo开发都比较复杂,后面更新或单独一篇。

文末,再次感谢偶尔不帅的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

也欢迎大家来积极参与U Sparkle开发者计划,简称“US”,代表你和我,代表UWA和开发者在一起!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

温馨提示:求助请到“Unity技术讨论”版块中发帖,便于集中解决!
您需要登录后才可以回帖 登录 | 立即注册

Unity游戏引擎开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2021-4-15 06:48 , Processed in 0.134214 second(s), 36 queries .