Qt3Dの未来

本記事は、Qt World Summit TokyoのGoldスポンサーよるゲスト投稿です。
執筆者:  KDAB社 Sean Harmer様

The Future of Qt 3D

多くの方がすでにご存知の通り、Qt Quick 3D という新しいモジュールによる Qt Quick で QML の API で 3D の機能の提供が始まりました (Qt 6 では C++ の API の提供も計画されています)。 これに伴い Qt 3D の立ち位置にどのような影響があるでしょう? Qt 3D はこの先も生き残っていけるでしょうか? 今回の記事や続編を通して、それらの疑問に対して回答をすると共に Qt 3D の現在の開発内容についても共有できればと思います。この記事では Qt 5.x 向けの内容にフォーカスをし、Qt 6 の範囲の内容については別途記事を書きたいと思います。

Qt 3D はどこで使われるの

Qt 3D は、何を描画するか、どう描画するかについての必要最低限の想定はありますが、非常に自由度の高いフレームワークとして設計されています。自由度の高さがもたらすメリットと、それに由来するデメリットは常にトレードオフの関係にあります。

Qt 3D の利用に際して、その他の Qt のモジュールを使用する場合よりもその分野の専門的な知識が必要になるのがデメリットの1つです。マテリアルのカスタマイズやフレームグラフを用いた描画のアルゴリズムのカスタマイズが必要になるポイントは、想像よりも早くやってくるでしょう。一方で、任意のシェーダーパイプライン経由のデータを、任意のアルゴリズムで描画可能であることは大きなメリットです。

Qt Quick 3D はシンプルな 3D コンテンツに限定することで、簡単に Qt Quick で 3D を使えるような試みです。これもメリット、デメリットがあります。簡単なものが簡単にできるのは間違いないですが、Qt Quick 3D でできない範囲のことをやろうとした場合には、結局自分でやらざるを得なくなります。

例えば、何らかの 3D のモデルを、Qt Quick 3D が提供する何らかのマテリアルを用いて 2D のコンテンツと共存させたいだけの場合には、Qt Quick 3D で問題ないでしょう。しかし、ステンシルバッファを利用し上下反転した物体のクリッピング結果を利用した反射との干渉を考慮するような少し凝った反射表現を実現したい場合には、自分で 3D の描画ロジックを全部書くか、Qt 3D のようなフレームワークが必要となるでしょう。

遅延レンダリングやステンシルシャドウ、ボリュームレンダリング、その他の様々なテクニックが必要な場合も同様です。

Qt Quick 3D がぴったりなケースがあるのと同様に、Qt 3D の良さが活きる場面もあり、それは以下の通りです。

  • これまで紹介したような、技術的に比較的複雑なことが要求されるケース
  • 腕まくりをして、自分の手で作り上げるのが好きな場合
  • QML ではなく、C++ 側の API を利用したより高度なことがしたい場合
  • GPL および商用のライセンスが利用できない場合

実は、3D コンテンツをアプリケーションを組み込む際の選択肢がもう1つあります。KDAB が開発した Kuesa™ 3D Studio を利用することで、高機能の Qt 3D をとても簡単に扱えるようになります。Kuesa は、Qt 3D がベースとなっている 3D 描画のランタイムで、glTF2 形式のモデルを簡単にインポートし利用することができるようになっています。デザイナーが作成したコンテンツを Kuesa を利用した QML/C++ アプリケーションに簡単に組み込めるよう、Blender と 3DS Max 向けのエクスポート機能も提供しています。

the-fture-of-qt3d

Kuesa Runtime 1.1 が間も無くリリースされる予定です。GitHub 上の最新のソースコードをお試しいただくことももちろん可能です。morph アニメーションやボーンアニメーション、物理ベースレンダリング(PBR)の metal-rough マテリアルといった glTF 2 の機能に完全対応しています。というわけで、インターネット上にある様々なモデルのロードが可能になり、付属の内部構造の可視化ツールで把握した内容を元に、個別の部品の制御をアプリケーション側から簡単にできるような仕組みを提供しています。

Qt 3D 自体にでも外部の貢献者に寄る glTF の実装が含まれていますが、glTF 2 の仕様に完全に対応するのはなかなかの作業で Qt3DExtras にバンドルされているマテリアルとは別のアプローチが必要になります。

