【逆向】UE4 渲染流程分析

UE4做爲當今商業引擎界的大佬,渲染和圖形質量一直是數一數二的水準,可是相對於unity來講UE4基本上是一套完整方案提供,不經過源碼修改對渲染進行定製的可能性比較小,並且同時UE4這方面的文檔不多,所以這篇文章就是想經過分析UE4的渲染過程,來給你們針對本身使用ue4開發的遊戲的內容特色作出優化帶來啓發。函數

咱們使用Renderdoc對UE4(PC,DX11)截幀,UE4的版本爲4.18. 能夠看到UE4一幀畫面的渲染過程以下優化

圖片描述

能夠看到的是整個渲染流程仍是很清晰明瞭的,接下來就會逐步分析每一個過程。spa

1.Z-Prepass
UE4在deferred shading 過程以前這個,會有一系列的culling過程剔除掉不須要的像素或者幾何體,基本上能夠猜想是UE4是爲了減輕後期在deferred shading gbuffer 生成中的龐大計算量,第一遍的zpass會先渲染一遍場景中的幾何,用於生產SceneDepthZ以及HZB buffer,格式爲R24G8TYPELESS設計

2.Compute light grid
在Pre-Z以後UE4會把場景中的燈光按照屏幕空間分紅相應的grid,相似於cluster shading的方法,注意這裏的grid只考慮點光源,聚光燈,以及reflection captures,UE4這一步是經過compute shader實現的,因此只在sm>5.0的平臺上有。具體shader代碼在LightGridInjection.usf,閱讀代碼以後咱們能夠發現 UE4的燈光空間grid的劃分是按照指數增加的。也就是每一個grid的z隨着距離會增加。
在真正計算光照時,咱們能夠用GridIndex來快速決定某點是否受到燈光影響。
Lightculling的方法在forward下對於提升燈光的渲染效率是十分有用的,但UE4在DS下仍然保有了這一個過程。其效果存疑,初步推測是爲了和UE4新加的Forward renderer統一。3d

3.Occlusion query
這一步在light culling以後,和Pre-Z pass 不一樣的是,Occlusion query 主要在物體級別作culling。ue4一樣使用的是hardware occlusion queries(GPU query)的技術。在這一個pass中,全部的不透明物體會被渲染爲一個occluder(包圍盒):
Occlusion query幾何體orm

在根據深度計算query以後,query的數據會傳回cpu,咱們就能夠計算每一個物體有多少像素可見。這樣咱們就能知道物體最終是否會被渲染htm

在不透明物體的query pass以後。Unreal 還有一些其餘的query pass,例如燈光(點光源)會有一個ShadowFrustumQUeries(通常是畫一個球體)反射則有 PlanarReflection queries(通常是畫一個
Cube)blog

4.HZB generation
接下來UE4會生成場景的Hi-z(Hierarchical Z),R16_Float 格式,這一步也就是對以前的zbuffer作連續的downsample。HZB buffer會在以後的計算中起到不少做用,特別是Image based 的lighting技術,例如SSR等等。遊戲

