虛幻4渲染程式設計【第一卷:虛幻自身的延遲渲染管線】
阿新 • • 發佈:2019-02-07
因為虛幻的架構,我們美術做一個效果只能使用材質編輯器。這讓我很不舒服,稍微想做點特別點的效果就沒辦法了。我又是天天在公司用自研引擎的人,這種限制讓人很不舒服。所以我開始修改了虛幻的shadingmode之類的。但是感覺自己還是不滿足,想調個多pass虛幻都不讓我做,所以我打算加個pass什麼的。但是虛幻加pass可不像unity那麼簡單,只有操刀去改原始碼了。然後我又反觀了一下我前幾篇部落格,只簡單講了一下怎麼改程式碼,沒說原理。所以這個系列我打算系統說一下虛幻的一個架構。當然虛幻如此龐大,我也有很多不知道的地方。 其實我寫部落格的目的很簡單,就是想記錄一下自己做的東西,有時候自己翻一下,再把問題再想一下,也許會有新的發現。虛幻的渲染方面的資料也是少得可憐,研究的人也少得可憐。大部分牛人都自己去造輪子去了。我只是個技術美術,造輪子的事情還是交給圖形程式吧。不過研究虛幻4的確學到很多。如果有大牛看到我的文章中有錯誤,還請留言斧正。首先在看這個系列之前,你需要具備一下:(1)至少要敲過簡單的渲染器,不管是拿dx敲還是拿gl敲或者vk之類的。(2)對虛幻引擎有一定了解,對虛幻的渲染有一定了解。可以看我前幾篇文章,或許可以有所幫助。(3)C++基礎。其實本人c++水平也是一般般(常常受到公司程式大牛的鄙視,不過我是美術哈哈哈)。那麼下面就正式開始吧!首先,虛幻有很多個管線的。Forward和Tiled Based Deferred Lighting 還有專門適用於手機端的。我目前只研究了Deferred。首先找到。在這個函式裡你將會看到很多熟悉的函式名稱虛幻就是通過呼叫這些函式來一步步繪製的。是不是很眼熟?這個就是各大論壇啦,部落格啦講的虛幻渲染流程的真面目。 通過這個我們便能知道一個大概的繪製流程(千萬別以為虛幻只有這幾步,不過主要的大概的流程是這樣)。先繪製那些深度啊,初始化視口啦我們先不管。我們來看下這個BasePass。這個BasePass乾的事情就是把GBuffer畫出來。這裡就是畫素著色器的入口。繪製完這一步後,我們就有了GBuffer然後再繪製剩下的。環境遮罩驟就先不說了。來看看最重要的光照部分。光照部分的入口在這裡:虛幻的TiledDeferredLighting的渲染方式。不知道這個的去看毛星雲的RTR3的部落格的光照那節,講得特別好。這裡給個傳送門:https://blog.csdn.net/poem_qianmo/article/details/77142101這裡會呼叫 GetDynamicLighting這個函式會呼叫這裡會接著呼叫看到這裡就很熟悉了,看過前面我修改shadingmode的部落格應該會對這裡很熟悉。lighting繪製完了之後就會繪製一些反射啊之類的東西了,然後就是透明物體啊後期啊。這些後面會慢慢分析他們。我們先把兩個最重量級的研究了。接下來我們研究一下fog渲染階段。找到FogRendering.cpp你就會發現,其實繪製fog的是一個globalshader。前面繪製各個物體的是materialshader。你會發現繪製fog的是一個globalshader。虛幻一共有這麼幾種shader:Globalshader materialshader和meshshader。
下面就是官方的DrawOrder了。那麼這個順序是怎麼來的呢。就是上面那個函式的呼叫順序。
再開啟這個Render函式,你就將看到延遲渲染一幀所呼叫的各個函式。(反正我看了半天就看到個大概的渲染順序之外,還是啥也不知道)那麼當我們把一個模型託到場景裡,這個模型被渲染出來的整個流程到底是什麼樣的呢?這個流程其實是非常龐大的。下面我就來一個一個拆分。(1)第一步:資源準備階段。這個階段包括頂點緩衝區的準備,索引緩衝區的準備。這一步由場景代理管理完成。當然從磁盤裡讀取模型資源這些就涉及到StaticMesh這些了。想了解這一步可以去看我以前的部落格,或者直接去看UPrimitiveComponent,UMeshComponent,UStaticMeshComponent,UCableComponent,UCustomMeshComponent。當你把這些原始碼全部研究一遍後,這個階段算是瞭解了。這個階段我不打算再描述了,因為已經有了很多現成的程式碼了。(2)第二步就是shader資源的準備了,這個又是一個非常大的話題了。可以去看我以前關於給改材質編輯器和加shadingmode的文章便可以有個大概的瞭解。這一步我還會進一步闡述。(3)第三步就是繪製了。我們先不看Render函式那些複雜的呼叫,我們把精力先集中到shader層面來。一張畫面是怎麼開始繪製的呢?這篇部落格只是一個概述性和引導性的。只是說明一下虛幻繪製的一個大概情況。下一卷我將演示一下怎麼自己寫個shader,引擎識別它,編譯它,然後如何cpu和gpu進行資訊交流的。