Qt 3D的未来展望
如您所知,Qt推出了名為Qt Quick 3D的全新模塊,它基于QML API為Qt Quick增加了3D繪圖能力(預計在Qt 6提供C++ API)。這對Qt 3D有什么影響,未來在Qt世界中它又該如何定位呢?
希望本文以及后續文章可以解答這一問題,同時能深入介紹我們對Qt 3D正在進行的改進。本文將聚焦在Qt 5.x中即將發布的改進,而下一篇文章將會深入介紹在Qt 6時代我們將對Qt 3D做的一些研究和改進。
如何定位Qt 3D?
Qt 3D是一個靈活的框架。為此,它極少限制您要渲染的內容和方式。和任何技術選擇一樣,這么做有利有弊,需要妥協和權衡。
不利的一面是,相對其他Qt模塊而言,Qt 3D要求開發者具備更多的專業知識,您可能會比預想更快地碰到需要實現自定義材質或者在frame graph上實現渲染算法的點。從好的一面來看,您可以完全掌控渲染算法,在完全自定義的著色器流水線中的映射數據。
Qt Quick 3D則試圖克服這些缺點,在Qt Quick 2應用程序中可以更方便地添加簡單的3D內容。當然,這同樣有利有弊。它可以把在應用中添加3D變得簡單,但是如果Qt Quick 3D 沒有提供您想要的功能,那您還是要自定義了。
您如果想用某個內建材質顯示一個3D模型并用一些2D內容蓋再上面,那么Qt Quick 3D可能是很好的選擇。然而,如果您想要實現更多復雜的功能,比如實現自定義反射,即通過模板緩沖區(stencil buffer)正確裁切出上下顛倒的物體外形來模仿倒影,那么您就可能需要自己寫3D渲染代碼或者切換到其他框架,例如Qt 3D模塊。
類似情況還包括,如果您想使用延遲渲染,陰影剪裁,批量渲染或者其他數千種渲染技術。我的意思是說,的確有使用Qt Quick 3D的需求,但是Qt 3D也有適用的場景,它們包括:
- 相比上述更復雜的用例
- 那些愿意擼起袖子動手干的開發者
- 那些希望使用更完整C++ API來代替或補充QML的開發者
- 那些不能使用GPL或商業授權的開發者
還有另一個選項可以簡化在程序中添加3D內容。它使用并釋放了Qt 3D的強大功能,同時又使用簡單。我們開發了Kuesa,它的運行時基于Qt 3D,可以方便導入各種glTF 2格式文件。我們也有導出器,可以借助Kuesa的能力, 把Blender和3DS Max中的設計導出為 C++/QML應用程序。
Kuesa Runtime 1.1很快就要發布了,您現在也可以就通過GitHub嘗試最新的版本。它能完全兼容glTF2標準,包含了變形目標動畫(morph target animation),骨骼動畫和基于物理渲染的粗糙金屬材質(PBR metal-rough materials)。它能讓你輕松加載、查看網絡上各種格式的模型,并通過應用數據控制它們。
得益于一個外部代碼貢獻,Qt 3D中內置部分但完全兼容的glTF2格式支持,這里的工作量非常大并且需要使用與Qt3DExtras完全不同的材質處理方式。
Qt 3D的計劃是什么?
首先,我要明確地說Qt 3D不會消失。Kuesa和其他項目上正在使用Qt 3D,其他公司甚至還在一些非常大的商業應用上使用Qt 3D。
我們知道Qt 3D存在不少性能問題,正如您可能已從gerrit上看到了大量的更新,我們已在非常努力地解決這些問題。下面讓我們簡要梳理一下正在發生的事情和未來計劃。
多線程架構
從一開始,Qt 3D就被設計成多線程模式。通常來說這是件好事,但是隨著異步性的增加,事情會變得棘手。在一些沒有良好內存分配器或信號量實現不理想的低端嵌入式硬件上,多線程實際上可能會礙事。
為了提升這塊性能,我們在Qt 5.14中去掉了所謂的Aspect Thread。仍有一個線程池來并行化任務處理,但是可以通過一個環境變量控制。
在常規場景中去掉幀緩存對象(FBO)
在執行3D內容渲染、再疊加2D UI的常規場景中,Qt 3D不再只能使用幀緩存對象(FBO)了。這種方式首先將3D內容渲染到FBO附加的顏色紋理(以及深度紋理)中,這是OpenGL必須要設置的渲染目標。然后Qt Quick把同一個顏色紋理映射到一個簡單四邊形上,最后與Qt Quick 2場景的其余部分合成。
這個方式在桌面和許多設備上都沒有問題。然而,有些設備的FBO實現非常差,會極大降低性能。如果3D內容嚴格地位于UI下層并使用簡單的渲染方式(通常是正向渲染),那么我們可以對其進行優化,完全避免使用FBO代碼路徑。這時,我們可以命令Qt 3D直接在屏幕上繪制,因為我們明白所有Qt Quick內容都會在這個基礎上覆蓋。要啟用此優化,應使用Scener3D全新的compositingModeproperty(Qt 5.14起),并設置為Underlay。非常感謝Giuseppe D’Angelo實現了這一點,以及Paul Lemire做的集成。
優化消息系統(Notification System)
第三個大變化領域,也是仍在進行中的領域,是改變我們在Qt 3D前、后端發送/接受屬性變化通知的方式。到目前為止,這是通過為每一個屬性變化傳遞類似事件的數據包來實現。在有成千上萬個實體和許多動畫屬性的大規模場景中,這就會讓性能陷入泥沼,并成為瓶頸。
在考慮各種選擇后,Mike Krus和Paul Lemire一直十分努力地重新設計這個重要的子系統,以提高性能。新機制是基于當前端和后端對象變dirty后直接同步的原理。這讓一個對象上的所有屬性可以一次性全部更新,而不是每次調用只更新一個屬性。當前基準測試結果表明,在大規模場景(數千個實體)中,屬性變更通知分發速度加快了200~300%。
如果一切順利,以上這些修改都會在未來的Qt 5.14.x版本中落地。
總結
除了以上改進,我們還在整個代碼庫中引入了許多小的提升。例如,frame graph的遍歷現在只在frame graph中發生了實質性影響輸出的變化時發生。另外還有僅當uniforms的值改變后才會更新的優化。
在Qt 5.14系列中我們對Qt 3D進行了許多優化,并且將來還有更多。這些提升大大降低了CPU渲染幀時額外的CPU開銷,同時減少了線程同步的數量,因為線程同步可能會導致有些系統上的時間浪費。
原文地址
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Qt 3D的未来展望的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GitLab添加SSH Keys并连接(
- 下一篇: Qt 6的Qt 3D会是什么样?