[引擎搭建记录] 分块/分簇延迟渲染

本文知乎地址:https://zhuanlan.zhihu.com/p/66884611

项目地址:https://link.zhihu.com/?target=https%3A//github.com/MrySwk/GravityEngine

分块、分簇(tiled/clustered)渲染是上个世代提出来的渲染技术,已经有些年头了,其目的是在计算光照前对光照进行裁剪,以提升场景中光源较多时的性能表现。分块和分簇和其它延迟或者前向渲染技术能兼容得比较好,现在的商业和in house引擎也都在使用,以虚幻为例,虚幻的管线是普通版本的tiled deferred和forward+。实际上之后提出的还有2.5d tiled等技术,以及和deferred texturing或visibility buffer等结合的版本,这里我把分块和分簇都实现了下,最后结果是分簇的表现好一些,所以最后采用了分簇。

为了检验效果我们会经常需要gpu profiling,但是不像unity和ue4有内置的,每次需要去用renderdoc抓效率太低了,而且又特别占硬盘空间,所以我暂时弄了个简陋的profiler,可以看各个pass的耗时和比重:
在这里插入图片描述
那么先看下效果如何,首先我们试试普通的延迟渲染,在1080p下渲染同屏1000个点光源的效率如下(注意右上角的效率分析):
在这里插入图片描述然后是接近4K的分辨率(除去边框):
在这里插入图片描述

可以看到,1080p下光照pass要39ms,而4K分辨率下light pass更是达到了恐怖的90ms,只剩10帧每秒,卡成狗。

然后是分簇渲染的结果
在这里插入图片描述在这里插入图片描述
可以看到,1080p下分簇pass只消耗了0.16ms,而light pass缩减到了1.2ms,可以跑到每秒三百多帧了,4K下对应的则是0.22ms的cluster pass和2.7ms的light pass,现在这个结果还有优化空间,light pass可能还能更快,但已经可以明显看出开销大大降低,速度翻了几十倍,(当然这只是在上千个光的极限情况下,在实际游戏中不可能效果这么明显,分块还是分簇、块的大小等等都要在实际场景里去调)。

接下来介绍一下分块和分簇的原理以及一些具体实现上面的细节和容易碰到的坑。


分块着色(Tiled Shading)

分块的思想就是将屏幕分成一个个相同大小的块,每个块都各自保存一个和这个块相交的光源的list,我们先用计算着色器将每个光源和每个tile求交,把结果保存到tile的light list里面,然后在着色的时候取出来用,只渲染保存在light list里面的光源,这样一来就达到了对光照做剔除的效果。
在这里插入图片描述
下面这张图能更好地表达tiled shading的意思,屏幕被划分成一个一个的tile,然后光源分别与这些范围求交,然后把相交的光存在对应tile的list里面,最后只渲染这个list里的光。
在这里插入图片描述
这里我把分块的工作交给了计算着色器,并且每个tile的大小选择的是16x16。

首先第一步,统计块里面的深度,统计深度是为了算出前和后两个截面,从视锥顶部俯视来看我们要的是这样的一堆frustum来对应每个tile:
在这里插入图片描述
有了深度,就可以根据块的位置和深度上下限具体地求出这个视锥的六个面了,这里用到的方法类似于推导视锥体,但是略有不同,可以参考一下这个:
http://www.lighthouse3d.com/t

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值