《鸣潮》基于虚幻引擎4的多平台效果和性能优化实践 | 王宏波 库洛游戏
文章目录
- [《鸣潮》基于虚幻引擎4的多平台效果和性能优化实践 | 王宏波 库洛游戏](#《鸣潮》基于虚幻引擎4的多平台效果和性能优化实践 | 王宏波 库洛游戏)
-
- [Why Deferred Shading](#Why Deferred Shading)
- 移动端高质量的TAAU
- [从One Pass Deferred Pipeline到One Pass Uber Pipeline](#从One Pass Deferred Pipeline到One Pass Uber Pipeline)
-
- 渲染管线简介
- OPDS在MALI上的指令异常(第一个坑)
- [From OPDS Pipeline to One Pass Uber Shading Pipeline](#From OPDS Pipeline to One Pass Uber Shading Pipeline)
- [OPDS在Adreno GPU GLES 下的写带宽异常(第二个坑)](#OPDS在Adreno GPU GLES 下的写带宽异常(第二个坑))
- 树的双端方案
更多参考文章: UE TAAU详细解析 - 知乎 (zhihu.com)
Why Deferred Shading
选了Deferred Shading之后AA只能选后处理AA了
AA之前:
移动端高质量的TAAU
渲染流程
增加了Velocity Pass,把TAA Pass变为了 TAAU Pass
Ghost和Flicker优化,一些图像空间算法的融入
Ghost问题优化:
同时实现这三种模式。低配置上会选RGB颜色空间来做,而高配置会选YCocg来做
第一部分是关于速度,速度编码到了24位的一个RGB里去了。第二部分是记录遮罩是不是角色的,这样更不容易产生鬼影和染色问题。
因为没有把勾边Pass渲染Velocity Buffer,这样会导致角色上有很多黑边,在做TAA的时候Character Mask判断它不是角色的一个像素。对卡渲来说,渲染一个角色要五六遍。蒙皮更严重,每一次渲染都需要蒙皮两次,因为需要上一帧的位置和当前帧的位置才能得到它的速度。所以去掉了Velocity Buffer勾边渲染。去掉之后会导致角色边缘闪烁的比较厉害。
Flicker问题优化:
动静态像素的差异处理
尝试一:使用运动速度插值动态静态两套权重
最终权重是根据Velocity的值的大小进行插值的。像素运动越快,当前帧的权重就越大。像素运动越慢,当前帧的权重就越小。
尝试二:图像的锐化算法
主要是为了处理动态像素。例如Unsharp Masking Kernel。它也是十字星的采样,所有可以重用之前的采样数据。
TAAU之Upscale简介
一般图像在做上采样的时候,考虑的是目标像素到原像素的距离来做一个权重的插值。但是FSR等除了考虑这个距离,还会考虑原像素本身的一些情况。Lanczos2用的是多项式的一个逼近。
总结及其他的一些优化和结果:
混合方案:实现了经典TAA算法,同时又融入了一些图像处理的方式与方法
从One Pass Deferred Pipeline到One Pass Uber Pipeline
渲染管线简介
GBuffer的结构:
第一版:三张GBuffer+一张SceneColor+一个DepthBuffer (Depth Fetch获取深度信息)
三种材质Scene Color存的都是自发光;GBufferA存的是法线、LightFunction(做云层投影用)和一个通道的卡渲信息;GBufferC存的是BaseColor和AO的信息;GBufferB每种都不太一样,存的是一些特化的信息
OPDS在MALI上的指令异常(第一个坑)
上面方案在arm的mali gpu的测试结果:
发现三个灯光pass的指令数都非常高,FPK失效。进一步分析发现是Depth Fetch的问题会导致FPK失效(从1.2兆变为0.01兆)。
From OPDS Pipeline to One Pass Uber Shading Pipeline
上述问题的解决方案 - 混合方案:OPDS+Forward前向卡通渲染+Gbuffer重新编码(把原来的depth编码到GbufferB里面去)
最终放在了Lighting Passes之后
OPDS在Adreno GPU GLES 下的写带宽异常(第二个坑)
发现是引擎RHI实现有个小的Bug导致的(UE4才有的问题,UE5没有)
只对SceneColor和Depth生效,会把GBuffer三张都给Resolve出来
修改后:所有的RT和Depth都是可以Discard掉的
测试带宽结果:
树的双端方案
多平台适配框架简介:
整体方案
Billboard Tree
把原来插片树的面向相机的每一丛树叶都变成一个billboard来替代
测试结果:Billboard树只要30%~40%的面片占用就可以达到插片树效果的还原,但是阴影会跟着相机转动。渲染的时候让阴影面向光源而不是面向相机就可以解决。
Imposter Tree
Imposter树原理:围绕模型放一圈相机去拍这个树,记录树的一些基本渲染信息,渲染的时候通过相机的方向去采一些最接近当前相机方向的离线渲染出来的信息去做信息合成,最终生成当前相机下应该出现的样子。
Dynamic Texture Array & Streaming
扩展了UE默认的Texture Array做成了动态Texture Array,可以按需增加Slice进来
Depth还原:
光影效果对比:
蓝色效果为Imposter树,其他为模型树
优化结果测试: