[程式][演讲笔记]UE5 Mobile Deferred Render

楼主: dorgonman (dorgonman)   2022-09-03 17:32:15
部落格版本:http://dorgon.horizon-studio.net/zh/archives/1768
发现大家蛮喜欢看这种演讲笔记的,因此花了一些时间把EpicGameChina关于Mobile Deferred Render的演讲看完并做了一些笔记
,分享给大家,也推荐大家去看影片,我是觉得收获蛮多的。
影片在此:https://www.youtube.com/watch?v=GQoSjEii4nk
1. Mobile Deferred Render直到5.1才算比较成熟
2. Deferred的优势在于可以减少shader permutation,因为在base pass不用算lighting
,因此相关的permutation就可以从model material直接decouple出来,省下大量的
shader数量。
3. mobile deferred vs mobile forward在关掉static lighting的比较:
a. Mobile Deferred只需要建出LMP_NO_LIGHTMAP一种caseb. Mobile Forward则
需要建出LMP_NO_LIGHTMAP跟LMP_MOBILE_DIRECTIONAL_LIGHT_CSM搭上
bEnableLocalLights开关,总共有四种case。
c. Mobile Deferred的shader总量是Mobile Forward的1/4。
d. LMP指的是LightingMapPolicy,所有的Type参数ELightMapPolicyType这个
enum
4. mobile deferred vs mobile forward在打开static lighting后大约是原本的1/5大

