前言
最近在工作中越來越多地接觸到一些3D以及相比常見特性更酷炫的效果,因此萌發了想要自己從0開始打造一個渲染引擎的念頭,一方面是為了更好地實現公司業務的需求,另一方面則是可以學到整個渲染流水線上的方方面面。
因為之前做的大部分都是在特效這塊,對OpenGL會比較熟悉一些,但是放大到渲染引擎上就很多方面不熟悉了,甚至有些是完全0基礎,在給自己今年定下這麼一個目標時也是一頭霧水,有種瞬間不知道該向哪裡邁出第一步的感覺。因此這幾天基本都在尋找和渲染引擎甚至遊戲引擎相關的一些基本資訊和資料,自己給自己提問題,再從問題出發去尋找答案,一步步地去理清自己的思路,從而形成了這一份文章。
文章裡面的很多內容都是自己整理各位大神的文章/回答中的摘要而來(所有引用均會註明出處,在此對各位大神表示感謝和仰望),而且只靠一篇文章是肯定不足以完全講述清楚整個引擎所需要了解到的內容的,只是從我自己的角度來說,這篇文章之於之後構建渲染引擎之路來說,無異於撥雲見日的作用。
另外這系列文章假定各位對OpenGL具有一定的基礎,因此不會過多地介紹OpenGL的一些基礎知識如渲染流程、著色器用法等。
從問題出發
且不論遊戲引擎這樣的龐然巨物,就只說渲染引擎所需要涉及的內容就非常,你可能要考慮怎麼去封裝渲染API,還要考慮怎麼去整合各類效果系統,初版效果出來了,要不要考慮搞搞Vulkan搞搞Metal,什麼樣的方案才是最佳的等等。
因此如果沒有一個方向就開始尋找資料的話和大海撈針沒有什麼區別,也容易因為一時間接收的資訊過多進而打擊信心和興趣,因此在開始找資料之前我給自己定了幾個問題,以這個幾個問題為方向去找資料為自己解答:
- 一個渲染引擎是由哪些系統組成的?這些系統都是不可或缺的嗎?
- 實現一個渲染引擎需要點亮哪些技能點?哪些是必須技?哪些可以邊做邊點亮?
- 渲染引擎的基本渲染流程是什麼樣的?
- 目前有哪些出色的渲染引擎?怎麼篩選參考引擎?參考哪些?
而在尋找答案的過程中,自然而然就也會接觸到其他方面的內容,比如一些自己之前見都沒見過的名詞,或者是大多數引擎都在用的成熟方案等等,這些也都會一併記錄下來。
啟程
其實這篇文章是有一個檢驗收穫的方式的,這個方式在一開始是沒有的,但是在找資料的過程中看到知乎大佬的回答有所感悟,在這篇文章結束時再回過頭來看看下面這句話,如果大致明白了,那麼這篇文章就起到作用了:
而這段話正是這一輪資料搜尋下來個人覺得最精煉的對渲染流程的描述了,至於裡面具體各個名詞所指則會在後面的內容進行補充,當然各個渲染引擎的流程在細節之處甚至一些環節上都會做出有所區別,這些則會在後面針對一些參考引擎做分析的時候再逐步整理出來。
那麼,啟程!
渲染引擎的技能樹
先貼一下找到的 知乎上的回答 :
是不是有種看一眼就想放棄的衝動 ?(╯°Д°)╯︵ ┻━┻
但是正如我們在日常開發中突然遇到一個新的技術需求的時候一樣,一般我們也不會把一個技術學到精通來才開始落地,而是會先預研一下方案,做下對比,掌握好基礎,對一些風險提前做好功課,保證好大方向上的正確性,然後就會開始逐步落地,在過程中慢慢打磨。
類比到上面的內容也是如此,按照我自己的想法,我覺得首先C++的基本語法、記憶體管理、標準庫的使用等基礎內容以及OpenGL的渲染管線和基本的glsl、矩陣這些是在開始之前必須要先打好底子的,否則可能會連參考第三方開源引擎都成問題,更不要說自己去寫了,而在自己寫專案或學習第三方開源專案的過程中則可以對遇到的不明白或者不完全理解的內容進行進一步的學習,不求快但求吃透每一點,以這樣的方式去持續擴大或加深自己的技能,在這個過程中儘量以點及面,每一個細節儘可能多去了解一些邊邊角角涉及到的地方,以便自己能夠儘快完成一個又一個的閉環,最終對整個領域的理解越來越清晰。
其次就是合理安排出一部分時間來進行理論方面的系統學習,比如計算機圖形學等,系統性的學習個人還是比較推薦通過書籍來進行,雖然週期更長,但是可以讓你對這個領域的方方面面能夠有一個更清晰的認識,從而形成一個更大的閉環。
而至於dx、metal、編譯知識這些如果暫時不需要做這方面的需求的話倒不是非常關鍵,可以放到上面的技能學習之後,甚至可能很長一段時間你都不會使用到,當然也可能你現在是需要用dx而不需要opengl,那麼就是dx的基礎知識是必須的opengl排到後面,總之因人而異吧。
3D引擎著色方式的演化史
這部分內容是我在尋找渲染流程過程中的額外收穫,雖然說的是演化史,但是裡面的內容正好是對 啟程
章節裡對渲染引擎主要流程的描述的擴充套件,通過對多種著色方式的瞭解,可以間接對渲染流程裡的幾個主要步驟有一個初步的感知。
該章節的內容起源是3D渲染引擎著色方式的演化史,原文對各個著色方式的介紹比較簡明扼要,在閱讀完這篇文章後我又自己去對裡面的各個名詞和許多不理解的地方進行了搜尋,因此大綱上還是會按照這篇文章的幾大部分進行,在內容裡面再補上自己找到的額外的資料,主要來源於 實時渲染中常用的幾種Rendering Path 和其他針對其中細節講解的文章。
這部分個人認為在這篇文章的階段不需要深究裡面的實現細節,這個可以在後續分析開源引擎流程以及自主實現的時候去深入研究,在這裡更多地是對這些Render path
有一個印象並且知道他們的大致渲染原理、彼此之間的區別以及能解決什麼樣的問題,從而能在後面的引擎中因地制宜地使用不同的著色方式。
Rendering Path
Rendering Path
其實指的就是渲染場景中光照的方式。由於場景中的光源可能很多,甚至是動態的光源。所以怎麼在速度和效果上達到一個最好的結果確實很困難。以當今的顯示卡發展為契機,人們才衍生出了這麼多的 Rendering Path 來處理各種光照。
在介紹各種光照渲染方式之前,首先必須介紹一下現代的圖形渲染管線。這是下面提到的幾種 Rendering Path 的技術基礎。
現代的渲染管線也稱為可程式設計管線(Programmable Pipeline)
,簡單點 說就是將以前固定管線寫死的部分(比如頂點的處理,畫素顏色的處理等等)變成在 GPU 上可以進行使用者自定義程式設計的部分,好處就是使用者可以自由發揮的空間增大,缺點就是必須使用者自己實現很多功能。
下面簡單介紹下可程式設計管線的流程。以 OpenGL 繪製一個三角形舉例。首先使用者指定三 個頂點傳給 Vertex Shader
。然後使用者可以選擇是否進行Tessellation Shader
(曲面細分可能會用到)和 Geometry Shader
(可以在 GPU 上增刪幾何資訊)。緊接著進行光柵化
,再將光柵化後的結果傳給 Fragment Shader
進行 pixel
級別的處理。 最後將處理的畫素傳給 FrameBuffer
並顯示到螢幕上。
名詞解釋
Geometry:即我們所要渲染的一個幾何圖形
Vertex Shader:頂點著色器,處理每個頂點,將頂點的空間位置投影在螢幕上,即計算頂點的二維座標。
Tessellation Shader:曲面細分著色器,是一個可選的著色器,用於細分圖元
Geometry Shader:幾何著色器,是一個可選的著色器,用於逐圖元的著色,可以產生更多的圖元
Fragment Shader:片段著色器,也稱為畫素著色器(Pixel Shader),用於計算“片段”的顏色和其它屬性,此處的“片段”通常是指單獨的畫素
後面文章內容中出現的VS、TS、GS、FS(PS)即對應上圖中的Vertex Shader、Tessellation Shader、Geometry Shader、Fragment Shader
FrameBuffer:幀緩衝儲存器,簡稱幀快取或視訊記憶體,它是螢幕所顯示畫面的一個直接映象,又稱為位對映圖(Bit Map)或光柵。幀快取的每一儲存單元對應螢幕上的一個畫素,整個幀快取對應一幀影像。
Forward rendering
這是最初始的渲染方式,原理是以mesh
為單位進行渲染,在光柵化後,對每個PS
進行計算時,根據光照
進行著色計算,所以這種方式稱為前向著色
。
Forward Rendering 是絕大數引擎都含有的一種渲染方式。要使用 Forward Rendering,一般在 Vertex Shader
或 Fragment Shader
階段對每個頂點或每個畫素進行光照計算,並且是對每個光源進行計算產生最終結果。下面是 Forward Rendering 的核心虛擬碼:
For each light:
For each object affected by the light:
framebuffer += object * light
複製程式碼
比如在 Unity3D 4.x 引擎中,對於下圖中的圓圈(表示一個 Geometry
),進行 Forward Rendering 處理:
將得到下面的處理結果:
也就是說,對於 ABCD 四個光源我們在 Fragment Shader 中我們對每個 pixel 處理光照, 對於 DEFG 光源我們在 Vertex Shader 中對每個 vertex 處理光照,而對於 GH 光源,我們採用球調和(SH)函式進行處理。
這種方式存在以下弊端:
- 如果畫素被其他畫素遮蔽了,就浪費了寶貴的處理結果
- 光源多起來後管理很麻煩,Shader也不好寫。
因此,Deferred rendering就應運而生了。
很明顯,對於 Forward Rendering,光源數量對計算複雜度影響巨大,所以比較適合戶外這種光源較少的場景(一般只有太陽光)。
但是對於多光源,我們使用 Forward Rendering 的效率會極其低下。因為如果在 Vertex Shader 中計算光照,其複雜度將是
O(num_geometry_vertexes ∗ num_lights)
,而如果在 Fragment Shader 中計算光照,其複雜度為O(num_geometry_fragments ∗ num_lights)
。可見光源數目和複雜度是成線性增長的
。對此,我們需要進行必要的優化。比如
多在 Vertex Shader 中進行光照處理,因為有一個幾何體有 10000 個頂點,那麼對於 n 個光源,至少要在 Vertex Shader 中計算 10000n 次。而對於在 Fragment Shader 中進行處理,這種消耗會更多,因為對於一個普通的 1024x768 螢幕,將近有 8 百萬的畫素 要處理。所以如果頂點數小於畫素個數的話,儘量在 Vertex shader 中進行光照。
如果要在 fragment shader 中處理光照,我們大可不必對每個光源進行計算時,把所有畫素都對該光源進行處理一次。因為每個光源都有其自己的作用區域。比如點光源的作用區域是一個球體,而平行光的作用區域就是整個空間了。對於不在此光照作用區域的畫素就不進行處理。但是這樣做的話,CPU 端的負擔將加重。
對於某個幾何體,光源對其作用的程度是不同,所以有些作用程度特別小的光源可以不進行考慮。典型的例子就是 Unity 中只考慮重要程度最大的 4 個光源。
名詞解釋
Mesh:網格,任何一個模型都是由若干網格面組成,而每一個面又有若干個三角形組成,也就是說,模型是由若干個三角形面組成的
Deferred rendering
Deferred Rendering(延遲渲染)顧名思義,就是將光照處理這一步驟延遲一段時間再處理。
具體做法就是將光照放在已經將三維物體生成二維圖片之後進行處理。也就是說將物空間
的光照處理放到了像空間
進行處理。要做到這一步,需要一個重要的輔助工具——G-Buffer
。
G-Buffer 主要是用來儲存每個畫素對應的 Position,Normal,Diffuse Color 和其他 Material parameters
。根據這些資訊,我們就可以在像空間中對每個畫素進行光照處理。
下面是 Deferred Rendering 的核心虛擬碼。
For each object:
Render to multiple targets
For each light:
Apply light as a 2D postprocess
複製程式碼
這種渲染方式相比 Forward rendering 就是在渲染mesh
時,並不進行光照計算,而是按照以下步驟進行:
-
將深度、法線、Diffuse、Specular等
材質屬性
分別輸出到GBuffer
裡(其實就是幾張RT
) -
然後GBuffer裡的深度和法線資訊,累加所有光照的強度到一張
光照強度RT
上 -
根據GBuffer裡的Diffuse和Specular資訊,以及光照強度RT,進行著色計算
名詞解釋
GBuffer:指Geometry Buffer,亦即“物體緩衝”。區別於普通的僅將顏色渲染到紋理中,G-Buffer指包含顏色、法線、世界空間座標的緩衝區,亦即指包含顏色、法線、世界空間座標的紋理。由於G-Buffer需要的向量長度超出通常紋理能包含的向量的長度,通常在遊戲開發中,使用多渲染目標技術來生成G-Buffer,即在一次繪製中將顏色、法線、世界空間座標分別渲染到三張浮點紋理中
下面簡單舉個例子:
首先我們用儲存各種資訊的紋理圖。比如下面這張 Depth Buffer
,主要是用來確定該像 素距離視點的遠近的。
根據反射光的密度/強度分度圖來計算反射效果。
下圖表示法向資料,這個很關鍵。進行光照計算最重要的一組資料。
下圖使用了 Diffuse Color Buffer。
這是使用 Deferred Rendering 最終的結果。
Deferred rendering 的最大的優勢就是將光源的數目和場景中物體的數目在複雜度層面上完全分開,也就是說場景中不管是一個三角形還是一百萬個三角形,最後的複雜度不會隨光源數目變化而產生巨大變化。從上面的虛擬碼可以看出 Deferred rendering 的複雜度為 O(screen_resolution + num_lights)
。
這種渲染方式也有一些弊端:
- 由於硬體限制或者效能限制,GBuffer裡儲存的材質資訊有限,對於特殊材質來說,例如人的皮膚、翡翠等,渲染結果很不好
- 延遲計算光照會大幅增加紋理頻寬和幀緩衝區頻寬的開銷
- 當光源數量很多時,光源會不斷對光照強度RT進行累加,也會大幅增加幀緩衝區頻寬開銷
- 由於硬體限制或者效能限制,不能使用硬體支援的MSAA,只能使用類似後期處理的FXAA或者Temporal AA
名詞解釋
MSAA、FXAA、Temporal AA都是抗鋸齒(Anti-Aliasing)技術,鋸齒的來源是因為場景的定義在三維空間中是連續的,而最終顯示的畫素則是一個離散的二維陣列。所以判斷一個點到底沒有被某個畫素覆蓋的時候單純是一個“有”或者“沒有"問題,丟失了連續性的資訊,導致鋸齒。
具體區別可見FXAA、FSAA與MSAA有什麼區別?
Deferred Rendering 侷限性是顯而易見的。比如我在 G-Buffer 儲存以下資料:
這樣的話,對於一個普通的 1024x768 的螢幕解析度。總共得使用 1024x768x128bit=20MB, 對於目前的動則上 GB 的顯示卡記憶體可能不算什麼,但是使用 G-Buffer 耗費的視訊記憶體還是很多的。一方面,對於低端顯示卡,這麼大的顯示卡記憶體確實很耗費資源;另一方面,如果要渲染更酷的特效,使用的 G-Buffer 大小將增加,並且其增加的幅度也是很可觀的;並且存取 G-Buffer 耗費的頻寬也是一個不可忽視的缺陷。
對於 Deferred Rendering 的優化也是一個很有挑戰的問題。 下面簡單介紹幾種降低 Deferred Rendering 存取頻寬的方式。最簡單也是最容易想到的就是將存取的 G-Buffer 資料結構最小化,這也就衍生除了 Light Pre-Pass
方法。另一種方式是將多個光照組成一組,然後一起處理,這種方法衍生了 Tile-based deferred Rendering
。
Light Pre-Pass / Deferred Lighting
這個技術是CryTek這個團隊(該團隊開發了CryENGINE遊戲引擎,即下面簡稱的CE,如果還不熟悉的話,那麼這個團隊開發了《孤島危機》、《孤島驚魂》等遊戲)原創的,由 Wolfgang Engel 在他的 部落格 中提到的,也用於解決Deferred rendering
渲染方式裡的第一個弊端。原理跟Deferred rendering
差不多,只是有幾處不同:
-
GBuffer中只有深度(Z)和法線(Normal)資料,對比 Deferred Rendering,少了 Diffuse Color, Specular Color 以及對應位置的材質索引值
-
在 FS 階段利用上面的 G-Buffer 計算出所必須的 Light properties,比如 Normal * LightDir, LightColor, Specular 等 Light properties,將這些計算出的光照進行
alpha-blend
並存入LightBuffer
(就是用來儲存 Light properties 的 buffer) -
著色過程不是Deferred rendering中類似於後處理的方式,而是渲染mesh,即將結果送到 Forward rendering 渲染方式計算最後的光照效果
相對於傳統的 Deferred Render,使用 Light Pre-Pass 可以對每個不同的幾何體使用不同 的 Shader 進行渲染,所以每個物體的 Material properties 將有更多變化。這裡我們可以看出對於傳統的 Deferred Rendering,它的第二步是遍歷每個光源,這樣就增加了光源設定的靈活性,而 Light Pre-Pass 第三步使用的其實是 Forward rendering,所以可以對每個 mesh 設定其材質,這兩者是相輔相成的,有利有弊。
另一個 Light Pre-Pass 的優點是在使用 MSAA 上很有利。雖然並不是 100%使用上了 MSAA(除非使用 DX10/11 的特性),但是由於使用了 Z 值和 Normal 值,就可以很容易找到邊緣,並進行取樣。
下面這兩張圖,上邊是使用傳統 Deferred Render 繪製的,下邊是使用 Light Pre-Pass 繪 制的。這兩張圖在效果上不應該有太大區別。
其實這種方式也有弊端:
-
由於不透明物體在主視口中被渲染了兩次,會大幅增加渲染批次,不過好在CE對狀態切換管理的非常好,所以渲染批次的承載力很高
-
由於某些特殊材質需要對光照進行特殊處理,比如說樹葉的背光面也會有一定的光照,所以這種方式也不太完美
印象裡貌似CE對主光,例如太陽光,不累加進光照強度RT,而是著色時單獨處理,這樣的話效果會提升不少,至少室外場景是完全能夠解決問題的;而對於點光源比較多的室內場景,主光著色好看了就會效果很好了,畢竟其他光照的影響佔比比較小。
Tile-based deferred rendering
這個方案是對Deferred rendering
渲染方式裡的第三個弊端進行優化的。原理就是:
- 先將整個光照強度RT分成很多個正方形區域,計算每個區域受哪些光源影響,並儲存起來
- 然後以每個區域為單位,在一個批次裡累加所有的光照
這樣就能減少對光照強度RT上某個畫素頻繁讀寫的次數。
TBDR 主要思想就是將螢幕分成一個個小塊 tile
,然後根據這些 Depth 求得每個 tile 的 bounding box
。對每個 tile 的 bounding box 和 light 進行求交,這樣就得到了對該 tile 有作用 的 light 的序列。最後根據得到的序列計算所在 tile 的光照效果。
對比 Deferred Render,之前是對每個光源求取其作用區域 light volume
,然後決定其作用的的 pixel,也就是說每個光源要求取一次。而使用 TBDR,只要遍歷每個 pixel,讓其所屬 tile 與光線求交,來計算作用其上的 light,並利用 G-Buffer 進行 Shading。一方面這樣做減少 了所需考慮的光源個數,另一方面與傳統的 Deferred Rendering 相比,減少了存取的頻寬。
在 一篇文章 中提到目前所有的移動裝置都使用的是 Tile-Based Deferred Rendering(TBDR) 的渲染架構,,裡面還提及了使用TBDR的一些注意事項,感興趣的可以看看,以及 針對移動端TBDR架構GPU特性的渲染優化 ,移動GPU渲染原理的流派——IMR、TBR及TBDR
名詞解釋
tile:區塊,即將需要渲染的畫面分成一個個的區塊
bounding box:邊界框,是一個矩形框,可以由矩形左上角的xx和yy軸座標與右下角的xx和yy軸座標確定。從技術上講,邊界框是包含一個物體的最小矩形
light volume:體積光,散射是一種非常美麗的自然現象,在自然界中光穿過潮溼或者含有雜質的介質時產生散射,散射的光線進入人眼,讓這些介質看起來像攏住了光線一樣,也就是所謂的體積光。可見 遊戲開發相關實時渲染技術之體積光
Hybrid deferred rendering
為了解決Deferred lighting
裡面的第一個弊端,從CE3的某個版本開始,換成了這種方式。理由是,對於大多數物體來說,Deferred rendering
的方式就很好了,而對於特殊材質,則使用Deferred lighting
的方式。這樣,既能保持很好的渲染效果,又能避免渲染批次激增。
更詳細的內容可見 Hybrid-Deferred-Rendering.pdf
Forward+
有時候,你轉了很大一個圈以後,發現又回到了原點。
好,那這就到了終極方式了——前向著色
的改進版。這個方案是ATI(著名顯示卡生產商,06年被AMD收購)發明的,已經應用於Ogre 2.1(開源的物件導向的3D引擎)。UE4(大名鼎鼎的虛幻引擎)正在針對VR研發前向著色,不知道是不是也是這個。
原理也很簡單:
-
先用
Tile-based deferred rendering
裡的方式計算好每個區域受哪些光照影響 -
然後像傳統的前向著色一樣渲染每個mesh——當然,要去光照列表裡查詢影響當前區域的所有光照,並著色
這種方式只有上述提到的一個缺點,那就是可能和Deferred lighting
一樣需要渲染兩遍場景,不過以後應該會有優化的方案。優點則有:
-
渲染效果好
-
頻寬開銷低,尤其適用於VR這種每幀需要渲染兩遍場景的應用
-
可以使用硬體支援的MSAA,質量最高。
Forward+的優勢還有很多,其實大多就是傳統 Forward Rendering 本身的優勢,所以 Forward+更像一個集各種 Rendering Path 優勢於一體的 Rendering Path。
Forward+ = Forward + Light Culling
。Forward+ 很類似 Tiled-based Deferred Rendering。 其具體做法就是先對輸入的場景進行 z-prepass,也就是說關閉寫入 color,只向 z-buffer 寫入 z 值。注意此步驟是 Forward+必須的,而其他渲染方式是可選的。接下來的步驟和 TBDR 很類似,都是劃分 tiles,並計算 bounding box。只不過 TBDR 是在 G-Buffer 中完成這一步驟 的,而 Forward+是根據 Z-Buffer。最後一步其實使用的是 Forward rendering 方式,即在 FS 階段對每個 pixel 根據其所在 tile 的 light 序列計算光照效果。而 TBDR 使用的是基於 G-Buffer 的 Deferred rendering。實際上,forward+比 deferred 執行的更快。我們可以看出由於 Forward+只要寫深度快取 就可以,而 Deferred Rendering 除了深度快取,還要寫入法向快取。而在
Light Culling
步驟, Forward+只需要計算出哪些 light 對該 tile 有影響即可。而 Deferred Rendering 還在這一部分把光照處理給做了。而這一部分,Forward+是放在 Shading 階段做的。所以 Shading 階段 Forward+ 耗費更多時間。但是對目前硬體來說,Shading 耗費的時間沒有那麼多。
以下是 Forward+ 與 Deferred Rendering 的對比圖:
感興趣的可以再額外看看 forward框架的逆襲:解析forward渲染 這篇文章。
名詞解釋
Light Culling:剔除光照
渲染/遊戲引擎調查
渲染引擎屬於遊戲引擎中的一部分,本章節主要簡要整理一下找到的一些渲染引擎和遊戲引擎,具體內在區別後續進一步深入瞭解的時候再整理補上。
渲染引擎
- bgfx
- OGRE 3D
- osg
- The Forge
- gkEngine
- three.js
- pixi.js
- g3d
- OpenSceneGraph
- LiteScene
- webglstudio.js
- sketch.js
- PlayCanvas
遊戲引擎
在Wiki上也已經有整理了目前為止市面上已有的大量遊戲引擎:Game Engine
Github上統計的開源遊戲引擎:game-engines
參考引擎
通過上面的調查我們發現現在市面上的大小引擎數不勝數,一個個地去看的話時間週期估計要以年為單位,首先我們要先從自身的需求出發定出一些對參考引擎所需要具備的特性的要求,然後再根據要求來篩選出幾個比較貼合我們需求的深入研究。
以我自身的角度出發,我列出來了以下一些要求:
- 開源,但是專案規模還未到非常龐大的程度,避免研究週期過長
- 具備一定規模的使用人數和影響力
- 保持更新,所用方案不至於落後行業太久
- 使用C++語言編寫,具備跨平臺特性
- 支援2D/3D渲染,實現粒子系統、光源、動畫系統、後處理等多項功能中的幾種
- 具備多平臺自動切換渲染驅動的話更好
我從上面調查後的引擎列表裡整理出了以下幾個符合語言、使用人數、持續更新、支援效果等方面都比較符合的引擎來優先作為研究的物件,後續的分析系列文章也會先以這些引擎來作為目標:
-
渲染引擎
- bgfx
- 可實現2D以及文字繪製,3D渲染,光照等效果
- 可自動切換Metal等渲染驅動
- OGRE 3D
- 老牌渲染引擎,除了渲染之外還包含動畫系統和粒子系統
- OpenSceneGraph
- 中文文件,粒子系統等功能可通過第三方外掛實現
- bgfx
-
遊戲引擎
- godot
- 用的人多,中文文件,2D和3D都支援
- What are the best 3D C++ game engines with full source code access?:外網評價的截止2019最佳遊戲引擎,下面的GoDot排第二,第一是Unreal
- Urho3D
- 歷史久遠使用人數比Godot少很多,各方面表現比較中庸
- 輕量級專案,支援在該引擎的基礎上方便地擴充套件各種效果元件
- godot
總結
至此我們完成了在邁出跨平臺渲染引擎第一步之前的鋪墊工作,我們梳理了渲染引擎的一個大致流程,以及這個流程裡面的關於 Rendering path 等方面的細節資訊,對這些內容有了一個初步的印象,同時列舉了以下令人望而卻步的技能樹,但是我們可以一步一步地吃成胖子,重要地是邁出這第一步,最後我們整理了一下渲染/遊戲引擎列表,並按照自身要求從中梳理了幾個引擎來作為下一步分析研究的目標。
接下來就是技術活了,下一篇《跨平臺渲染引擎之路:bgfx分析》將針對 bgfx 開始第一步學習研究,分享其內部的渲染流程以及分析思路等。