日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opengl游戏引擎源码_UE4渲染引擎模块简介(1)

發布時間:2025/3/19 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opengl游戏引擎源码_UE4渲染引擎模块简介(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

UE4官方文檔中《Graphics Programming Overview》開篇即說:UE4的渲染代碼太多故難以從宏觀上快速預覽它的全貌(There is a lot of rendering code in Unreal Engine 4 (UE4) so it is hard to get a quick high level view of what is going on)。這一官方說辭從側面說明了UE4渲染引擎的復雜性是很高的,這個說法多少有點推卸責任,也頗具勸退之意。但我們自己做為一個合格的程序員,在做任何技術選型的時候最基本的要求總該是:我選的方案在其內涵和外延上至少要能貼合或拔高項目對該功能塊的需求,并且這個方案得是我能全程能Hold得住而不是挖深坑用以自埋的。在這一前提下對UE4的渲染引擎乃至UE4引擎本身做一個宏觀的整體性的評估就必不可少了。

當然UE4渲染引擎的FeatureList非常棒且推進迅捷,所以在功能性和前瞻性方面往往大超項目預期,往往并不是評估的重點。許多公司之所以選UE4做為項目的引擎必選項,是因為老板看到基于UE的吃雞大熱,UE4所產出的其它產品和宣傳視頻也驚艷絕倫,于是乎腦袋一熱雙手一拍,技術人員就麻著膽子硬著頭皮,戰戰兢兢開始玩弄UE(或者說被UE摁在地上摩擦了)。

本文的內容是從渲染引擎的宏觀功能上羅列UE4的覆蓋面和劃分方式,尚不會涉及到具體每個功能模塊的實現細節。本文在討論渲染模塊的時候還假設大家均具備這些圖形引擎常識:渲染API的功能范疇、如何組織基礎的渲染管線、夸平臺圖形引擎需要基礎框架支持的最小集。

先從頂層來看一次完整的渲染

給渲染器輸入以原始的幾何和材質數據,渲染器把幾何和材質數據轉換為渲染API所支持的數據、渲染狀態、Shader及Shader參數并由這些數據組裝為一個RenderPipeline,然后執行該RenderPipeline,得到渲染結果后交換到渲染的目標Context上去(如Windows下的一個窗口,Android下的一個View等)。一個3D渲染引擎的核心工作就是組織好這一宏觀上的工作流,使其最大化利用目標平臺的硬件資源(CPU,GPU,內存,硬盤或閃存等)和特性,使其使用最便利、性能最優,效果最佳。

UE4的渲染系統也不例外,所以我們的渲染功能的識別方式的基于以上基本過程和傳統的3D引擎功能劃分來做。UE4的模塊(Module)和我們將要討論的渲染功能模塊不存在一一對應關系,可能UE4的一兩個類即實現一個功能塊,或一個UE4的模塊(Module)除了包含數個渲染相關的功能。

UE4場景和場景管理(Scene 、SceneManager)

在UE4中不存在傳統引擎中的嚴格一一對應的Scene和SceneManager,它的實現是散落在許多類中。

傳統引擎中的Scene一般表達一個渲染用的世界。這個概念在UE4中有兩個類和它對應:用于游戲線程中的UWorld類和用于渲染線程中的FScene類.UE4中的中UWorld和FScene有一一對應關系,UWorld用于游戲線程,用于用戶的主動操作(如創建、刪除世界中的物件等),而FScene則隱藏于渲染線程,由UWorld和世界中的對象被動操作。在游戲過程中,一般只存在一個UWorld實例(在過渡的時候可能有兩個),但在編輯器形態下,一般會存在許多個UWorld對象——一般來說,一個UWorld對象表達一個單獨的編輯器窗口。

UE4和其它支持大世界的引擎一樣支持游戲場景中的物體動態加載和卸載。但它對于大世界的拆分方式是比較獨特的——UE4的場景的劃分模式不是基于物件級而是基于子關卡級來做。在UE4中,一個UWorld由一個一直存在的持久關卡(ULevel類)和多個動態加載卸載的子關卡組成。UE4中這種動態加載卸載的子關卡叫做流關卡(StreamingLevel ,ULevelStreaming類),且場景中的具體物件都是放置在關卡或流關卡中而不是直接位于UWorld中。

UE4中的流關卡的加、卸載策略實現是由UWorldComposition類來負責的。這是一個基于視點距離和流關卡卡包圍盒的簡單的加載策略實現。

用于渲染線程的FScene不具備復雜的場景管理功能,它有一些數組用于各類管理場景可渲染對象和燈光,它有兩個Octree結構用于空間的快速查詢——一個用于燈光,另一個用于其它的可渲染對象,它還有一個DrawList用于Cache各個渲染Pass的指令。

UE4場景中的物體(SceneObject)

當我們在UE編輯器中往場景里拖一個NPC,或放置一個燈光,一個后處理盒(PostProcess Volume)的時候,我們都是往該關卡中添加了一個AActor子類實例,UE4關卡和流關卡中每一個獨立物件由一個AActor及其子類的對象實例來建模表達。

AActor及其子類本身并不直接持有渲染所需的數據,AActor基于組合模式設計,可持有數個UActorComponent實例,具體的渲染相關的數據均在UActorComponent及其子類的實例中。

USceneComponent見名知義,它是UActorCompoent子類里可用于場景中的組件基類。USceneComponent有兩個主要作用:它包含Transform數據,它可以支持Attachment。

UPrimitiveComponent是USceneComponent的子類,它是所有可渲染組件的基類。它包含一系列的幾何數據,而做為附贈品,它同時也可以做為碰撞數據使用。

ULightComponentBase是USceneComponent的另一個子類,它是所有燈光組件的基類。

渲染相關的主要Component類結構層次

UE4要渲染API封裝

UE4中的渲染API封裝是個獨立的模塊(Module),他們把它命名為RHI(Render Hardware Interface)。RHI的接口定義上傾向于向最新的渲染API靠近(如DX12和Vulkan),它除了提供渲染API提供的主要接口轉發外,還對CommandList,ShaderCache、StateCache和GpuProfiler做了基本的封裝。

RHI的轉發實現在RHICommandList.h文件里,可以看到其實現除了基本的條件判斷,大都是直接 轉調渲染API實現的RHI子模塊里的渲染指令。

UE4具體的實現了以下RHI模塊的封裝

D3D11RHI ,基于D3D11 Feature的RHI封裝

D3D12RHI,基于D3D12 Feature的RHI封裝

MetalRHI,基于Metal 1和2的RHI封裝

OpenGLGLDrv ,它同時實現了Windows,Linux,Android,Ios,Web等各個平臺的Opengl,包含GL3,GL4.x和GLES2,GLES3和H5上的Feature.

EmptyRHI和NullDrv,這兩個都是對RHI的空實現

UE4的材質系統

UE4對材質系統的封裝可以理解為RenderPipiline輸入的所有數據中除了幾何體數據之外的所有其它數據。它包括渲染所需要選擇的光照模型、光照自身的照射分布函數、材質模型及該材質模型所需要的輸入參數,渲染狀態數據,為各種頂點格式和渲染分支生成的Shader,以及一個提供給用戶編輯態使用的節點圖等等。

UE4中可用于渲染的材質分為兩種:一種是材質模板(UMaterial),另一個是基于材質模板的材質實例(UMaterialInstance).這兩貨都是UMaterialInterface的子類。只有UMaterial材質模板帶有可編輯的節點圖并可拒此生成對應的Shader組合,而UMaterialInstance材質實例則只需要引用UMaterial對應的Shader.UMaterialInstance只能修改材質模板暴露出來的材質參數。

對渲染層來說,一般并不需要區分材質實例和材質模板本身。

FMaterialResource是FMaterail的子類,用于UMaterial的渲染,具體來說FMaterialResource負責為各個渲染API和材質所支持的各種質量等級生成對應的Shader組合。所以,每個UMaterial都會包含多個FMaterialResource。

FMaterialRenderProxy是FMaterial用于渲染線程的代理,它可以透過FMaterail和UMaterialInterface訪問到Shader、渲染狀態,光照模型等所有用戶設置好的材質參數。

UE4的材質中光照模型是不可定制的,所以在不魔改源碼的前提下,你無法修改其光照模型,比如你想實現一個NPR的Ramp給光照分層時。

UE4中Shader生成

FShader是UE4中所有Shader的基類,它有兩個主要的子類

FGlobalShader:全局Shader,會自動注冊到全局ShaderCache中

FMaterialShader:用于材質(編輯器)的Shader,所有的后處理、UI、用于模型渲染的Shader都是它的子類。

UE4 Shader生成分兩部分,第一部分是把材質編輯器中的節點圖編譯成HLSL代碼,這一部分是通過FHLSLMaterialTranslator來完成的。

UE4 Shader生成的第二部分是把HLSL生成多平臺的Shader代碼,如Windows上的HLSL,Android上的GLSL,IOS上的MetalShader,簡單的流程是這樣:

如果是目標平臺是HLSL相關的平臺,則使用ShaderCompilerCommon模塊編譯出HLSL AST,再適配到不同的SM Feature上。

如果目標平臺是非HLSL相關的平臺,則先通過Hlslcc模塊(在源碼的ThirdParty中)把HLSL編譯成基于Mesa自定義的GLSL ByteCode的AST,對該AST再使用GLSLOptimizer進行優化,并把對應的AST通過不同平臺的Shader編譯后端把Mesa GLSL ByteCode生成不同的Shader源碼。

第二部分編譯是通過啟動ShaderCompilerWorker實用程序并行編譯。

ShaderCompilerWorker的只是簡單封裝了一下就轉調了IShaderFormat的各個子類的CompileShader,而ShaderFormat則會調用對應的xxxxFrontend(FOpenGLFrontend)進行具體的Shader生成。

基本生成流程如下圖

從上面的介紹可以看到UE4的Shader跨平臺方案,和U3D一樣,使用的字節碼的方案,不過一個用的是HLSL BC,一個使用的是Mesa BC。Shader Cross Compile在有了Spir-v之后或者大家都往其遷移是更靠譜的方式——畢竟這是個有強大開源組織在維護、升級和推動的天然跨平臺的字節碼,而且其Optimizier也在持續維護,要比目前的UE使用的glsloptimizer可維護性會更好。

關于Shader編譯的細節和優化、后續還會有文章詳細介紹,而這篇文章的字數看起來也比較有點多了,所以就此打住,更多的關于UE4渲染模塊的簡介也在后面的文章里再續。

總結

以上是生活随笔為你收集整理的opengl游戏引擎源码_UE4渲染引擎模块简介(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。