5. 减少Shader大小代表我们打包出来的pak变小,而且也能降低内存的使用量,另外
也可以减少因为run-time compiling shader所造成的卡顿。
a. 注:run-time compiling shader的卡顿可以使用PSO Caching的机制解决,
只不过这个方法会要求团队在打包之前先跑一次版本以记录用到的材质。
6. Deferred Render因为base pass没有复杂的光照计算,因此这阶段的开销比forward
减少很多,而且光照只在可见的pixel上做计算,不会浪费GPU在不可见的pixel上,理论
上对于减少GPU压力是有帮助的。
a. 不过现在的芯片大多内建了减少OverDraw的技术,例如PowerVR GPU的
Hidden Surface Removal,以及Arm GPU的Forward pixel kill,即便如此,在某些
device上还是能有明显的收益的。
7. Deferred Render可以把原本Foward要保留给光照用的Sampler让出来给美术使用,最
多能多出6~7个Sampler。大致上的数量如下
a. Reflection capture可以减少1到2个
b. Shadow texture减少1个
c. Planar reflection 1个
d. Light grid data减少3个。
8. 虽然Deferred Render需要创建多张G-Buffer,但我们可以利用tile-based GPU的特
性,把GBuffer分配在Tile Memory上,这样就可以不需要用到System memory,从而减少
传输成本。只不过这招会让我们无法在PostProcess存取到GBuffer的资料,这也就是为什
么目前mobile不支援screen space reflection的原因之一。
9. 以下功能是Deferred Render才有的功能:
a. Lit deferred decal:forward的decal是无光照的,而deferred render因为
有了GBuffer,可以靠上面的资料来计算光照效果。
b. IES Profile
c. Light Function
d. Better EnvBRDF:Deferred的效果上会更阅近PC,不需要real-time计算,只
需要做一次贴图采样就行了,因此性能更好;而foward因为要省下一个sampler,因此采
用的是近似的版本在real-time做计算。
10. Deferred Render在Android手机上有遇到一些兼容性问题,因此在设计系统时会考
虑以下几个限制。
a. 对于OpenGLES的支援:由于Mali不支援MRT(Multiple Render Targets)的
FrameBufferFetch,因此使用了Pixel Local Storage的技术,但用了这个技术的限制是
,它只有128 bit。
b. 对于Vulkan的支援:调查了市面上的Android手机,发现有16%左右的机器只
支援4个Input Attachment。
11. 由于GBuffer和SceneDepth都会算在InputAttachment上,为了支援16%只有4个
Input Attachment的机器,引擎只能把GBuffer的数量控制在3个,再加上一个SceneDepth
就到了4个上限。不像PC可以创出5张或更多的GBuffer来支援一些效果。
12. 每个平台都会有以下几个Buffer:SceneColor、SceneDepth以及GBufferA、
GBufferB、GBufferC。其中SceneDepth如果PP用不到就不需存下来以节省频宽。
13. 在Android Mali OpenGLES上我们是把GBuffer利用Pixel Local Storage存在Tiled
Memory上,再加上32bit的SceneColor,刚好占满Pixel Local Storage的128 bit。
14. Vulkan或Qualcommon的GLES手机,我们是用Memoryless的方式把GBuffer建立在
TileMemory上。
a. 注:Memoryless代表该份资料只会存在于TileMemory而不会回存到System
Memory,这也就代表PostProcess存取不到GBuffer上的资料。
15. 在IOS或其他PowerVR的Android GLES手机:因为GPU不支持DepthBufferFech,只能
用MRT的FrameBufferFetch,所以只能新申请一张32bit的DepthAux来存Depth。DepthAux
跟GBuffer一样是memoryless,所以不占回写到System Memory的频宽,只是需要处理一下
shader fetch depth的逻辑。
16. 在UE4中不支援shading model只能支援defaultLit,要支援shading model的话,就
要必须要有至少4个通道来存储custom data,最好每个通道都有8 bit,不然精度不太足
。正常情况下我们可以多申请GBuffer来达成这件事,但是因为硬件的限制只能有4个
Input Attachment,所以我们只能想办法挖东墙补西墙。
17. 前提是,在Mobile Deferred Render上我们我们只有GBufferA、GBufferB、
GBufferC,每张Buffer都有32 bit,里面各别存了下面资料:
a. GBufferA:
Encoded Normal.xy:由于normal的z可以靠cross product算出来,因此只
需要xy二个通道就行了,但由于normal在某些情况下需要比较高的精度,例如在一些反射
比较好的效果下,如果只用8 bit可能会看到一些瑕疵,因此xy各别用10 bit保存,共20
bit。
ShadingModelID:占用4 bit。
PerObject Data:在Mobile中没有使用
b. GBufferB:Metallic、Specular、Roughness以及Indirect Irradiance,各
别占用8 bit。
c. GBufferC:BaseColor.RGB占用24 bit、Precomputed Shade 8 bit。
18. 以上资料有一些东西可以省下来让给CustomData用
a. GBufferA:PerObject Data有8 bit在Mobile中没有使用,可以拿出来。
b. GBufferB中的Metallic在很多ShadingMode中没有用到,可以拿出来。
c. GBufferB跟GBufferC中的Indirect Irradiance只在静态光照下用到,限制只
能开动态光的话就能拿出来给CustomData用。
d. 以上共4个通道可以在只有动态光条件下空出来给CustomData
19. 影片上有详细讲解Buffer Layout里面各别存了什么东西的细节,建议大家去看。
20. 目前UE5.1中在关掉静态光的情况下已经可以支援所有的Shading Model
21. Eye shading model有一点特殊,它用到了subsurface profile shading model,所
以在Mobile上它用了5个custom data,所以我们就只能把其中二个custom data压缩到一
个通道里。所会如果看到结果感觉到精度不足,很有可能就是这个原因。
22. 由于GBuffer已经把Tiled Memory都占用了,因此不能使用MSAA,因此目前引擎只支
援FXAA跟TAA跟5.1新增由AMD研发的FSR技术。虽然FSR的效率上比不上有硬件支援的MSAA
,不过效果不差。
23. 补充FSR:由官网的资料看来,他是个可以用在全平台的技术,不像NVDIA的DLSS需要
用到GeForce RTX上专门的Tensor核心。
24. 关于lighting跟shadow的支援状况:
a. Directional light pass:支援Light function material、Clustered
local light(runtime toggle:r.Mobile.UseClusteredDeferredShading)、planar
reflection、CSM and distance field shadow以及Reflection。
b. Reflection and sky pass:如果只有一个方向光就会合并到Directional
light pass里一起做(inline),不然为了避重复计算会统一在这个pass做。
c. Local Light pass:Light area masked with stencil、support movable
spot light shadow、support IES Profile、Support light function。Local light是
分二次绘制的,第一次是用stencil 报标记灯光所覆蓋的区域,第二次是在这个区域的像
素里去着色,也是为了性能优化。
d. Simple light pass:这个是粒子里创建的简单光源,通常它是在clustered
local light阶段绘制的,如果没有开启clustered local light,才会有自己的pass。它
的过程和local light的pass类似。
25. 在UE5.1中,mobile上也支持了Deferred render lighting channel,不过我们的方
式跟PC上的不太一样,因为PC上是把Lighting channel写到stencil buffer里,然后在
shader里面去读取,这个对于mobile device来说有点困难。因为OpenGLES不支持
TextureView的扩展,所以我们在硬件上就是直接在stencil test上做。
26. 在硬件上就是直接在stencil test上做的方法如下:我们只遍历所有的灯光,只做一
次lighting channel的stencil test。但由于每一盏灯只支持一个lighting channel,如
果有多个lighting channel的话就会出错。这也是美术上需要留意的地方。
27. 关于优化,我们主要是做了以下二个优化
a. 只在必须的情况下才去把数据存下来,比如DepthAux,我们直接申明成
memory less,又因为我们不支持MSAA,所以GBuffe也可以弄成memory less。还有就是
SceneDepth,只在需要的时候才用到,如果PP阶段没有用到Depth的讯息我们就可以不用
存下来。
b. 另外我们发现开启deferred rendering之后,半透明阶段的渲染耗时比以前
高,后来是发现是因为半透明阶段,默认也开了Clustered local light和Clustered
reflection,这个对性能有比较明显的影响。然后我们本身对于半透明的光照和反射效果
的需求并没有那么高,所以我们在半透明阶段关掉这些计算,这样半透明的效率就和
forward持平了。
28. fornite在season 22会开启,有做了初步的测试,发现,如果用vulkan的话性能会
有普遍改善、卡顿变少,不过OpenGLES测下来发现性能会变差,后来发现是因为DXC转译
Shader有点问题导致性能下降,并不是因为deferred rendering的问题,后续会修覆之后
再针对openGLES打开
作者: coolrobin (泳圈)   2022-09-03 18:06:00
未看先推
作者: kingroy (手残总比脑残好)   2022-09-04 10:26:00
推一个最近也在看

Links booklink

Contact Us: admin [ a t ] ucptt.com