5.ShadowMap 渲染
接下來的一步就是渲染shadowmap(shadowDepth,注意,這裏指的是實時陰影的計算。根據UE4中燈光類型的不一樣,實時陰影的計算也有必定的差異。
UE4中的燈光類 型分爲stationary, static,moveable三種,相應的每種燈光cast realtime shadow的方式也不一樣。
對於stationary light,靜態物體的陰影會bake到static shadowmap,shadowmap只計算標記爲動態物體的陰影,而對於dynamic light 會對全部物體投射陰影,而靜態燈光不會產生實時陰影。圖片

ue4首先會渲染方向光的陰影,通常會渲染3split的cascade shadow ,因此咱們能在截幀信息看到split0, split1和split2,注意cascade split數目在ue4中也是能夠在方向光參數中設置的變量。
圖片描述

以後是stationary light的shadow渲染,注意這裏只針對場景中的moveable的物體。

最後是對於movable light的渲染,對於movable的方向光,ue4仍然是cascade shadow map計算陰影,須要注意的是對於movable的點光源,ue4使用了cubemap shadowmap,在cubeshadowmap的第一個pass CopyCachedShadowMap中,ue4會直接cachecopy static物體的shadowmap,例如這個場景中
圖片描述

圓柱體爲static,其餘兩個物體設爲movable,所以最後咱們能看到Shadow 只畫了兩個幾何體。
圖片描述

最後動態物體的shadow會添加在這個cubemap上面。

圖片描述
圖片描述

注意 shadowcubemap使用了geometry shader來選擇畫在那個面上。

6.G-prepass
其實在g-prepass以前還會渲染一個volumtric fog(若是場景中有的話) 這裏咱們先跳過,
G-prepass就是ue4中常說的basspass,這個bass會真正的渲染場景併產生咱們在deferred shading 中須要的G-buffers:
圖片描述
SceneColorDefferd:包含了間接光照信息,例如lightmap和lightprobe(ue4叫ILC)

圖片描述
場景Normal

圖片描述
場景Albedo顏色

圖片描述
PBR Specular信息

除此以外還有針對特殊shading模型的特殊Custom Data RT(例如 頭髮的tangent sss等)和Pre baked shadow factors RT,通常狀況下UE4的渲染須要5-6個RT輸出,除了產生GBuffer的計算以外,在這一步UE4還會計算完間接光照的信息,主要包括採集lightmap信息(靜態物體)和球諧函數信息(Indirect lighting cache或者Volumetric light map)
UE4在4.18引入了新的半動態光照技術也就是Volumetric lightmap,相比於以前的 ILC機制,Volumetric lightmap可以更加細緻的根據物體的空間位置對球諧函數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.注意最後計算的結果會乘到SceneColorDeferred這個RT上.
圖片描述
9.Lighting

接下來就是光照的渲染部分,UE4在渲染燈光光照時會先處理translucent 物體的照明。

在這以後會分別計算陰影燈光和非陰影燈光的standarddeferredlighting,

在這個pass以後,SceneColorDeferred RT就會包含最後直接光照的結果
圖片描述

10.ImageBased lighting

接下來UE4會渲染屏幕空間的一些光照效果,例如SSR(屏幕空間反射)還有ReflectionProbe等等

SSR會用到咱們以前生成的HZB,在屏幕空間作Zbuffer的raymarching ,同時ue4的SSR會每幀jitter和TAA結合來提升質量。當擊中時SSR的shader會採樣上一幀的RT來得到顏色
圖片描述
在SSR以後是ReflectionEnvironment Pass。這一步會結合場景中的反射球和以前的SSR結果會疊加到SceneColorDeferred這個RT中。

11. Post Processing
最後一步是UE4的Postprocessing,主要包括Temporal AA; Bloom;EyeAdaption等等這些能夠自定義的內容,

UE4 的TAA會經歷兩個pass,第一個pass會處理沒被stencil的像素(例若有粒子特效的時候),會用到MainRT和velocity buffer,第二個pass會處理例如粒子這樣stencilled的pixel。兩個pass的區別在於混合當前RT和History buffer的blendfactor的不一樣,第一個pass的blendfactor會根據pixel的亮度距離等等變化,而第二個pass的blendfactor嘖固定爲0.25,也就是說第二個pass的像素會更多考慮當前像素,極可能這是爲了減小TAA中很常見的ghosting effect

注意:TAA的處理只包含動態的光照部分,也就是純動態光照。
圖片描述

以上的分析仍是省略了不少的細節,例如半透照明這種還沒涉及。從總體的流程分析來看,UE4在設計渲染方案的時候仍是最大限度的考慮了功能的最大化,UE4的DS renderer包含了很是齊全的光照特效,包括靜態的lightmap,動態的lightprobe,屏幕空間的lighting,以及一些影視級別的渲染技術,例如頭髮的渲染模型等等,但同時爲了功能UE4的計算任務是很繁重的,所以也就不難理解爲何UE4須要Pre-Z和Occlusion Culling去剔除掉不用的像素。固然,對於使用UE4製做遊戲的團隊來講,根據遊戲內容特色,畫面的藝術風格,渲染管線都不必一成不變,例如對於一款開放世界的野外生存遊戲。咱們能夠考慮省掉Pre-Z的過程,或者,只用地表去畫Pre-Z,又或者對於NPR畫面的遊戲咱們徹底能夠不須要6-7個RT去作Deferred shading。UE4應對這些定製化開發的需求的方法就是:開源。代碼就在DeferredShadingRenderer.cpp裏。

相關文章
相關標籤/搜索