Qt Quick 3D におけるライトマップベイクとその他の改善点

このブログは「Lightmap Baking and Other Improvements in Qt Quick 3D」の抄訳です。

本ブログでは、Qt Quick 3D のシーンをよりリアルに見せるための最近の改善点として、ライトマップベイク、グローバルイルミネーション、そしてそれらに関連する技術について解説します。主に取り上げるのは Qt 6.10 で追加・改善されたライトマップベイク機能ですが、あわせて 次期 Qt 6.11 で導入予定の 2 つの新機能についても紹介します。具体的には、Screen-space Global Illumination(SSGI)、Screen-space Reflections(SSR)です。
これらの機能により、Qt Quick 3D で作成する 3D シーンは、より自然で現実感のあるライティング表現が可能になります。特に、パフォーマンスとビジュアル品質のバランスが求められるリアルタイム 3D 表現において、大きな進化と言えるでしょう。

ライトマップベイクの改善点

Qt 6.10 のリリースにより、Qt Quick 3D モジュールのライトマップベイク機能は大きく進化しました。QML を使ってリアルタイム 3D シーンを構築しており、実行時の負荷を抑えつつ、よりリッチなライティング表現を実現したい方にとって、非常に注目すべき内容です。このセクションでは、ライトマップベイクとは何か、Qt 6.10 で何が新しくなったのか、それがなぜ重要なのか、を順を追って解説していきます。

ライトマップベイクとは?

ライトマップベイク(Lightmap Baking)は、3D レンダリングにおいて、シーン内の静的オブジェクトに光がどのように影響するかを事前に計算しておく手法です。

リアルタイムでライティング、シャドウ、間接光を計算する代わりに、ライティング情報を「ライトマップ」と呼ばれる専用のテクスチャにオフライン処理で書き込んでおきます。実行時には、レンダラーがこれらのテクスチャをサンプリングするだけで済むため、グローバルイルミネーション、柔らかな影、環境光の反射といった表現を、非常に低い計算コストで実現できます。その結果、GPU リソースが限られるモバイルや組み込みデバイスにおいても、見た目がリッチで高パフォーマンスな 3D シーンを描画することが可能になります。

Qt では バージョン 6.4 以降、ライトマップベイクの基本的なサポートが提供されてきました。本記事では、特に Qt 6.10 で追加・改善された点に焦点を当てて解説します。
ライトマップベイクの仕組みや、アプリケーションへの具体的な実装方法について詳しく知りたい場合は、公式 Qt ドキュメントを参照することをおすすめします。

以下の画像は、ベイク済みライティングを適用した Qt Quick 3D のシーン例です。

Lightmap baking example in a Qt Quick 3D scene

グローバルイルミネーションに関する新機能

Qt 6.10 では、ライトマップベイクに関して数多くの改善が行われました。特に、ベイク作業そのものの使いやすさや、シーン設定時のエルゴノミクス(作業効率・分かりやすさ)の面で大きな進化があります。本記事では、その中でも特に重要なポイントに絞って、ひとつずつ順に見ていきます。

NLMベースの組み込みデノイザー(Denoiser)

Qt 6.10 の Qt Quick 3D には、Non-Local Means(NLM)アルゴリズムを用いた組み込みデノイザーが新たに搭載されており、ライトマップのベイク完了後に自動で実行されます。NLM アルゴリズムは、画像内の類似した領域を平均化することで、レイトレーシング処理によって発生するランダムノイズを効果的に低減します。これにより、ベイクされたライティングがよりクリーンで自然な見た目になります。デノイズの強さは、新しく追加された Lightmapper::denoiseSigma プロパティで調整できます。値を小さくすると、テクスチャのディテールをより多く保持できますが、多少の粒状感(ノイズ)が残ります。値を大きくすると、シャープさは若干失われるものの、より滑らかでクリーンな仕上がりになります。この仕組みにより、ライトマップを外部ツールで後処理する必要はなくなり、Qt Quick 3D がベイク工程の一部として自動的にデノイズ処理を行ってくれるようになりました。
結果として、より手軽に高品質なグローバルイルミネーションを実現できるようになっています。
Comparing a noisy and denoised 3D lightmap

上の画像は、Cornell Box のシーンをノイズのあるライトマップ(左) と デノイズ後のライトマップ(右) で比較したものを示しています。

テクセル密度(Texels-Per-Unit)に基づくライトマップ

Qt Quick 3D 6.10 では、生成されるライトマップの解像度を指定する新しい方法が導入されました。
従来のように各 Model ごとに固定のテクスチャサイズ(幅×高さ)を指定する代わりに、ワールド空間上の単位面積あたりに割り当てるライトマップのテクセル数を指定します。これを Texels-Per-Unit(TPU) と呼びます。

