若該文為原創文章,轉載請注明原文出處
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/140059315
長沙紅胖子Qt(長沙創微智科)博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中…
Qt開發專欄:開發技術(點擊傳送門)
上一篇:無
下一篇:敬請期待…
前言
??Qt3D是qt的三維,Q3D是Qt的三維圖表,Qt3D是qt的自帶的三維開發框架,Qt的3D開發分為opengl、Qt3D然后是第三方三維框架(OSG、vtk等等)多個技術流。
??本篇描述Qt3D的基礎概念,有一個基本知識。
個人經驗,僅供參考(持續更新)
??通過深入研究和實踐,從中長期看采取第三方三維框架是比較好的方式,如osg,一學多用,如果用Qt就被限制住了,而且學習成本也不低,關鍵是不同版本更新會有些更改迭代跟Qt版本綁定。
??進一步通過深入研究發現,其本質上的模式類似于OSG的模式,也是采用結點的模式,添加組件嵌套的模式實現各種功能。
- 采取節點模式:每一個物體、場景都是一個結點,結點套結點
- 采取組件模式:每一個屬性如材質、光照都是附加給欸結點
- 采取攝像頭模式:三維的視口,其跟osg的函數都差不多
- 采取控制器模式:這里的控制器其實就是osg的漫游器
- 采取輸入控制模式:這部分就是類似于上面的單獨控制器,既受場景漫游器的影響,又可以單獨
- 顯示優化方面:qt3D需要自己控制優化處理,但是osg他本身就做了內存和探測深度的優化,其性能已經優化了一個層級。
- 其他:Qt3D可以隨Qt安裝,Qt的opengl的3D開發又太過基礎,只適合做小三維開發,第三方框架就涉及了編譯和遷移,筆者就經常遇到被人問arm上編譯通不過osg的問題。
??Qt3D就是與osg類似的一套框架,在細節處理上osg更加靈活但是相對開發過程也會難,反過來qt3D雖然稍微簡單點,但是就存在限制靈活性,學習成本,只能依附與Qt。
??還有一點就是qt很多一些功能提及都是談到其后續會逐步添加-_-!!!
??(以上,是現階段研究的對比,會隨著qt3D的研究推進,加深理解,會回到本篇及時更新兩者的差異,如果不同看法,請留言,共同探討學習進步)。
Qt3D
概述
??Qt 3D提供了一個完全可配置的渲染器,使開發人員能夠快速實現他們需要的任何渲染管道。此外,Qt 3D為渲染之外的近實時模擬提供了通用框架。
??Qt 3D被清晰地分為一個核心和任何數量的方面,這些方面可以實現他們想要的任何功能。這些方面與組件和實體交互以提供一些功能。方面的例子包括物理、音頻、碰撞、人工智能(AI)和路徑查找。
基本三維功能
??Qt 3D是一個3D框架,可以繪制3D形狀并移動它們,以及移動相機。它支持以下基本功能:
用于C++和Qt Quick應用程序的2D和3D渲染
- 網格和幾何體
- 材質
- 著色器
- 陰影貼圖
- 環境閉塞
- 高動態范圍
- 延遲渲染
- 紋理化
- 實例化渲染
- 統一緩沖區對象
- 提示
材質
??Qt 3D擁有強大且非常靈活的材質系統,可實現多個級別的定制。它適用于不同平臺或OpenGL版本上的不同渲染方法,支持具有不同狀態集的多個渲染過程,提供在不同級別覆蓋參數的機制,并允許輕松切換著色器。所有這些都來自C++或使用QML屬性綁定。
材質類型的特性可以很容易地映射到GLSL著色器程序中的統一變量,該程序本身在引用的效果特性中指定。
有關使用材質的示例,請參見以下示例:
- Qt 3D: Simple Custom Material QML Example
- Qt 3D: Advanced Custom Material QML Example
- Qt 3D: PBR Materials QML Example
著色器
??Qt 3D支持所有OpenGL可編程渲染管道階段:頂點、鑲嵌控制、鑲嵌評估、幾何體和片段著色器。計算著色器計劃在未來發布。
有關使用著色器的示例:
- Simple Shader Example
- Qt 3D: Shadow Map QML Example,
- Qt 3D: Wireframe QML Example
- Qt 3D: Wave QML Example.
陰影貼圖
??OpenGL不直接支持陰影,但有無數的技術可以用來生成陰影。陰影貼圖很容易用于生成好看的陰影,同時具有非常小的性能成本。
??陰影映射通常使用兩次渲染來實現。在第一次渲染中,生成陰影信息。在第二個過程中,使用特定的渲染技術生成場景,同時使用第一個過程中收集的信息繪制陰影。
??陰影貼圖背后的想法是,只有最靠近燈光的片段才會被照亮。其他碎片后面的碎片被遮擋,因此處于陰影中。
??因此,在第一個過程中,場景是從燈光的角度繪制的。所存儲的信息只是這個光空間中最近的碎片的距離。用OpenGL的術語來說,這相當于有一個幀緩沖區對象(FBO),上面附著了一個深度紋理。事實上,離眼睛的距離就是深度的定義,OpenGL進行的默認深度測試實際上只存儲最近碎片的深度。
??甚至不需要顏色紋理附件,因為不需要對碎片進行著色,只需要計算它們的深度。
??下圖顯示了具有自陰影平面和三葉結的場景:
??
??下圖顯示了場景的夸張陰影貼圖紋理:
??
??該圖像指示從燈光角度渲染場景時存儲的深度。較深的顏色表示較淺的深度(即更靠近攝影機)。在該場景中,燈光放置在場景中對象上方的某個位置,相對于主攝影機位于右側(將其與第一張屏幕截圖進行比較)。這與玩具飛機比其他對象更靠近攝影機的事實相匹配。
??生成陰影貼圖后,將完成第二次渲染過程。在第二個過程中,使用法線場景的攝影機進行渲染。任何效果都可以在此處使用,例如Phong著色。在片段著色器中應用陰影貼圖算法是很重要的。也就是說,最靠近光線的片段被繪制為亮的,而其他片段被繪制在陰影中。
??在第一遍中生成的陰影圖提供了關于碎片到光的距離的必要信息。然后,在光空間中重新映射片段就足夠了,從而從光的角度計算其深度,以及其坐標在陰影貼圖紋理上的位置。然后可以在給定坐標處對陰影貼圖紋理進行采樣,并且可以將片段的深度與采樣結果進行比較。如果碎片離得更遠,那么它就在陰影中;否則它被點亮。
實例化渲染
??實例化是一種讓GPU繪制基礎對象的多個副本(實例)的方法,每個副本都會以某種方式發生變化。通常,在位置、方向、顏色、材料屬性、比例等方面。Qt 3D提供類似于Qt Quick Repeater元素的API。在這種情況下,委托是基本對象,模型提供每個實例的數據。因此,帶有Mesh組件的實體最終會轉換為對glDrawElements的調用,而帶有實例化組件的實體則會轉換為glDrawElementsInstanced的調用。
??實例化渲染計劃在將來發布。
統一緩沖區對象
??統一緩沖區對象(UBO)可以綁定到OpenGL著色器程序,以使大量數據隨時可用。UBO的典型用例是針對材質或照明參數集。
提示
??在這個頁面上可以找到一些非常有用的3D渲染編程技巧:Qt 3D Render Pro技巧。
可配置渲染器
??為了將對C++和QML API的支持與具有完全可配置的渲染器相結合,引入了幀圖的概念。雖然場景圖是對渲染內容的數據驅動描述,但幀圖是對如何渲染的數據驅動的描述。
??框架圖使開發人員能夠在簡單的前向渲染器(包括z填充過程)和使用延遲渲染器(例如)之間進行選擇。它還讓他們可以控制何時渲染任何透明對象等等。由于這一切都是純粹根據數據配置的,因此即使在運行時動態修改也非常容易,而無需接觸任何C++代碼。可以通過創建自己的實現自定義渲染算法的框架圖來擴展Qt 3D。
三維擴展
??除了在屏幕上顯示3D內容的要點之外,Qt 3D還具有足夠的可擴展性和靈活性,可以作為與3D對象相關的以下類型的擴展的主機:
- 物理模擬
- 碰撞檢測
- 3D位置音頻
- 剛體、骨骼和變形目標動畫
- 路徑查找和其他人工智能
- 揀貨
- 粒子
- 對象生成
表演
??Qt 3D被設計為性能良好,并隨著可用CPU內核的數量而增加,因為現代硬件通過增加內核數量而不是基本時鐘速度來提高性能。使用多個核心效果很好,因為許多任務彼此獨立。例如,路徑查找模塊執行的操作與渲染器執行的任務不會強烈重疊,除非可能是在渲染調試信息或統計信息時。
Qt 3D架構
??Qt3D的主要用例是近實時模擬對象,并將這些對象的狀態渲染到屏幕上。Space Invaders示例包含以下對象:
??
- 玩家的地面大炮
- 地面
- 防守蓋帽
- 敵人的太空入侵者飛船
- 敵人老板飛碟
- 敵人和玩家射出的子彈
??在傳統的C++設計中,這些類型的對象通常被實現為在某種繼承樹中排列的類。繼承樹中的各個分支可能會為根類的功能添加附加功能,例如:
- 接受用戶輸入
- 播放聲音
- 已設置動畫
- 與其他對象碰撞
- 在屏幕上繪制
??“太空入侵者”示例中的類型可以根據這些特征進行分類。然而,為這樣一個簡單的例子設計一個優雅的繼承樹并不容易。
??這種方法和繼承的其他變體存在許多問題: - 深入而廣泛的繼承層次結構很難理解、維護和擴展。
- 繼承分類法是在編譯時確定的。
- 類繼承樹中的每個級別只能根據單個標準或軸進行分類。
- 隨著時間的推移,共享功能往往會使類層次結構膨脹。
- 無法預測開發人員想要做什么。
??擴展深度和廣度的繼承樹通常需要理解并同意原作者使用的分類法。因此,Qt3D將重點放在聚合上,而不是將繼承作為將功能賦予對象實例的手段。具體而言,Qt 3D實現了實體組件系統(ECS)。
使用ECS
??在ECS中,實體表示模擬對象,但其本身沒有任何特定的行為或特征。通過使實體聚合一個或多個組件,可以將附加行為移植到實體上。每個組件都是對象類型行為的垂直切片。
??在“Space Invaders”示例中,地面是一個帶有附加組件的實體,該組件“告訴”系統該實體需要渲染以及需要什么類型的渲染。敵方太空入侵者飛船是另一個帶有附加組件的實體,這些組件可以對飛船進行渲染,但也可以使其發出聲音、與之碰撞、設置動畫,并由簡單的人工智能控制。
??玩家的地面大炮實體與敵方太空入侵者飛船的組件大多相似,只是它沒有AI組件。在它的位置上,大炮有一個輸入組件,使玩家能夠移動它并發射子彈。
ECS后端
??
??Qt 3D的后端以方面的形式實現了ECS范式的系統部分。一個方面實現由實體的一個或多個聚合組件的組合提供給實體的功能的特定垂直切片。
??例如,渲染器方面查找具有網格、材質和可選變換組件的實體。如果呈現器方面找到這樣一個實體,它知道如何獲取這些數據并從中提取一些好的東西。如果一個實體沒有這些組件,呈現器方面會忽略它。
??Qt 3D通過聚合提供附加功能的組件來構建自定義實體。Qt 3D引擎使用方面來處理和更新具有特定組件的實體。
??例如,物理方面尋找具有某種碰撞體積分量的實體,以及指定此類模擬所需的其他特性(如質量、摩擦系數等)的另一個分量。發出聲音的實體具有指定其為聲音發射器的組件,以及指定何時播放以及播放哪些聲音。
??因為ECS使用聚合而不是繼承,所以可以通過添加或刪除組件來動態更改對象在運行時的行為。
??例如,為了使玩家能夠在通電后突然穿過墻壁,可以暫時移除該實體的碰撞體積分量,直到通電超時。沒有必要為PlayerWhoRunsThroughWalls創建一個特殊的一次性子類。
Qt 3D ECS實現
??Qt3D將ECS實現為一個簡單的類層次結構。Qt 3D基類是Qt3DCore::QNode,它是QObject的一個子類。Qt3DCore::QNode為QObject添加了自動將屬性更改傳遞到方面和在整個應用程序中唯一的ID的能力。方面存在于附加線程中,Qt3DCore::QNode簡化了面向用戶的對象和方面之間的數據傳輸。
??通常,Qt3DCore::QNode的子類提供組件引用的額外支持數據。例如,QShaderProgram類指定在呈現一組實體時要使用的GLSL代碼。
??
??Qt 3D中的組件是通過子類化Qt3DCore::QComponent并添加相應方面完成其工作所需的數據來實現的。例如,渲染器方面使用網格組件來檢索應發送到OpenGL管道的逐頂點數據。
??最后,Qt3DCore::QEntity只是一個可以聚合零個或多個Qt3DCore::QComponent實例的對象。
擴展Qt 3D
??為Qt 3D添加功能,無論是作為Qt的一部分,還是特定于您自己的應用程序,以從多線程后端獲益,都包括以下任務:
- 識別并實施任何必要的組件和支持數據。
- 向QML引擎注冊組件(僅當您使用QML API時)。
- 子類QAbstractAspect并實現子系統功能。
基于Qt三維任務的引擎
??在Qt 3D中,在每一幀中要求各方面執行一組任務以及它們之間的依賴關系。任務由調度器分布在所有配置的內核上,以提高性能。
Qt 3D的方面
??默認情況下,Qt 3D提供Qt3DRender和Qt3DInput方面。這些方面提供的組件和其他支持類在這些模塊的文檔中進行了討論。
??更多功能在Qt 3D的未來版本中添加。(汗顏)
上一篇:無
下一篇:敬請期待…
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/140059315