今天介绍的是idTech在Siggraph 2016分享的一些渲染相关的技巧,分享人是Tiago Sousa & Jean Geffroy,照例,这里对工作内容做一个总结:
- 因为工期紧张,因此开发的指导原则是KISS,即keep it simple stupid,也就是尽量的简洁
- 由于针对场景做了详细的规划与设计,因此最终版本里只有100个左右的母材质与350个PSO
- 整体帧率目标为60fps,其中GPU部分的耗时给出如下(前向渲染与延迟渲染之间的某种策略):
- shadow绘制耗时3ms,采用了cache策略
- 不透绘制耗时最多,约6.5ms
- 半透部分耗时1.5ms
- AO、反射、fog、composite等延迟后处理效果总计耗时2ms,这是管线中唯一的延迟部分,这部分的输入数据从forward pass中取,相对于传统的延迟渲染概念,这里的带宽消耗更低
- async post process耗时2.5ms
- Pre-Z耗时0.5ms
- 光照部分采用了clustered rendering来减少不必要的浪费,统一半透跟不透物件的绘制过程,不用单独处理以增加复杂度(流程与shader变体),cluster不仅仅用在了光源上,还用在了其他合适的应用,如reflection probe,贴花等
- 这里对如何判断某个froxel受哪些光源影响的策略做了优化,将屏幕空间的相交判断改成了Plane与AABB的测试,通过SIMD加速提升了计算效率
- 启用了VT,在控制消耗的基础上提升整体的效果,并做了如下的一系列优化策略:
- 对VT Page做了压缩以进一步降低消耗
- 采用了硬件sRGB来优化性能
- 优化了mipmap生成算法以降低高光锯齿问题等
- 优化了贴花的绘制过程,将之放到半透物件的光栅化过程中完成,与光照计算叠加在一起完成,采用的是类似光源光照过程的处理模式,据说可以高效的规避若干trouble case
- 先贴花的贴图混合逻辑,再光源的光照计算逻辑
- 不用单独的pass来渲染贴花,且因为不需要单独绘制贴花,也不用读取深度buffer,因此支持对半透物件叠加贴花效果
- 光照的一些设计:
- indirect diffuse部分,对于静态物体而言,会使用lightmap,动态物体则基于irradiance volume
- indirect specular部分的反射计算来自于三部分:环境光probe、SSR以及高光遮蔽
- 动态光源,只考虑直接光部分,做动态计算+shadow即可
- 寄存器压力会导致性能的显著下降,这里提供了一系列的优化建议
- 通过对特效的细致分析,提出了将特效粒子的分辨率与渲染的分辨率分割开来考虑的思想,并通过cache等策略进一步降低这里的渲染消耗
- 阴影的计算有如下的设计:
- 所有的shadowmap会被汇总到一张Atlas中,方便一次性绘制与取用,减少RT切换,增强合批
- 对满足条件的shadowmap做了cache处理,并会基于距离等各种因素动态调节各个光源应该分配的shadowmap分辨率,以有限的性能保障尽可能高的效果
- 如果cache的贴图没有动态物件叠加,就直接使用;有叠加,就做copy-paste-append处理
- 使用低模的proxy mesh替代高模的普通mesh来降低渲染消耗
- 方向光阴影用了CSM,两级之间的衔接处,通过dither做了平滑
- 基于下采样+高斯模糊的方式得到毛玻璃的mipmap结果,之后按照粗糙度进行取用
- 在渲染性能上,做了较多的debug工具来直观的展示性能压力区域
- shader复杂度(UE具备)
- 场景光源复杂度热力图(比性能热力图更为细分)
- 其他性能优化策略
- 根据GPU的负载,动态调节各个pass的分辨率,从而以尽可能低的成本得到尽可能无损的品质
- 在面片尺寸较大的区域,禁用VS参数缓存的延迟分配
- 谨慎使用Async Compute Shader以减少缓存命中率的破坏