このページでは

ライトマップとグローバルイルミネーション

はじめに

注: Qt 6.4の時点で 、ライトマップのベイク処理は初期の技術プレビュー段階にあります。今後のリリースにおいて、機能、品質、およびAPIに変更が加えられる可能性があります。

ベイクされたライトマップを使用すると、DirectionalLight 、PointLight 、SpotLight などのライトによる直接照明(ライトが投じる影を含む)を事前に生成することができます。実行時には、フラグメントシェーダーで適切な計算を行う代わりに、また影の場合は計算コストが高くなる可能性があるシャドウマップをリアルタイムで生成する代わりに、事前に生成されたイメージマップがサンプリングされます。

ライトマップは、Model ごとに生成されます。たとえModel に複数のサブメッシュがあり、それゆえに複数のマテリアルが関連付けられていたとしても、モデル全体に対して生成されるライトマップ画像は1つだけです。

ライトマップはレイトレーシングを使用して生成されます。レイトレーシングは本質的に適切なオクルージョン(「光は壁を通り抜けない」)を提供し、ライティングやシャドウマッピングのためのリアルタイム技術よりも、より現実的な影を生成できる可能性があります。

さらに重要な点として、ライトマップは間接照明のベイクも可能にし、グローバルイルミネーションの解決策を提供します。これにより、シーン内の他の表面から反射した光線も考慮されます。

以下に簡単な例を示します。このシーンには 4 つの Rectangle モデルと 1 つの Sphere モデルが含まれており、下向きに配置されたDirectionalLight とPointLight があります。Rectangle モデルは 0 度と 90 度に回転しており、これらはすべてDirectionalLight の方向に対して平行または垂直であるため、リアルタイムのライティング計算の限界が顕著に表れています。

2枚目の画像では、5つのモデルすべてに対してライトマップをベイクした後、ライトマッピングを有効にしてシーンをレンダリングしています。両方のライトは「完全ベイク」に設定されており、直接照明と間接照明の両方がベイクされています。 間接照明には、256個のsamples と最大3個のbounces が使用されています。生成されたライトマップはその後、ノイズ除去処理が施されました。これにより、はるかにリアルな画像が得られています。

リアルタイム照明

球体、長方形、そして2つのライトを使ったシンプルなシーン

完全ベイク済みライティング

両方のライトを「フルベイク」に設定した同じシーン

以下は、ライトマップ処理の結果がどのように得られたかを示すスニペットです。違いは、usedInBakedLighting 、bakeMode 、およびbakedLightmap のプロパティにあります。この例では、ディスク容量を節約し、アプリケーションの読み込み時間を短縮するために、texelsPerUnit プロパティを使用してライトマップのサイズを縮小しています。

DirectionalLight {
    bakeMode: Light.BakeModeAll

    eulerRotation.x: -90
    brightness: 0.5
    castsShadow: true
    shadowFactor: 75
}
PointLight {
    bakeMode: Light.BakeModeAll

    y: 200
    z: 100
    color: "#d9c62b"
    castsShadow: true
    shadowFactor: 75
}
Model {
    usedInBakedLighting: true
    bakedLightmap: BakedLightmap {
        enabled: true
        key: "sphere1"
    }

    source: "#Sphere"
    materials: PrincipledMaterial { }
    y: 100
}
Model {
    usedInBakedLighting: true
    bakedLightmap: BakedLightmap {
        enabled: true
        key: "rect1"
    }

    source: "#Rectangle"
    materials: PrincipledMaterial { }
    eulerRotation.x: -90
    scale: Qt.vector3d(10, 10, 10)
}

// ... three additional Rectangle models, with rotations 0, 90, and -90

上記の例では、完全にベイクされたライトを使用しています。 また、ライトの設定を変更することで、間接照明にはベイクされたライティングのみを使用し、直接照明とシャドウマッピングをリアルタイムで実行するようにすることも可能です。以下のシーンには5つのポイントライトがあり、2枚目のスクリーンショットではすべてが「BakeModeIndirect 」に設定されています。直接照明と影の外観は同じですが、2枚目の画像はグローバルイルミネーションが適度に追加されているため、画質が格段に向上しています。

リアルタイムライティング

スポンザとスザンヌのモデル、および5つのポイントライトが登場するシーン

ベイクされた間接照明を追加した場合

間接照明でレンダリングしたのと同じシーンですが、リアルタイムの直接照明が適用されています

ライトマップを使用する際の重要な考慮事項

ベイク済みライティングに寄与するライトの「bakeMode 」プロパティは、Light.BakeModeIndirect またはLight.BakeModeAll のいずれかに設定されます。後者は、その特定のライトの直接光と間接光の両方がライトマップから得られていることを示します。直接光には常に影も含まれます。 一方、ライトマップを使用して特定のライトについてシーンに間接照明のみを追加し、直接照明の計算(およびシャドウマッピング)はリアルタイムで実行し続けることを意図している場合は、そのライトには代わりにLight.BakeModeIndirect を使用する必要があります。

注:ライトマップは 、一般的に、トランスフォーム、ジオメトリ、マテリアルが静的なモデルに適しています。これは、ベイクされたライティングに関与するライトについても同様です。

たとえば、eulerRotation プロパティをアニメーション化してModel を回転させるシーンでは、そのModel にライトマップを適用すると、視覚的に不正確な結果になります。事前に生成されたライトマップはオブジェクトの1つの回転状態しか捉えていないため、その特定のModel のレンダリング結果は不正確になります。 別の例を挙げると、モデルのサブメッシュの1つのマテリアルが、時間(アニメーション)やユーザーの操作に基づいてbaseColor プロパティを動的に変更する場合も、同様の現象が発生します。 ライトマップは、特定のマテリアルbaseColor のみをキャプチャできます。ライトについても同様です。例えば、時間の経過とともに回転したり、明るさや色などが変化するDirectionalLight は、ベイクされたライティングには適していません。

注:一方で 、ライトマッピングをいつ使用するかは常にデザイナーの判断に委ねられます。特にBakeModeIndirect ライトの場合、ライトマッピングされたシーン内のオブジェクトの一部が動的な挙動を示す場合でも、視覚的に満足のいく結果が得られるシーンは存在するでしょう。

ライトマッピングは、エンジンおよびツールセットにおける複雑な機能です。これは、エンジンのレンダリングパイプラインのいくつかの部分を置き換え、再実装するものです。ライトマップをベイクする際には根本的に異なるレンダリングモデルで動作しますが、それでも同じシーン構造、アセットデータ、およびエンジンデータ構造を利用し、相互に連携します。 レイトレーシングに基づく結果は、多くの場合、リアルタイムの代替手段を上回り、時にはその差が顕著になることもあります。その代償として、関与するモデルやライトが静的である必要があるといった制約や、場合によってはライトマッピング特有の品質やレンダリングアーティファクトの問題が生じることがあります。

実際には、どのような種類の照明をいつ使用するかについては、デザイナーによる芸術的な判断が求められます。「bakeMode 」の3つの設定にはそれぞれ用途があり、複雑で大規模なシーンでは、シーンの特定の部分に何が適しているか、またどのようなモデル、マテリアル、動的な挙動が存在するかによって、異なるライトに対してこれら3つすべてを活用することも十分に考えられます。 ライトマッピングは、あらゆるシーンやアプリケーションで単純にオン/オフを切り替えられるような単純な機能ではなく、特定のシーンにおける照明の要件を慎重に評価することを前提とした強力な機能であり、多くの場合、シーンの内容や挙動をそれに応じて設計する必要があり、 さらに、最終的なアプローチや関連する設定を決定する前に、さまざまなライトマップのベイクや品質設定を模索・テストする「テストと調整」のループを組み合わせる必要があります。

注:ライトマップは 両面表面に対応していません。リアルタイムライティングでは、cull mode がMaterial.NoCulling に設定されたマテリアルは、フラグメントの向きに基づいて法線を自動的に反転させます。ライトマップのベイク処理はビュー空間で行われないため、この機能は利用できません。したがって、この機能に依存するモデルでは、ベイクされたライティングの使用を避けてください。

ライトマップのベイク

ライトマップのベイク(直接光および間接光を捉えた画像マップを生成し、アプリケーションのその後の実行時にレンダラーが利用できるようにするオフライン処理)に関連するプロパティとタイプ:

Qt 6.4の時点で、ライトマップのベイク処理は手動で起動する必要があります。コマンドライン引数--bake-lightmaps が指定されている場合、または環境変数QT_QUICK3D_BAKE_LIGHTMAPS が1 (またはその他のゼロ以外の値)に設定されている場合、エンジンはベイクモードで動作し、ベイクが完了するとアプリケーションを終了します。 ベイク処理の各ステップは、デバッグ出力に表示されるメッセージを確認することで追跡できます。処理の結果、シーン内のすべてのベイク済みライトマップを含むバイナリファイル(デフォルトでは `lightmaps.bin `)が現在の作業ディレクトリに書き込まれます。 また、.raw というファイルも作成されます。このファイルには、ライトマップ全体と、ノイズ除去に必要な追加データが含まれています。各ライトマップは、BakedLightmap::key から取得された一意のキーによって、ファイル内で一意に識別されます。

ライトマップ化されたシーンの準備には、主に以下の手順が必要です:

  • どのモデルがライトマップを使用すべきか、またどのモデルがライトマップの生成に寄与すべきかを特定します。ライトマップ化されたシーンを構成するモデルは、Model::usedInBakedLighting をtrueに設定する必要があります。 ライトマップ処理の対象となるモデル(つまり、ライトマップのベイクが行われるモデル)は、さらにModel::bakedLightmap を有効なBakedLightmap オブジェクトに設定する必要があります。このオブジェクトは、特定のModelオブジェクトインスタンスを一意に識別するキーを提供します(これは、Qt XMLが永続的なディスクストレージ内のモデルデータを識別するためにキーを必要とするためです)。 実行時にライトマップ処理を行う際、正しい結果が保証されるのは、ジオメトリ、トランスフォーム、マテリアルが静的なモデルに限られます。最も一般的な例として、動的に変更されたりアニメーション化されたりした位置、回転、スケールなど、時間の経過とともに非静的なワールドトランスフォームを引き起こす要素があるモデルは、ライトマップ処理の対象外となります。 ただし、特にベイクされた間接照明に寄与するだけで、それ自体がライトマップ化されないモデルについては、表現上の必要性によってこの制限を無視できる場合があります。こうしたモデルでは、動的なトランスフォームがあっても視覚的には許容されることが多々ありますが、これは常に当該のモデルとシーンによって異なります。
  • どのライトをどの程度反映させるかを特定します。Light::bakeMode には3つのオプションがあります:
    • Light.BakeModeDisabled:デフォルト設定であり、ライトマッピングのあらゆる目的において、そのライトが実質的に無視されます。
    • Light.BakeModeIndirect は、シーンにグローバルイルミネーション(間接照明)のレベルを持たせることのみを目的とし、そのライトのレンダリング結果に他の影響を与えない場合、多くの場合「安全な」選択となります。 このモードでは、レンダラーは標準的なリアルタイム手法を用いて、このライトに対する拡散光、鏡面反射、空/環境光、およびシャドウマッピングを含むすべての照明処理を引き続き実行します。 ただし、このライトはプリベイクされたデータを使用して間接照明に寄与するため、標準的なリアルタイムの照明計算では照らされない表面が照らされる可能性があります。
    • Light.BakeModeAll は、特定のシーンに対して何が適切であるかをデザイナーが評価した上で、特定のライトにのみ使用される可能性が高いオプションです。このモードでは、影を含め、そのライトによるすべての寄与がベイクされます。 Qt 6.4 の時点では、ベイクされた照明の一部としてスペキュラー照明はサポートされていないため、このようなライトにはスペキュラーの寄与は含まれません。 その一方で、これらのライトはレイトレーシングによるベイクされた影を生成し、適切なオクルージョン(例えば、「壁を通り抜ける」ようなことは起こらない)が適用されます。これは、ライトから生じるすべての直接照明の寄与が、実行時に計算されるのではなく、ライトマップのベイク時にレイトレーシングされるためです。 さらに、BakeModeIndirect と同様に、間接照明もベイクされます。
  • シーン(アプリケーション)をベイクモードで実行し、ライトマップが正常に生成されることを確認します。 Qt 6.4 以降、アプリケーションは、ライトマップ化されたシーンが最初に表示されるように構成されるか、あるいはqml ツールなどのQMLビューアを使用して当該シーンを読み込めるように構成されることが想定されています。ベイクが完了すると(その進行状況はコンソールやデバッグ出力で確認できます)、アプリケーションは終了します。
  • シーン(アプリケーション)を通常通り実行し、ライトマップが読み込まれた状態での表示を確認します。その後、調整を開始します:
    • モデルによっては、texelsPerUnit の値をデフォルトより小さく設定した方が適切な場合があります。これは特に、組み込みプリミティブや、ジオメトリが十分に単純なオブジェクトに当てはまります。これにより、ライトマップのサイズが小さくなり、ベイク時間も短縮されます。初回ベイク時にはデフォルト値で十分ですが、その後で値を調整することも可能です。
    • Lightmapperオブジェクトには、妥当なデフォルト値が設定された数多くの設定項目がありますが、デザイナーの期待通りに仕上げるために、これらのうちいくつかを調整する必要が生じることも珍しくありません。 例えば、samples やbounces を変更することで間接照明の品質を調整でき、indirectLightFactor を設定することで間接照明の寄与をより際立たせることができます。特に影の周囲などでアーティファクトが発生する場合は、bias を微調整することで改善できます。
    • 生成されたライトマップのノイズ除去は不可欠です。間接照明はパストレーシングを用いて計算されますが、使用されるsamples の数によっては、ノイズの多い画像が生成されることがあります。 サンプル数を増やすとノイズは減少しますが、ライトマップの生成にかかる時間は長くなります。サンプル数にかかわらず、生成されたライトマップ(バイナリファイルに保存された 32 ビット RGBA 浮動小数点画像)に対してノイズ除去処理を行うことは、ほぼ常に有効です。

