
上回書《Part 0 引擎基礎》說到,我們粗略地知道UE4是以哪些類來管理一個游戲場景里的資料的,但這僅僅是我們開始探索UE4渲染體系的一小步,
本回主要介紹UE4渲染體系中比較宏觀頂層的一部分——多執行緒渲染,具體的多執行緒中,又分為:
- 游戲執行緒(GameThread)
- 渲染執行緒(RenderThread)
- RHI執行緒(Render Hardware Interface Thread)

為什么是多執行緒?

用來描述“渲染”的最基礎的理論就是像圖上的那樣,CPU呼叫圖形API提供的DrawCall命令(也叫繪制指令),在命令中說明需要渲染的資料、屬性等等,然后CPU等待GPU回傳渲染結果,完成渲染,對于那些渲染頻率不高的場景,這種方式并沒有什么問題,但在游戲這種需要實時性渲染的高頻率場景下,問題就顯現出來了,
游戲引擎完成渲染不只有提交DrawCall這一個任務,除了這個以外,CPU要花費非常多的時間在處理游戲邏輯運算和準備渲染資料上,比如處理用戶的輸入、執行游戲腳本、更新物理和影片、可見性剔除等等等等,

假如引擎把所有的事都交由GameThread來完成,當GameThread把當前這一幀該做的事都做完了,準備好要渲染的資料,提交到GPU后,GameThread就只能等待渲染結果,但GameThread接受到當前這一幀的用戶輸入后,完全可以去執行下一幀的各種任務,但單執行緒的機制并不允許這樣的事情,
多核心的CPU和多執行緒并發并行的作業系統在今天已經不是什么稀罕事了,將與渲染相關的任務從GameThread中剝離出來,讓GameThread專注處理游戲邏輯上的的各種計算任務,讓RenderThread專門和GPU來完成渲染任務,就成了自然而然的事情,

加入RenderThread后,每次GameThread處理完各種任務,準備好渲染資料,把資料發送給RenderThread,然后就繼續處理下一幀的任務了,RenderThread收到資料,進行一些資料處理后(比如可見性剔除),向GPU提交DrawCall,等待渲染結果,完成渲染,
那RHIThread是什么呢?UE4中RHI的提出可能有很多原因:
- 支持跨平臺多種圖形API
- 并行提交DrawCall
- 其他各種各樣的性能優化
首先是針對跨平臺多種圖形API,由于不同平臺支持的圖形API不同,Windows限定的Direct3D、MacOS限定的Metal以及跨平臺(包括移動端)的OpenGL和Vulkan,在有RHIThread之前,RenderThread會根據不同的圖形API來選擇DrawCall,這肯定會增加不少作業量,維護也更加復雜,
"All problems in computer science can be solved by another level of indirection." —— Jay Black
如果把這件事交由單獨的一個執行緒來做,豈不美哉?這不,RHIThread就來了,

RenderThread準備好渲染資料后,向RHIThread提交一個與圖形API無關的RHIDrawCommand,RHIThread掏出來一個表,查找當前平臺的圖形API里哪一句是對應的DrawCall,然后再向GPU提交DrawCall,等待渲染結果,完成渲染,這樣一來,RenderThread就可以在自己的任務上專注(方便優化),在RHIThread上完成對各個平臺的圖形API版本迭代維護,

當然這是從工程優化角度上RHIThread存在的理由,當然RHI還有一些更加直接的存在理由,那就是為了支持并行化提交DrawCall,在一些比較舊的圖形API里,DrawCall都是阻塞的,即一個執行緒提交DrawCall時,不允許其他執行緒提交,圖形API呼叫GPU計算后,GPU本身計算渲染是需要時間的,而在這時間里,圖形API如果能準備好下一次DrawCall,那必然是更好的,

隨著技術更新,一些新的圖形API開始提供一些并行化提交DrawCall的方式,在沒有RHI的時候,難道讓UE4跑多個RenderThread嗎?好像也不太合理,RenderThread里面除了提交DrawCall的其他部分也不需要多個執行緒來完成,那需要單獨提出來多執行緒化的任務就順理成章地變成了RHIThread了,
總結
可以看到UE4渲染體系中多執行緒渲染的設計并不是一開始就是這樣,而是跟隨著技術的需求在不斷發展進步的(新的UE5里面估計又改了不少了),
本回并沒有著重討論各種執行緒內部細節的任務,也沒有非常深入的講解各個執行緒之間是如何傳遞具體的命令和資料的,因為講起來那篇幅真的就太長了,之后再慢慢地整理吧,網路上的資料也很多,大家可以自行拓展閱讀,
參考文獻
- [1] 可可西, UE4之Game、Render、RHI多執行緒架構, 博客園
- [2] 0向往0, 剖析虛幻渲染體系(02)- 多執行緒渲染, 博客園
- [3] 醉里挑燈看劍, Unreal Engine中的RHI執行緒, 知乎
- [4] leonwei, 基于UE4的多RHI執行緒實作, CSDN
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/462920.html
標籤:其他
上一篇:Unity制作一個小星球
下一篇:Unity手機觸屏輸入
