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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Filament 渲染引擎剖析 之 FrameGraph 1 虚拟资源的定义与创建

發布時間:2023/12/8 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Filament 渲染引擎剖析 之 FrameGraph 1 虚拟资源的定义与创建 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Filament 使用了可擴展渲染管線(FrameGraph)來組織渲染通道和管理渲染資源,網上也搜了下可擴展渲染管線的相關的文章,一般認為可擴展渲染管線是次時代渲染引擎應該具備的比較先進的管線組織架構方式。所以就硬著頭皮讀了讀?Frostbite 對?FrameGraph 的宣講PPT,看完后覺得似懂非懂(應該是腦袋榆木,英語不是很好的原因)。網上的文章也有點“含混晦澀”,就是看懂了,實現起來估計也費盡,很多細節不明朗。回過頭來想,這不是有現成的代碼,分析下現成的教材(filament)豈不是更好?!

看了一段時間filament 對FrameGraph 的實現,基本上是了解了其原理。其實先不管代碼驅動(code-driven) 還是數據驅動(data-driven)這些比較前衛的編程理念(網上搜了個遍,也沒有什么資料把code-driven的概念講清楚,倒是有個網站編程提及了一些code-driven 的概念)。可擴展渲染管線雖然說的"高大上",其實簡單的理解起來還是比較容易,就是將渲染管線的組織變得具有一定的擴展性,渲染管線的組織盡量不走固化代碼的那套,可以動態的配置。對渲染資源的管理也要更具靈活性。渲染管線與渲染資源的定義,用戶盡可能使用起來簡單和抽象,方式也比較統一。資源的使用是在真正執行渲染之前才實例化,沒有用到的渲染資源和渲染通道從渲染管線中動態剔除掉。因為沒有實例化資源,預編譯渲染通道及資源的成本比較低廉?。

設計渲染管線,擺在我們面前的是面對復雜多樣的業務需求,如何定義及組織渲染通道來實施各種技法,如何管理渲染資源并最優的使用它們。

下面看看 filament 的FrameGraph 的實現方式:

(1)首先,大體上FrameGraph 中的渲染通道(PassNode)以一維數組的形式組織起來,渲染時遍歷這個一維數組來執行渲染。沒有Frostbite介紹的實現方法那樣復雜,雖然是構建的是有向無環圖,但沒有看到filament多路徑并發渲染的實現,應該可以看做是framegraph 的簡化版。

(2)渲染資源及渲染通道的有效性測試及剔除是在FrameGraph 的編譯階段進行的,究竟是如何根據資源的使用情況來動態剔除沒有使用的資源和渲染通道,在后面的文章里會介紹。

(3)每個渲染通道都是一個可執行實例,調用其方法實例化資源并完成渲染。

這個章節我們主要是看看虛擬資源在filament 的FrameGraph中是如何定義及創建的。先搞清虛擬資源,后面的內容也好理解了。

既然FrameGraph 中的資源在沒有使用它們之前是沒有被實例化的虛擬資源,應該有一種機制能夠持有創建具體資源的所有信息,能夠在用到這些資源的時候實例化虛擬資源,并對上層FrameGraph的構建者提供必要的構建信息,使其了解資源的在各渲染通道中的使用情況以支持上層對資源的剔除操作, 那么主要是由兩個類來支持,虛擬資源入口類ResourceEntry和構建FrameGraph的資源狀態類ResourceNode?。

一、虛擬資源的定義

1)虛擬資源的入口類 ResourceEntry

說是入口類,其實它就是虛擬資源類,在整個filament 分析中要有這個概念,不要被它的Entry迷惑。

虛擬資源入口的接口類定義:

虛擬資源入口的基類定義:

虛擬資源入口實現類:

ResourceEntry 是類模板,可以實例化具體的模板類, 如果是紋理資源入口類,可直接使用?FrameGraphTexture 實例化該類模板, 例如 ResourceEntry<FrameGraphTexture>。作為抽象資源的接口類,在實例化具體的資源時要能夠獲得足夠的信息來創建該資源,所以?ResourceEntry 最主要的兩個屬性 是 resource 和 descriptor。 resource 是 虛擬資源實例, descriptor 是具體的資源信息。?

渲染目標資源類:

?

為什么要重新定義一個新的RenderTargetResourceEntry類 ? 很明顯,渲染目標資源需要擴展一些方法來支持更復雜的渲染目標的操作。?

最后來張類圖:

總結:

(1)ResourceEntry持有創建具體資源的所有信息 {descriptor 屬性}, 這個descriptor 屬性的定義來源于具體資源的定? 義,通過類模版實例化完成具體資源的定義。

(2)T resource{}? 是具體資源,它包括具體資源的描述和具體資源實例。

(3)ResourceEntry提供虛擬資源的管理功能,比如實例化具體資源,刪除具體資源實例等?。

2)具體資源的孵化器?FrameGraphTexture 和 FrameGraphRenderTarget?

虛擬資源是資源的信息的集合和實例化后的渲染資源持有者,它在渲染管線需要實例化時,根據其資源的描述信息創建具體的資源實例。作為渲染過程,不管用什么形式最終主要是與紋理和渲染目標打交道。

filament 的framegraph 的具體資源分為兩類:

1、紋理資源