Qt 6.5 以降では、DebugView を通じてインタラクティブなランタイムソリューションが提供されています。「Tools」メニューに新しいボタンが追加され、これを押すとベイク処理が開始されます。処理の進行状況を示すウィンドウがポップアップ表示されます。 キャンセルは、キャンセルボタンをクリックするか、このウィンドウを閉じることで行えます。完了すると、ライトマップのバイナリファイルが現在のディレクトリに書き込まれます。

ノイズ除去

以下はコーネルボックスのシーンの例です。最初のレンダリングでは、256個のsamples と最大3個のbounces を使用してベイクされたライトマップを使用しています。2番目の例では、生成された画像ファイルからノイズが除去されており、ノイズがほぼなくなり、結果が大幅に改善されています。

オリジナル

1つのポイントライトが設置されたコーネルボックスのシーン、ライトマップは完全にベイク済み

ノイズ除去済み

ノイズ除去されたライトマップを用いたコーネルボックスのシーン

ノイズ除去は、ベイクされたすべてのライトマップに対して自動的に行われます。作業ディレクトリに既存のベイク済み.raw ライトマップファイルが存在する場合、DebugView のDenoise ボタンをクリックするだけで、ノイズ除去のみを行うことが可能です。また、--denoise-lightmaps 引数を指定してアプリケーションを起動することで、ノイズ除去を行うこともできます。ノイズ除去の強さを調整するには、denoiseSigma プロパティを使用できます。

ライトマップの UV

ライトマップの UV 座標は、通常のテクスチャリングと同じ UV データを使用しません。ライトマップを使用してレンダリングする場合、レンダラーはライトマップをサンプリングする際に UV0 データも UV1 データも使用しません。その代わりに、メッシュ内には追加の専用の UV チャンネルがあり、そこにはライトマッピングの目的に適した方法で配置された UV チャートが含まれています。 これには、重なりを避け、必要に応じてパディングを設けることが含まれます。通常のUVデータにはそのような要件はなく、1つの頂点に対して複数のU座標やV座標を使用することも十分にあり得ます。

適切なUVセットを生成するプロセスは、ライトマップUVアンラップと呼ばれます。 Qtは、ライトマップのベイク時にこの処理を実行し、結果のメッシュをライトマップファイルに保存します。これにより、生成されたライトマップに対しては、常に互換性のあるメッシュが読み込まれ、使用されるようになります。つまり、モデルが常にベイクされたライティングを使用する場合、ソースメッシュファイルをアプリケーションに同梱する必要はありません。

ライトマップのテクスチャサイズ

各モデル(そのすべてのサブメッシュを含む)について、ライトマップのベイク処理は、ライトマップ UV 生成フェーズ中に適切なライトマップテクスチャサイズを決定します。これは、品質、パフォーマンス、およびリソース使用量(ディスクとメモリの両方)に影響を与えます。

特に中~高複雑度のモデルについては、デフォルト設定で十分な場合が多く、調整の必要はありません。

ただし、非常に単純なモデルの場合は、手動でサイズを縮小した方が良い場合があります。ライトマップのサイズを小さくしても視覚的に良好な結果が得られる一方で、アセット(ライトマップ画像)のサイズを縮小することで、ディスク容量とメモリの両方を節約できるためです。これを行うには、texelsPerUnit を適切に小さい数値に設定してください。 そうすることで、モデルのサイズや形状に応じて、texelsPerUnit に一致するように、実際のライトマップの幅と高さがテクセル密度に近づくよう調整されます。

値を変更する際は、変更されたライトマップサイズの効果がどのようなものか評価するために、必ずライトマップを再生成し、結果を視覚的に確認してください。

実行時のライトマップの使用

実行時にプリベイクされたライトマップを使用する際に重要なプロパティと型:

ベイクが正常に完了すると、アプリケーションを通常通り実行する(コマンドライン引数や環境変数を設定せずに)だけで、生成されたライトマップ画像が自動的に読み込まれ、正しくレンダリングされるようになります。これは、ライトマップが最初にベイクされるまでは不可能です。 必要に応じて、アプリケーションはそれらを別の場所に配置したり、Qtリソースシステムを介して実行ファイルの一部として同梱したりすることができます。これは、source プロパティによって有効になります。

前述の球体と 4 つの長方形を含むサンプルコードを例にとると、ベイク処理により、ベイクされたすべてのメッシュとライトマップを含む `lightmaps.bin ` ファイルが生成されます。アプリケーションは、エンジンがこのファイルを見つけられるように、`source` で指定された場所にこのファイルを配置する必要があります。

「Qt Quick 3D - ベイク済みライトマップの例」および「Qt Quick 3D - SSGI ライトマップの例」も参照してください 。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.