[程式]UE5中的渲染技术演讲笔记 by EpicChina

楼主: dorgonman (dorgonman)   2022-08-12 20:49:08
blog版本:http://dorgon.horizon-studio.net/zh/archives/1734
========================================================
花了一些时间把EpicChina在2022台北游戏开发者论坛的演讲看完并做了一些笔记。
题目是关于UE5中的渲染技术。
只是看完影片后觉得资讯量太多,脑袋呈现完全爆炸状态……然后影片结尾听到讲者说这
只是很粗浅的介绍后我就崩溃了。
虽然以下笔记很多内容我都还有点消化不良而且可能也有理解错误的地方,但不管怎么样
先分享出来给需要的人。
想更进一步知道细节的推荐大家去看演讲,不能只有我崩溃。
https://www.twitch.tv/videos/1533064361 1:54:37秒 开始
1. 在nanite中大小三角形会分别用软硬件做,大的用硬件做,小的为了避开overshading
的问题,他自己用compute shader写了rasterization。为什么呢?在三角型在算pixel的
颜色时,由于顶点不会刚好在pixel的中间,因此他必须相邻的4个pixel拉进来,用一个
Quad为单位来考虑。当你的三角型很小而且紧密时,某些pixel会一直反复被拉进去做计
算,这情况称之为Overshading或者是Quad OverDraw。而Nanite为了解决这个问题,因此
大的三角型虽然还是靠硬件做,但小的三角型则是自己用软件做,在Compute Shader中写
rasterization。小的三角型有一些条件需要达成才会被归类为小三角型。
Quad OverDraw补充:在三角型在算pixel的颜色时,由于顶点不会刚好在pixel的中间,
因此他必须相邻的4个pixel拉进来,用一个Quad为单位来考虑。当你的三角型很小而且紧
密时,某些pixel会一直反复被拉进去做计算,这情况称之为Overshading或者是Quad
OverDraw。
2. 整套技术的重点在Cluster生成、Culling跟LOD的选择,为了高效的达成Culling跟LOD
的选择,引擎从4.22开始就把整个render底层换成retained mode,就是说让GPU去维护整
个场景render object的一些状态。 这边是GDC2019演讲。
3. LOD的生成机制,其实就是先做graph partition算法做cluster分组,然后不断的递
回减半面数,最终生成一个DAG(Directed Acyclic Graph)。Graph partition的分群的给
定条件是共享的边尽可能的少,面积尽可能的均匀。这出来的结果是每下一级LOD都会是
最小的变化,也就是说外观的变化最小。而衡量外观变化的标准就是使用QEM(Quadric
error metric)。
4. QEM这个衡量标准可以保证我们减面后的error会越来越大,从DAG的Root到Leaf Node
,记录在节点中的error值可以帮助我们做LOD的选择。
5. 每个Cluster的BoundingBox都会再各别对每级的LOD个别生成
BVH(BoudingVolumeHierarchy)后,再挂到一个大的BVH root下面,因为这样gpu的入口会
比较一致。每4个Cluster会组成一个cluster group,最终这个nanite模型会是一个
cluster的BVH结构。
6. Culling会利用分群后的资讯进行,经过以下步骤:
a. Instance Culling:用上一个frame的HZB做跟BoundingBox来做剔除,得到一个粗略的
可能还可见对象的instance。
b. Hierarchical culling:利用Cluster group组成的BVH再去Culling掉大部份不必要的
cluster
c. Cluster Culling:最后存活下来的Cluster我们再进去做实际的Culling。
7. Raster binning:根据需不需要顶点动画以及三角形的大小分成不同的binning喂进不
同的pipeline,静态的nanite mesh基本上进HW Raster passes(硬件)的fixed vertex
pipeline ,需要顶点动画进programmable vertex shader以及太小的三角型进SW
Raster Passes(软件)。
补充: 目前5.0版本Nanite不支援skeletal animation、morph target、material的
mask & translucent以及vertex animation,因此这边提到的programmable vertex
shader看起来就是在5.1 Roadmap中提到的新架构,在5.2以后上面提到的这些限制可能都
会开始支援。
8. RebuildHZB:利用上个步骤基于上个frame HZB的culling,跟这个frame的HZB,但还
没被处理过的对象,重新再跑一次整个Culling流程,生成这个frame的visibility
buffer后,喂进material pass,生成最终的G-Buffer,用于跟传统的管线结合在一起,
作为最后光照render来用。
9. 整体来看流程分为以下三个部份:
a. Culling:包括LOD的选择
b. raster binning:分组以决定怎么做rasterization的管线
c. Rasterization:生成visibility buffer,进而给后面的material pass生成G-Buffer
用。
10. 这边比较特别的地方是,不管软件或硬件的rasterizatoin,最终都还是透过
compute shader把结果写入visibility buffer(利用atomic64保证操作不会有race
condition),硬件rasterization只是用了他的rasterization的能力,最终并没有用硬件
的深写入机制,因为这样的话就可以同时对二个软硬件的computer shader做平行处理。
11. Nanite的材质假设每个mesh大部份情况下只用到3个材质,虽然unreal最多支援到64
个,但如果你mesh小于3个材质时他会把资讯压缩进cluster上,超过的话会需要去另外一
个global的表上找,效率会比较低。
12. 搭配nanite的技术之后,我们可以使用Virtual Shadow Map的技术,他可以帮我们解
决因为shadow map精度不够而产生的漏光跟shadow acne的现象。
13. shadow acne是指目前的深度指跟shadow map中的值很接近的时候产生的
self-shadow artifact,在地形上会呈现条纹状,要手动调整shadow bias,但这个值调
大了之后,角色或物件的影子又会浮空。使用virtual shadow map就不需要手动调整了。
14. Virtual Shadow Map,粗暴的理解,其本质上就是一个精度非常高的Shadow Map。对
于所谓的局部光源,使用了16x16K的virtual shadow map,每个都有8级的mipmap。对于
点光源,因为他是cube map,所以他有6张这样的virtual shadow map。对于方向光,他
们发现就算是用17级的16k mipmap都不够,因此他另外用一个叫clipmap的技术。
15. Clipmap跟mipmap的区别是,他不降分辨率,而是覆蓋的区域翻倍。
16. virtual texture默认的TileSize是128X128,最远的那一级会覆蓋将近80公里左右的
范围,我们可以调tile size来调整。
17. 为了提高效率,加载进来的virtual texture会用page的概念来做cache,只是一有光
线变化,我们所有的page cache都会被invalid掉,所以在做time of day光线变化效果时
,一般会建议不会每个frame去更新。
18. 关于page cache的另外一个策略是把动态跟静态对象分PhysicalPagePool存,虽然
pool size会翻倍,但可以避免因为树跟草这些有顶点动画的影子把我们的cache invalid
掉。
作者: rhox (天生反骨)   2022-08-12 21:37:00
推,改天来仔细看,理解基础逻辑对开发蛮有用的
作者: rurumi0318 (C萌的把拔)   2022-08-12 21:42:00
推,刚开始以为只是概略的技术介绍,结果挖下去超深的
作者: coolrobin (泳圈)   2022-08-12 21:46:00
先推不看 (疑
作者: nicetw20xx (哇爱台湾)   2022-08-15 22:15:00
推大大分享
作者: a82611141   2022-08-17 02:35:00
作者: superweak   2022-08-21 21:16:00
作者: rickkcir (多果汁)   2022-08-26 08:31:00
推分享

Links booklink

Contact Us: admin [ a t ] ucptt.com