lightmap的shadowmask混合光照对于GPU Instancing的支持

       项目的需求,开放视角要考虑DrawCall的开销,所以要是实现这个功能,这个功能已经完成一段时间了,在这里做个记录,由于项目是商用,故不能贴出源代码,只贴出实现思路,供大家交流,如有不对的地方还请指正。

        GPU Instancing已经不是什么新技术了,其目的主要是为了提升绘制大量物体的渲染效率,从CPU和GPU层面减少重复性的工作,具体GPU Instancing的技术细节说明,本文不再赘述,感兴趣的同学可以在查看本文最后的扩展链接。

        Unity在5.4版本开始引入了GPU Instancing,分为自动和手动两种方式,原生的 surface shader和stand shader都提供GPU Instancing的自动选项,只要在材质界面上勾选Enable GPU Instancing选项,无论手动或自动,大的前提是要Mesh和材质相同。

        

        我们知道,任何通用的解决方案背后都会有或多或少的限制,这在程序设计上是说得通的,因此才会体现定制的价值。Unity也不例外,自动的GPU Instancing会有很多限制,比如:不支持static batch,不支持lightmap,等等。关于Unity GPU Instancing说明以及限制。请参照官方文档https://docs.unity3d.com/Manual/GPUInstancing.html

           在项目的实际应用中,我们的场景中存在大量的静态植被都需要lightmap烘焙,如果自动不支持,显然我们就要考虑手动的方式,这正是本文的目的,Unity提供了两个底层的API来进行手动的GPUInstancing,分别是Graphics.DrawMeshInstancedGraphics.DrawMeshInstancedIndirect

           有了实现的入口,接下来就是实现的思路和流程,首先要做lightmap的支持,如果不考虑shadowmask的情况下,这个问提还是很好解决的,就是把模型对应的lightmapScaleOffset传给shader做lightmap采样,在shader走uniry 的gi流程,模型行本身不做GPUInstancing处理,考虑到混合光照的情况,还要对shadowmask进行采样,所以就需要把shadowmask贴图和光照贴图都传给shader。

          这里面在项目实际操作中,遇到了两个坑:

          1:如果shadowmask是多张的情况,还要通过shadowmask对对象分组,就是在一张shadowmask贴图上都有哪些对象,而最终的分组长度则会直接影响GPUInstancing的批处理数量。

          2:很多项目在Quality设置选项中,都会将shadow distance的值设置的很小,这是为了保证阴影的精度。如果绘制对象过于密集,由于是按shadowmask进行分组Instancing,单张shadowmask中对象在场景中很分散,对象所对应的阴影距离超出shadow distance设置的值,表现得效果就是,不分对象没有进行shadowmask采样,这个问题在目前还没有找到很好的解决办法,有哪位小伙伴有更好解决方案可以在下面留言。

            最后再通过Graphics.DrawMeshInstancedGraphics.DrawMeshInstancedIndirect每帧绘制对象,这里还有一个问题要注意就是官方对于Graphics.DrawMeshInstanced绘制对象的个数是有限制的,最高上限上限是1023,强迫症的表示很不爽。


这是1023颗草的效果,36个DrawCall。

最后要感谢leonwei博主,起初我就看了他的文章,才有了思路,原文在这

http://blog.csdn.net/leonwei/article/details/73274808

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值