Version: 2023.1
言語: 日本語
ライトマッピングとシェーダー
ライトマップ UV 入門

ライトマップ UV 入門

Realtime Global Illumination (リアルタイムグローバルイルミネーション) システムと Baked Global Illumination (ベイクしたグローバルイルミネーション) システムは、どちらもライトマップを使用するため、ライトマップ UV が必要です。

Unity は、リアルタイムグローバルイルミネーションシステムとベイクしたグローバルイルミネーションシステムに別々の一揃いのライトマップ UV を使用します。これには 2 つの理由があります。

  • インスタンスのグループ化に関して、リアルタイムライトマップとベイクしたライトマップの間に直接の一致はありません。同じリアルタイムライトマップのインスタンスが、2 つの異なるベイクしたライトマップに存在する場合があり、その逆もあります。
  • 異なるスケールで表示されるメッシュは、ベイクされたライトマップではライトマップの UV を共有しますが、リアルタイムライトマップでは UV を共有しません。

ベイクしたライトマップ

ベイクしたライトマップ UV はメッシュ単位です。同じメッシュのすべてのインスタンスは同じベイクドライトマップ UV を共有します。Unity はモデルをインポートする際にベイクドライトマップ用の UV を計算することができますが、独自のデータを提供することもできます。

Unity はメッシュにベイクされたライトマップ UV を Mesh.uv2 チャンネルに保存します。このチャンネルは TEXCOORD1 シェーダセマンティックにマップされ、一般に “UV1” と呼ばれます。

ベイクしたグローバルイルミネーションが有効で、与えられた MeshRenderer がライトマップからグローバルイルミネーションを受け取る場合、Unity は Mesh.uv2 チャネルのデータを使用して、ベイクされたライトマップをメッシュに正しくマップします。

ノート: 与えられたメッシュで Mesh.uv2 を別の目的で使用する場合、そのメッシュを使用するすべての MeshRenderer コンポーネントが、ライトマップではなくライトプローブからグローバルイルミネーションを受け取るようにする必要があります。これを変更するには、Mesh Renderer コンポーネントのインスペクター 、またはMeshRenderer.receiveGI API を使用します。

詳しくは、ライトマップ UV の生成 を参照してください。

リアルタイムのライトマップ UV

リアルタイムのライトマップ UV は Mesh Renderer ごとです。同じメッシュのすべてのインスタンスは同じ入力データを共有しますが、Mesh Renderer の異なるインスタンスはランタイムに異なるリアルタイムライトマップ UV を使用できます。Unity は事前計算のステージでリアルタイムグローバルイルミネーションシステム用の UV を計算します。この計算はメッシュごとの UV を入力とし、そのデータを使ってメッシュごとの Renderer UV を作成します。Unity はモデルのインポート時に入力のメッシュごとの UV を生成することができますが、自身でデータを提供することもできます。

これは以下のように動作します。

  • Unity は、Mesh.uv3 チャンネルのデータを、リアルタイムのライトマップ UV 計算の入力として使用できます。 Mesh.uv3 は TEXCOORD2 シェーダのセマンティックにマップされ、一般に “UV2” と呼ばれます。
  • Mesh.uv3 にデータがなく、 Mesh.uv2 にデータがある場合、Unity は Mesh.uv2 のデータをリアルタイムライトマップ UV 計算の入力として使用するようにフォールバックします。Mesh.uv2 はベイクドライトマップ UV のために使用されます。リアルタイムライトマップ UV の入力データとしてベイクしたライトマップ UV を使用するのが一般的です。
  • 計算結果は MeshRenderer ごとに MeshRenderer.enlightenVertexStream に保存されます。リアルタイムグローバルイルミネーションが有効で、与えられた MeshRenderer コンポーネントがグローバルイルミネーションに貢献し、そのグローバルイルミネーションをライトマップから受け取る場合、Unity は自動的に Mesh.uv3 のデータではなく、MeshRenderer.enlightenVertexStream のデータをシェーダーの TEXCOORD2 に渡します。

ノート: リアルタイムグローバルイルミネーションを使用するメッシュで Mesh.uv を別の目的で使用する場合、そのメッシュを使用する全ての MeshRenderer コンポーネントがライトマップではなくライトプローブからグローバルイルミネーションを受け取るようにする必要があります。Mesh Renderer コンポーネントのインスペクター、またはMeshRenderer.receiveGI API でこれを変更してください。

詳しくは、ライトマップ UV の生成 を参照してください。

リアルタイムのライトマップ UV の計算方法

Unity がメッシュごとの入力 UV を、メッシュごとのレンダラーの出力 UV に処理する際に起こっていることを説明します。

パッキング

Unity は、各チャートの境界が全方向の中心テクセルに当たるようにリアルタイムライトマップ UV を再パックし、各チャートの境界の周りに半テクセル分のパディングを追加しています。これにより、すべてのチャートは、それらの間の完全なテクセル空間を持つことが保証されます。

これは、リアルタイムライトマップの解像度を意図的に低くして、リアルタイムに更新できるようにしたためです。このライトマップは低周波の間接光を保存するだけなので、低解像度はグラフィカルな品質に影響しませんが、チャートがテクセルを共有するときににじみが発生することがあります。再パッキングを行うと、チャートが決してテクセルを共有しないようになります。これはこの問題を回避し、また Unity が効率的にチャートを隣り合わせにパックすることを可能にします。

ノート: このパッキングテクニックは、計算された UV がインスタンスのスケールとライトマップの解像度に依存することを意味します。そのため、リアルタイムのライトマップ UV は Mesh Renderer ごとになります。ただし、Unity は可能な限り自動的にこれを最適化し、同じスケールとライトマップ解像度で同じメッシュを使用する Mesh Renderer は同じ UV を共有します。

マージ

任意で、このプロセス中に可能な限り UV チャートをマージするように Unity に指示することができます。これにより、ライトマップのサイズが小さくなり、ランタイムメモリ使用量とパフォーマンスが向上する可能性があります。

この最適化は、Mesh Renderer コンポーネントを持つどのゲームオブジェクトでも可能です。Mesh Renderer Inspector で、 Lightmapping セクションに移動し、Optimize Realtime UVs をクリックします。

ノート: この機能では、元の UV マッピングの不連続性についての間違いが時々発生します。例えば、意図的に尖らせたエッジを連続したサーフェスと誤認することがあります。このような場合は、この機能を無効にしてください。

ライトマッピングとシェーダー
ライトマップ UV 入門