虛幻引擎 4 渲染流程分析
今天為大家?guī)淼氖寝D(zhuǎn)載自虛幻引擎愛好者王文濤的博客文章《虛幻引擎 4 渲染流程分析》,這篇文章通過 Renderdoc 的分析通俗地介紹虛幻引擎 4 的渲染過程。
UE4作為當(dāng)今商業(yè)引擎界的大佬,渲染和圖形質(zhì)量一直是首屈一指的水準(zhǔn),但是相對于unity來說UE4基本上是一套完整方案提供,不通過源碼修改對渲染進(jìn)行定制的可能性比較小,而且同時UE4這方面的文檔很少,因此這篇文章就是想通過分析UE4的渲染過程,來給大家針對自己使用ue4開發(fā)的游戲的內(nèi)容特點(diǎn)做出優(yōu)化帶來啟發(fā)。
我們使用Renderdoc對UE4(PC,DX11)截幀,UE4的版本為4.18. 可以看到UE4一幀畫面的渲染過程如下
可以看到的是整個渲染流程還是很清晰明了的,接下來就會逐步分析每個過程。
1.Z-Prepass
UE4在deferred shading 過程之前這個,會有一系列的culling過程剔除掉不需要的像素或者幾何體,基本上可以猜測是UE4是為了減輕后期在deferred shadinggbuffer 生成中的龐大計算量,第一遍的zpass會先渲染一遍場景中的幾何,用于生產(chǎn)SceneDepthZ以及HZB buffer,格式為R24G8TYPELESS
2.Compute light grid
在Pre-Z之后UE4會把場景中的燈光按照屏幕空間分成相應(yīng)的grid,類似于cluster shading的方法,注意這里的grid只考慮點(diǎn)光源,聚光燈,以及reflection captures,UE4這一步是通過compute shader實(shí)現(xiàn)的,所以只在sm>5.0的平臺上有。具體shader代碼在LightGridInjection.usf,閱讀代碼之后我們可以發(fā)現(xiàn) UE4的燈光空間grid的劃分是按照指數(shù)增長的。也就是每個grid的z隨著距離會增長。
在真正計算光照時,我們可以用GridIndex來快速決定某點(diǎn)是否受到燈光影響。Lightculling的方法在forward下對于提高燈光的渲染效率是十分有用的,但UE4在DS下仍然保有了這一個過程。其效果存疑,初步推測是為了和UE4新加的Forward renderer統(tǒng)一。
3.Occlusion query
這一步在light culling之后,和Pre-Z pass 不同的是,Occlusion query 主要在物體級別做culling。ue4同樣使用的是hardware occlusion queries(GPU query)的技術(shù)。在這一個pass中,所有的不透明物體會被渲染為一個occluder(包圍盒):
在根據(jù)深度計算query之后,query的數(shù)據(jù)會傳回cpu,我們就可以計算每個物體有多少像素可見。這樣我們就能知道物體最終是否會被渲染。
在不透明物體的query pass之后。Unreal 還有一些其他的query pass,例如燈光(點(diǎn)光源)會有一個ShadowFrustumQUeries(一般是畫一個球體)反射則有 PlanarReflection queries(一般是畫一個 Cube)
4.HZB generation
接下來UE4會生成場景的Hi-z(Hierarchical Z),R16_Float 格式,這一步也就是對之前的zbuffer做連續(xù)的downsample。HZB buffer會在之后的計算中起到很多作用,特別是Image based 的lighting技術(shù),例如SSR等等。
5.ShadowMap 渲染
接下來的一步就是渲染shadowmap(shadowDepth,注意,這里指的是實(shí)時陰影的計算。根據(jù)UE4中燈光類型的不同,實(shí)時陰影的計算也有一定的差別。
UE4中的燈光類 型分為stationary, static,moveable三種,相應(yīng)的每種燈光cast realtime shadow的方式也不同。
對于stationary light,靜態(tài)物體的陰影會bake到static shadowmap,shadowmap只計算標(biāo)記為動態(tài)物體的陰影,而對于dynamic light 會對所有物體投射陰影,而靜態(tài)燈光不會產(chǎn)生實(shí)時陰影。
ue4首先會渲染方向光的陰影,一般會渲染3split的cascade shadow ,所以我們能在截幀信息看到split0, split1和split2,注意cascade split數(shù)目在ue4中也是可以在方向光參數(shù)中設(shè)置的變量。
之后是stationary light的shadow渲染,注意這里只針對場景中的moveable的物體。
最后是對于movable light的渲染,對于movable的方向光,ue4仍然是cascade shadow map計算陰影,需要注意的是對于movable的點(diǎn)光源,ue4使用了cubemap shadowmap,在cubeshadowmap的第一個pass CopyCachedShadowMap中,ue4會直接cachecopy static物體的shadowmap,例如這個場景中
圓柱體為static,其他兩個物體設(shè)為movable,因此最后我們能看到Shadow 只畫了兩個幾何體。
最后動態(tài)物體的shadow會添加在這個cubemap上面。
注意 shadowcubemap使用了geometry shader來選擇畫在那個面上。
6.G-prepass
其實(shí)在g-prepass之前還會渲染一個volumtric fog(如果場景中有的話) 這里我們先跳過,
G-prepass就是ue4中常說的basspass,這個bass會真正的渲染場景并產(chǎn)生我們在deferred shading 中需要的G-buffers:
SceneColorDefferd:包含了間接光照信息,例如lightmap和lightprobe(ue4叫ILC)
場景Normal
場景Albedo顏色
PBR Specular信息
除此之外還有針對特殊shading模型的特殊Custom Data RT(例如 頭發(fā)的tangent sss等)和Pre baked shadow factors RT,一般情況下UE4的渲染需要5-6個RT輸出,除了產(chǎn)生GBuffer的計算之外,在這一步UE4還會計算完間接光照的信息,主要包括采集lightmap信息(靜態(tài)物體)和球諧函數(shù)信息(Indirect lighting cache或者Volumetric light map)
UE4在4.18引入了新的半動態(tài)光照技術(shù)也就是Volumetric lightmap,相比于之前的 ILC機(jī)制,Volumetric lightmap能夠更加細(xì)致的根據(jù)物體的空間位置對球諧函數(shù)probe做插值(ILC是每個物體做插值)
Volumetric lightmap的Texture3d
7.Velocity rendering
在basepass之后是Velocity rendering,Velocity buffer會渲染為一張R16B16UNorm,主要用于motion blur和TAA
8.Pre-Lighting
UE4在這一部分會計算DeferredDecal(屏幕空間貼花),和AmbientOcclusion, UE4的屏幕空間AO考慮了深度和Normal信息,UE4的SSAO分為兩個Pass,第一個pass會計算一個四分之一分辨率的RT,使用的是四分之一分辨率的normal和depth, 注意這里就用了之前生成的HZB buffer,第二個pass會渲染一個全分辨率RT并與第一個combine.注意最后計算的結(jié)果會乘到SceneColorDeferred這個RT上.
9.Lighting
接下來就是光照的渲染部分,UE4在渲染燈光光照時會先處理translucent 物體的照明。
在這之后會分別計算陰影燈光和非陰影燈光的standarddeferredlighting,
在這個pass之后,SceneColorDeferred RT就會包含最后直接光照的結(jié)果
10.ImageBased lighting
接下來UE4會渲染屏幕空間的一些光照效果,例如SSR(屏幕空間反射)還有ReflectionProbe等等
SSR會用到我們之前生成的HZB,在屏幕空間做Zbuffer的raymarching ,同時ue4的SSR會每幀jitter和TAA結(jié)合來提高質(zhì)量。當(dāng)擊中時SSR的shader會采樣上一幀的RT來獲得顏色
在SSR之后是ReflectionEnvironment Pass。這一步會結(jié)合場景中的反射球和之前的SSR結(jié)果會疊加到SceneColorDeferred這個RT中。
11. Post Processing
最后一步是UE4的Postprocessing,主要包括Temporal AA; Bloom;EyeAdaption等等這些可以自定義的內(nèi)容。
UE4 的TAA會經(jīng)歷兩個pass,第一個pass會處理沒被stencil的像素(例如有粒子特效的時候),會用到MainRT和velocity buffer,第二個pass會處理例如粒子這樣stencilled的pixel。兩個pass的區(qū)別在于混合當(dāng)前RT和History buffer的blendfactor的不同,第一個pass的blendfactor會根據(jù)pixel的亮度距離等等變化,而第二個pass的blendfactor嘖固定為0.25,也就是說第二個pass的像素會更多考慮當(dāng)前像素,很可能這是為了減少TAA中很常見的ghosting effect
注意:TAA的處理只包含動態(tài)的光照部分,也就是純動態(tài)光照。
以上的分析還是省略了很多的細(xì)節(jié),例如半透照明這種還沒涉及。從整體的流程分析來看,UE4在設(shè)計渲染方案的時候還是最大限度的考慮了功能的最大化,UE4的DS renderer包含了非常齊全的光照特效,包括靜態(tài)的lightmap,動態(tài)的lightprobe,屏幕空間的lighting,以及一些影視級別的渲染技術(shù),例如頭發(fā)的渲染模型等等,但同時為了功能UE4的計算任務(wù)是很繁重的,因此也就不難理解為什么UE4需要Pre-Z和Occlusion Culling去剔除掉不用的像素。當(dāng)然,對于使用UE4制作游戲的團(tuán)隊來說,根據(jù)游戲內(nèi)容特點(diǎn),畫面的藝術(shù)風(fēng)格,渲染管線都沒必要一成不變,例如對于一款開放世界的野外生存游戲。我們可以考慮省掉Pre-Z的過程,或者,只用地表去畫Pre-Z,又或者對于NPR畫面的游戲我們完全可以不需要6-7個RT去做Deferred shading。UE4應(yīng)對這些定制化開發(fā)的需求的方法就是:開源。代碼就在DeferredShadingRenderer.cpp里。
-
分享到:
您需要登錄后才可以發(fā)帖 登錄 | 立即注冊
- 用戶名:
- 密 碼:
- 驗(yàn)證碼: 看不清? 點(diǎn)擊更換
- 忘記密碼?
全部評論:0條