the-future-of-qt3d

Qt 3D の計画はどうなっていますか?

まずはじめに言いたいことは、Qt 3D は無くなりません。KDAB は Kuesa をはじめとした様々なプロジェクトで利用していますし、世界中に Qt 3D のユーザーはいて、大規模な商用のアプリケーションでの利用事例もあります。

Qt 3D にはパフォーマンス的な問題がいくつかあることは把握していて、アクティブに開発を行なっており、gerrit 上で対応の詳細を見ることも可能です。というわけで、現時点での作業内容と、今後の予定を紹介したいと思います。

スレッドアーキテクチャの改善

Qt 3D は開発当初からマルチスレッド対応の設計になっています。基本的にはこれはいいことですが、非同期での動作によるトリッキーさが存在します。例えば、十分なメモリ確保の仕組みやセマフォの実装が無いようなローエンドの組み込み向けのハードウェアでは、スレッドの使用自体が問題になることがあります。

こういった問題に対処するために、Aspect Thread と呼ばれる機能を Qt 5.14 で削除しました。タスク処理を水平分散するためのスレッドプールはそのままですが、環境変数を通して制御をすることができるようにしました。

一般的なケースでの FBO の使用をやめました

ある3Dのコンテンツを描画し、その上に 2D の UI をオーバーレイ表示する際に、Qt 3D はフレームバッファオブジェクト(FBO)を介する必要がありました。具体的には、まず 3D のコンテンツを OpenGL が描画対象として用意している FBO のカラーテクスチャ(とデプステクスチャ)に描画します。それから、Qt Quick が、そのカラーテクスチャを矩形としてシーングラフ上で他の要素と合成します。

これは、デスクトップアプリをはじめ様々な用途でうまく機能しますが、FBO の実装がいまいちなデバイスではパフォーマンスが著しく低下します。3D のコンテンツをシンプルな描画方法(フォワードレンダリング)を利用して背景として描画する場合には、FBO を利用しない形での最適化が可能です。この場合、Qt 3D にコンテンツを背景して直接描画させ、その上に Qt Quick のコンテンツを描画させます。この最適化を行うには、(Qt 5.14 で導入された) Scene3D の compositingMode プロパティを Underlay に指定します。実装をしてくれた Giuseppe D’Angelo と、インテグレーションをしてくれた Paul Lemire に感謝します。

通知システムの改善

3つ目の大きな変更は現在も作業中で、フロントエンドのプロパティの変更をバックエンドに通知する仕組みの改善です。これまでの実装では、プロパティの変更1つ1つに対してデータをイベント的なパケットに変換したものを受け渡しをしていました。膨大な数のエンティティを含む巨大なシーンでたくさんのプロパティがアニメーションしている場合には身動きが取れなくなり、パフォーマンス的にボトルネックになっていました。

様々な試行錯誤の末、KDAB 社の Mike Krus と Paul Lemire はこの重要なサブシステムのパフォーマンスの改善を成し遂げようとしています。改善後にはフロントエンドとバックエンド間でプロパティの変更があった際にはダイレクトに同期処理が走ります。また、1つのオブジェクトで複数のプロパティの変更があった場合には、プロパティごとではなくまとめて更新処理が行われます。ベンチマークでは、巨大なシーンでのプロパティの変更は 200〜300% 速くなるという結果が出ています。

このままうまくいけば、この対応は Qt 5.14 のマイナーアップデートで利用可能になるでしょう。

まとめ

今回の記事で紹介した改善以外にも、様々な場所で改善を行なっています。例えば、フレームグラフの走査は、フレームグラフ内でアウトプットに実質的に影響のある変更が行われた際にのみ実施されるようになりました。uniform の更新も、値が変更された場合にのみ行われるように改善されました。

Qt 5.14 に向けて、数多くの Qt 3D の最適化を行ない、今後も継続的に改善を行なっていく予定です。これらの最適化の結果、1フレームの描画にかかる CPU のオーバーヘッドが素晴らしく減り、いくつかのシステムで時間を浪費指定たスレッドの同期処理も減りました。

次回の記事では、Qt 6 に向けた Qt 3D のリサーチを深掘りし、最近のグラフィックスの API を活用したパフォーマンスの改善の展望について解説したいと思います。

詳細はwww.kdab.jpをご覧ください。


Comments