TPU は Lightmapper::texelsPerUnit もしくは Model::texelsPerUnit プロパティで設定します。
たとえば、100×100 の矩形に対して TPU = 1 を指定すると、生成されるライトマップはおおよそ 100×100 テクセルになります。このアプローチの利点は以下の通りです。

  • 複数のモデルを同一シーンに追加しても、ライトマップの密度を簡単に統一できる
  • シーン全体の品質を保ったまま、解像度を一括で上げ下げしやすい
  • モデルごとのスケール差を意識せずに、一貫した見た目を維持できる

なお、直接光による影のシャープさはライトマップの解像度に依存します。
TPU が低すぎると影がぼやけ、高くするとシャープになりますが、その分メモリ使用量とベイク時間は増加します。これは、下の画像に示されている通りです。

Lightmap baking with different texel-per-unit values

上の画像は、同じシーンを異なる Texels-Per-Unit(TPU)値でベイクした結果を示しています。
左側のシーンは右側のシーンに比べて TPU が 5 倍に設定されています。

進捗状況の追跡機能の改善

ebugView の QML コンポーネントからライトマップのベイクを開始すると、ポップアップウィンドウが表示されます。このウィンドウが改良され、進捗バーとベイク完了までの推定残り時間が表示されるようになりました。
また、ベイク処理の実行中でも、メインアプリケーションの操作を継続できるようになっています。

How to see the progress when baking lightmaps with Qt

上記の画像は、ライトマップのベイク中に表示される進捗ウィンドウを示しています。

ライトマップビューア(Lightmap Viewer)

Qt 6.10 における注目すべき変更点のひとつとして、Lightmapper::source プロパティが追加されました。このプロパティは、シーン内で使用されるすべてのライトマップを含む 1 つのファイル を指定します。従来のバージョンでは、ライトマップベイクを行うと、使用されている各 Model ごとにメッシュとライトマップテクスチャファイルが生成されていました。現在では、これらすべてのデータが Qt Quick 3D 独自のカスタムファイルフォーマットを用いて、1 つのファイルにまとめて保存されます。
これにより、ワークフローが簡素化されるだけでなく、このファイルを簡単に確認できるようになりました。その目的のために Lightmap Viewer アプリケーションが作成されています。このアプリケーションを使うことで、生成されたライトマップと、それぞれに対応するモデルを確認することができます。

Qt's 3D lightmap viewer

上の画像は、ライトマップファイルを読み込んだ状態のライトマップビューアを示しています。

スクリーンスペース・グローバルイルミネーション

次に、ライトマップベイクの代替として Qt Quick 3D に追加された新しい手法を見ていきます。SSGI(Screen Space Global Illumination)は、スクリーンの深度バッファおよびカラーバッファに含まれる情報のみを使用して、現実的な間接照明(表面で反射する光)をシミュレートするリアルタイムレンダリング手法です。これは動的なポストプロセスエフェクトであるため、事前にベイクされたライトマップには依存せず、シーン内の動的な変化に反応します。

SSGI は、Qt 6.11 以降で ExtendedSceneEnvironment::ssgiEnabled を true に設定することで有効化できます。SSGI の見た目を調整するための追加プロパティも ExtendedSceneEnvironment に用意されています。

Comparing SSGI (Screen Space Global Illumination) and no global illumination

上の画像は、SSGI が無効なシーン(左)と、SSGI が有効なシーン(右)を示しています。SSGI を有効にすると、床で反射した光によって、サルの頭部やカーテンが照らされていることが分かります。

スクリーンスペース反射(Screen-space Reflections)

スクリーンスペース反射(SSR)は、SSGI と同様のリアルタイムレンダリング手法です。SSGI と同じく、画面の深度バッファとカラーバッファに含まれる情報のみを使用しますが、SSR は反射の描画に用いられます。画面上の各ピクセルを走査し、対応する反射後のスクリーンピクセルを見つけて合成する「レイマーチング」と呼ばれる手法によって動作します。

SSR は Qt 6.11 以降で、ExtendedSceneEnvironment::ssrEnabled を true に設定することで有効にできます。

3D rendering with Screen Space Reflections (SSR)

上の画像は、SSR が無効な場合(左)と、SSR が有効な場合(右)のシーンを示しています。

まとめ

すでに Qt Quick 3D のライトマップベイク機能を使用している方にとって、Qt 6.10 はビジュアル面およびパフォーマンス面の両方で、表現力をさらに高めるものになれば幸いです。まだ試したことがない方にとっても、今がまさに始める絶好のタイミングです。まずは、ベイク済みライトマップのサンプルドキュメントを確認してみてください。

SSGI や SSR を試す場合は、ExtendedSceneEnvironment の QML 型を確認してみてください。

この投稿を楽しんでいただけたなら幸いです。Qt を使って、皆さんがこれからどのようなものを作り上げていくのかを見るのを楽しみにしています。 


Blog Topics:

Comments