可以看到下圖紋理資源的Descriptor描述了具體資源創建屬性(除了沒有向GPU上傳數據), 紋理圖片寬width, 高height, 深depth, 在紋理細節等級的哪一級采樣?levels,多重采樣紋理采樣數samplers, 紋理類型,格式, 用途。

紋理資源的硬件句柄 texture 代表了實例化后的GPU端的紋理對象資源。

2、渲染目標資源

渲染目標資源是對幀緩存對象的抽象描述,每個幀緩存對象都會有N個緩存附件,以實現RTT 或MRT。從下圖可以看出每個幀緩沖對象有6個緩存附件,分別為4個顏色附件, 一個深度附件和模板附件。(如果你讀過framegraph去年的代碼,你會發現還沒有FrameGraphRenderTarget這個類,也就是虛擬資源還沒有統一起來,設計的不合理,新版修正了)。

?

仔細看上面兩個類的定義,都定義了資源描述descriptor? 和創建具體資源的接口 create 和 destroy。這就簡單多了,只要用這兩個類去實例化ResourceEntry類模版, 虛擬資源入口類的定義就完成。

綜合起來,filament 的 FrameGraph 的虛擬資源有兩類: ResourceEntry<FrameGraphTexture> 和 ResourceEntry<RenderTargetResourceEntry>。

有時具體資源(例如FrameGraphTexture)需要被導入到渲染通道中使用,那么 ResourceEntry? 與 FrameGraphTexture就不是一一對應的關系了,而是多對一的關系(多個虛擬資源使用同一個具體資源)。當虛擬資源被初始化時,ResourceEntry 實例通過imported 標記來判斷使用到的具體資源是否要被實例化。

3)資源狀態類 ResourceNode

ResourceNode 資源節點類主要是在FrameGraph編譯階段為資源的剔除操作提供支持,它記錄渲染通道(PassNode)對資源的使用情況,渲染通道對該資源讀取一次,資源的相應引用計數就會加1次。如果沒有渲染通道使用資源節點關聯的虛擬資源,資源將會被剔除。

二、虛擬資源的創建

虛擬資源的創建由FrameGraph構建器Builder類提供相應的接口createTexture 和 createRenderTarget 負責,底層統一調用FrameGraph接口創建具體資源。

當渲染通道需要使用資源時,由FrameGraph構建器Builder 創建相應的虛擬資源,下面列一下相關代碼:

Builder創建紋理資源

Builder 創建渲染目標資源

Builder 創建紋理資源和渲染目標資源的公共接口,最終還是通過FrameGraph 實例去創建具體資源:

FrameGraph 創建資源接口

注意: FrameGraph 使用的虛擬資源句柄在這里現了原形~~~?原來是資源節點實例在資源節點數組中的索引

上面的代碼可以看出創建一個虛擬資源對象(最終返回的是ResourceNode 在 ResourceNodes數組中的索引),FrameGraph會創建虛擬資源入口實例并加入到虛擬資源入口數組中,隨后創建虛擬資源節點并將其添加到虛擬資源節點數組(mResourceNodes)和虛擬資源節點入口數組(mResourceNodeEntries)中。

有了mResourceNodes ,為什么還要用 mResourceNodeEntries ?先看一下mResourceNodes 和 mResourceNodeEntries在FrameGraph中的定義,mResourceNodeEntries 只是個不能共享對象的指針的數組,超出作用域或資源生命周期讓其自動調用析構函數釋放內存,防止內存泄露。

既然兩者等價,那么只用mResourceNodeEntries 不就行了?@@@ 也不要太計較這些,filament有些模塊的早期代碼看是去邏輯設計的確實不是那么好(尤其是早期FrameGraph 的設計,作者貌似也是在似懂非懂的在嘗試,有些邏輯很不合理,我就上了它的“”,研究它的老代碼,有些地方看了許久沒整明白它想干啥,比較蹩腳。看了現在這版代碼設計上已經好了很多,把紋理虛擬資源,渲染目標虛擬資源給統一起來了, 尤其那個moveResource操作也干凈利落了)。

總結:

ResourceNode、ResourceEntry 、FrameGraphTexture 和 FrameGraphRenderTarget 關系:

(1)FrameGraphTexture 和 FrameGraphRenderTarget 是具體資源,具體資源描述了資源的屬性和狀態。它對外提供創建和銷毀具體資源實例的接口。具體資源在沒有被實例化時,只是資源描述的信息集合。

(2)ResourceEntry 是 FrameGraph的虛擬資源。ResourceEntry 和 具體資源之間有可能是多對一的關系。ResourceEntry 保存了虛擬資源被引用到的最終計數。

(3)ResourceNode 是構建FrameGraph時資源的狀態節點,它記錄渲染通道對虛擬資源的使用情況。FrameGraph上層對資源的操作都是針對ResourceNode 而言。

到現在為止,我們見識了什么是FrameGraph中的虛擬資源,以及系統如何創建它們,下一節我們再剖析下filament 代碼,看看它是如何創建 FrameGraph 中的渲染通道、如何編譯和剔除無用的渲染資源和其關聯的渲染通道,執行渲染通道進行渲染的。

下一節?Filament 渲染引擎剖析 之 FrameGraph 2 動態構建渲染管線

總結

以上是生活随笔為你收集整理的Filament 渲染引擎剖析 之 FrameGraph 1 虚拟资源的定义与创建的全部內容,希望文章能夠幫你解決所遇到的問題。

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