方法 - URP での 2D ライトとシャドウのテクニック
Unity 2022 LTS の ユニバーサルレンダーパイプライン (URP) を使用して、Happy Harvest デモのライトとシャドウがどのように作成されたかを学びます。
Happy Harvest は、サンプルの 2D トップダウン農業シミュレーション ゲームです。この記事で紹介したテクニックやその他の多くのテクニックについては、電子書籍『 アーティストのための 2D ゲーム アート、アニメーション、ライティング』で詳しく説明されています。
このシリーズの他の記事を読んで、Happy Harvestのエフェクトとビジュアルを再現する方法を学びましょう。
- Unity 2022 LTS で 2D キャラクターをアニメーション化する方法
- 2D タイルマップでアートとゲームプレイを作成する方法
- VFX Graph と Shader Graph を使用した 2D 特殊効果 (近日提供開始)
今すぐ Unity Asset Store からHappy Harvest を ダウンロードしてください。
ダイナミック 2D ライティングは、レベルの雰囲気を劇的に変え、ゲームプレイを強化します。例としては、洞窟をたいまつで照らす、窓から光を当ててキラキラ光る塵の粒子を強調する、そして 「Happy Harvest」の場合のように昼から夜へのサイクルのシミュレーションをアニメーション化する、などが挙げられます。
Unity の高度な 2D ダイナミック ライティング システムとスプライトの セカンダリ テクスチャ を組み合わせることで、効果的なリム ライティングと明確なシェーディングの詳細により、キャラクターを際立たせることができます。
2D ライトは 、Light 2D コンポーネントがアタッチされた GameObject です。これらは、Sprite Renderer、Sprite Shape Renderer、および Tilemap Rendererと連携して動作します。また、ソート レイヤーも使用されており、各ライトは 1 つ以上のレイヤーに影響を与えることができます。[ターゲット並べ替えレイヤー] ドロップダウン リストで、影響を受けるレイヤーを選択できます。
2D ライトには 4 つの種類 があります。
フリーフォーム: これらは n 辺の多角形のような形状にすることができます。このタイプのライトは、非有機的または様式化された環境で使用できます。これは、環境の大部分 (溶岩プールなど) を効率的に照らす場合や、光の形状 (天井の開口部から差し込む光線など) をシミュレートする場合、または光が投影される窓の形状に合わせる場合に適しています。
Sprite: この形状により、任意のスプライトをライトのテクスチャとして使用できるようになります。これは、他のライト タイプでは実現できない特定の形状が必要な場合に便利です。可能なテクスチャの例としては、レンズフレア、グレア、ライトクッキー、ディスコボールライトなどの光の形状投影、壁に星を投影するランプなどがあります。
Spot: このライトは、円形または円形セクターになります。スポットライト用、または、トーチの火、キャンドル、車のライト、懐中電灯、ボリュームライトなどで特定のポイントを照らすために使用します。
グローバル: このライトには形状はありませんが、対象となるソート レイヤー上のすべてのオブジェクトを照らします。ブレンド スタイル (ライトとスプライト間の相互作用の方法) およびソート レイヤーごとに、グローバル ライトを 1 つだけ使用できます。まずこれを使用して、基本環境ライトを追加します。
次の 設定は 、各ライト タイプで使用できます。
ブレンドスタイル: ブレンド スタイルは、特定のライトがシーン内のスプライトと相互作用する方法を決定します。シーン内のすべてのライトには、使用可能な 4 つのブレンド スタイルまたはモードのいずれかが必要です。加算、変調、減算、カスタム。各モードは、スプライトが光によって照らされる方法を制御します。
ライトオーダーとオーバーラップ操作:これらを使用すると、複数のライトが同じピクセルに影響を与えている場合に何が起こるかを制御できます。
影:このオプションを有効にすると、シャドウ キャスターを備えたゲーム オブジェクトがこの光源から影を落とします。
容積:これにより、投影された影の明暗の減衰を制御できます。
法線マップ:有効にすると、スプライト上の法線マップ情報を使用して、ピクセル方向に基づいて光の量を計算します。
スプライト エディター > セカンダリ テクスチャを使用して、2D プロジェクト内のすべてのスプライト アセットにオプションの セカンダリ テクスチャ を割り当てることができます。セカンダリ テクスチャには 2 つの種類があります。法線マップとマスクマップ。Happy Harvest では、 キャラクターからタイルマップ、小道具まで、すべての要素に法線マップとマスクマップが使用され、高品質のリアルタイムの照明と影の効果を作成できます。
法線マップ
ライトと法線マップは、Happy Harvest 全体で使用され、ボリューム感を演出し、デモにユニークな外観と雰囲気を与えています。スポット ライト、ポイント ライト、フリーフォーム ライトで法線マップを使用できます。
法線マップの作成方法によって、スプライトが 3D であるという錯覚が生じるかどうかが決まります。法線マップの各ピクセルには、メインテクスチャの角度に関するデータが格納されます。赤、緑、青 (RGB) チャネルには、X、Y、Z 座標の角度データが格納されます。法線マップを使用するすべてのライトには方向があり、法線マップを含むテクスチャ上のピクセルは、この方向とピクセルの方向に基づいてシェーディングされます。これは現実世界での光の働きを模倣したものです。ピクセルが光の方向を向いている場合は点灯し、反対を向いている場合は光を受け取りません。
マスクマップ
マスクは、ライトがスプライトに影響を与える場所を制御します。マスク チャネルとして選択できるチャネルは 4 つあります。赤、青、緑、アルファ。マスクの最大値は完全な光を意味し、最小値は光がないことを意味します。
マスク マップを使用すると、ビジュアルに詳細を追加できるため、ゲームを洗練させることができます。これらは 2D ライト ブレンド スタイルでも使用されます。
ブレンド スタイルは、特定のピクセルのライトの値を取得し、その値を同じピクセルのマスクで乗算します。結果として得られるマスクされたライトの値は、選択されたブレンド スタイルに基づいて、そのピクセルの色に加算、減算、または乗算されます。
リムライトに使用するマスクマップ
読みやすさを考慮して、キャラクターが動くときにシルエットの周りにリムライトが付けられることがよくあります。リムライティングは、キャラクターの輪郭を強調するために使用される効果です。オブジェクトの背後から来る光と光の散乱の自然な特性をシミュレートします。これはフレネル効果とも呼ばれます。横スクロールの 2D ゲームでは、地面と背景によってキャラクターのシルエットを強調することができます。トップダウンのゲームでは、シルエットは環境に埋め込まれているため、形状を区別するために明確なリムライトを使用すると効果的です。
Happy Harvest のメイン キャラクターと小道具には、リム ライト効果用のマスク マップが含まれています。メインキャラクターはRチャンネルでライト部分を描画し、小道具はGチャンネルで描画します。その理由は、キャラクターのシルエットを通常の小道具とは異なる方法で照らすためです (ブレンド スタイル チャネルの R チャネルにのみ影響する異なるライト セットを使用)。
覚えておいてください、法線マップは Normal Map として Unity にインポートされ、マスク マップはテクスチャ タイプ Defaultとしてインポートされる必要があります。これにより、Sprite Atlasを使用してテクスチャをパックするときに、各テクスチャが重複を避けるために正しいアトラスにのみパックされるようになります。
すでに影が描かれているスプライトでは、2D ライティングは見栄えがよくありません。また、法線マップで照明を「ペイント」することになるため、作業量は 2 倍になります。代わりに方向性のない影をペイントすると、太陽光などの方向性のある光を避けている限り、スプライトの見栄えが良くなります。
すべてのスプライト、タイル、またはスプライトの形状に対して法線マップを作成すると、時間がかかることがあります。生成のためのさまざまな手法を組み合わせたり、本当に重要な部分では手作業に時間を費やしたり、背景小道具のプロセスを自動化したりすることを検討してください。なお、Blender や 3ds Max などの 3D モデリング ソフトウェアから 2D スプライトを生成する場合、このテクスチャは簡単に生成できるはずです。
いくつかの例を見てみましょう:
- 既存の法線マップをモーフィングして、手元の 2D オブジェクトに適合させます。たとえば、指輪や宝石では、画像のサンプル法線マップを使用できます。
- SpriteIlluminator、NormalPainter、Krita の Tangent Normal Brush、Laigter などの法線マップ ジェネレーター ツールを使用します。
- ジェネレーター アプリはスプライトの角度を考慮しないので、スプライト全体に使用することは避けてください。彼らは物体も認識しません。代わりに、スプライトの色から形状を推定したり、画像編集アプリのベベルやエンボスに似た一般的なフィルターを追加したりして形状を推定します。
- 顔の角度を認識することはできませんが、角度が変化する場所を推測しようとします。この制限にもかかわらず、チェーン、ケーブル、ドラゴンの尾などの面取りされたスプライト セクションの法線マップや、レンガ、石、木材などの表面法線を生成するのに役立ちます。
- Unity は、グレースケールの高さマップから法線マップを生成する方法を提供します。これは、黒が最小表面高さを表し、白が最大高さを表すテクスチャです。画像を法線マップとしてインポートし、「グレースケールから作成」 オプションをオンにします。このテクニックは、エンジンを離れることなく法線マップをすばやく生成するのに便利です。
- サンプル画像から色をサンプリングします。まず、法線マップ パレット (オンラインで見つけることができます) を入手して、表面の角度を表すために使用される色をサンプリングします。お気に入りのペイント アプリにパレットをコピーし、カラー ピッカーを使用して法線マップ上にペイントする色を選択するだけです。
- 角度の色は 100% 正確である必要はありません。ただし、スプライトの全体的な形状が信頼できるものになるようにしてください。文脈上意味をなさない角度の色を使用すると、照明を当てたときに形状が崩れてしまいます。
- 法線マップをペイントするには、優れた空間的想像力が求められるため、最初は難しい場合があります。頭のベースプレーンのような単純なものから始めてみましょう。ここで使用される例は、ローポリゴンの外観を持つ簡略化された人間の頭部モデルです。
- 法線マップをペイントするときは、スプライトの一部である基本的な 3D 形状を想像し、各部分の角度を視覚化します。角度がわかれば、パレット スプライトのどの部分から色をサンプリングするかがわかります。
- ここで示すサンプル画像は平らな表面で作業していますが、柔らかいブラシでペイントする場合もプロセスは同様です。ハードエッジをブレンドして、より自然な外観を実現できます。
- オブジェクトに、RGB チャネルごとに 1 つずつ、3 つの異なる角度から光と影を手動でペイントし、カラー チャネルを組み合わせます。上から来る光には G チャンネルを使用し、右側から来る光には R チャンネルを使用し、中央から来る光には B チャンネルを使用する必要があります。B チャネルはオプションなので、作業負荷を軽減しながらも、リアルな外観を実現できることに注意してください。
グローバル ライトはシーン全体に影響するため、雰囲気を簡単に変えることができます。これらは、デモ (Ambient Light と呼ばれる GameObject) で使用され、全体的な色合いを適用し、暗い領域を回避します。
すべての新しいシーンには、デフォルトで 2D グローバル ライトが追加されます。シーンに均一な色合いを適用するために、白にしたり、色、強度、または影響を受けるレイヤーを変更したりする必要はありません。
シーンにはグローバル ライトが 1 つだけ存在する必要があります。パラメータを操作することで、強度を下げてシーンに紫色の色合いを適用し、夜間などのさまざまな環境条件を簡単にシミュレートできます。デモでは、時刻に基づいて色が変化し、この効果は DayCycleHandler スクリプトによって管理されます (後述)。
Happy Harvest では、大きなスポット ライトがキー ライトとして使用されます。カメラに取り付けられているため、常に画面上に表示され、太陽の動きをシミュレートするスクリプトによって回転します。
2D シーンには、3D シーンのような方向ライトはありません。ただし、X 位置と Y 位置からスプライトを照らす光源を使用することができます。これにより、日が進むにつれて太陽が移動するなどの効果を作成できます。これは、トップダウン ゲームやシミュレーション ゲームで重要になる場合があります。また、ローエンドのプラットフォームをターゲットにしている場合、大きなライトを使用するとコストがかかることにも注意してください。この記事の最後にあるパフォーマンスのヒントのセクションを確認してください。
デモでは、 4 つのライトがアタッチされた LightsRotatorという子 GameObject を探します。
夜の光:月明かりの方向をシミュレート
明け:太陽光の方向をシミュレートします(NightLight の反対の位置)
NightLightRim: NightLightの月方向ライトに似ていますが、キャラクターとプロップのリムライトのみに使用できます。
DayLightRim: DayLightの太陽光方向ライトに似ていますが、キャラクターとプロップのリムライトのみに使用できます。
これらのライトの動きを制御するスクリプトは、一日を通しての色の変化も制御します。グラデーションは、特定の時間に各ライトの色を選択します。これらのグラデーションは、DayCycleHandlerGameObject にアタッチされた DayCycleHandler スクリプトで確認できます。
「Happy Harvest」 では、ボリューム感を表現するために、あらゆる場所でライトと法線マップが使用されています。スポット ライト、ポイント ライト、フリーフォーム ライトで法線マップを使用できます。スプライトで法線マップを使用するには、ライト オブジェクトで法線マップを有効にする必要があることに注意してください。2 つの品質設定が利用可能です:高速かつ正確。
法線マップを有効にすると、ライトの位置に基づいて茂みのボリュームがどのようにシミュレートされるかを確認できます。街灯やその他の小道具は興味のあるエリアを照らし、プレイヤーが道を進むのに役立ちます。
2D オブジェクトは、Shadow Caster 2D コンポーネントを任意のスプライトまたはアニメーション キャラクターにアタッチすることで、無限の影を投影できます。
光の領域が限られている場合や、街灯や暖炉のように強く集中した光源がある場合、無限の影が美しい効果を生み出します。
スプライトでそのテクスチャを使用するには、ライト オブジェクトで法線マップを有効にし、シャドウ オプションをアクティブにすることを忘れないでください。
さらに、トップダウンのゲームでは非現実的に見えるため、キャラクターのシルエットに影を投影しないでください。Shadow Caster 2D コンポーネントは、キャラクター ゲームオブジェクト内の足のボーン (Visual > Prefab_character_base > root_bone > … > foot_r_bone および foot_l_bone) に接続されているため、足にのみ影響します。
トップダウンのゲームでは、太陽光による無限の影の投影が奇妙に見えることがあります。Happy Harvest で使用されている手法は、時間帯に応じて回転したり伸びたりする木や茂みのブロブ シャドウを使用するというものです。結果、アート ディレクションに沿ったより柔らかい影が生まれます。
スクリプト内の関数 UpdateShadow は この影を回転します。他のブロブ シャドウと同様に、これはスプライト ベースのライトです。これを確認するには、Treesと呼ばれる親 GameObject 内の任意の GameObject を調べます。RotationHandleという名前の GameObject 内で ShadowLong という子 GameObject を探します。Shadow Instance スクリプトは、UpdateShadow スクリプトに RotationHandle を追加します。このスクリプトはマネージャーとして機能し、関数を使用して影のサイズと回転を更新します。
ブロブ シャドウは、看板や木などの小さいオブジェクトや平らなオブジェクトに適しています。しかし、奥行きがあり、形がはっきりした大きな建物では、正確な影を落とす必要があります。Happy Harvestでは、フリーフォーム ライトによってこれらの影が作成されます。これらは、建物が地上に投影する様子を模倣したもので、2D には奥行き情報がないため、必要な近似値となります。
明確に定義された影に関する課題は、それを昼から夜へのサイクルに合わせて機能させる方法です。影が太陽のさまざまな位置に反応するように、Light Interpolator スクリプトは、さまざまな参照影の間でフリーフォーム ライトのベクトル ポイントをトゥイーンします。
デモの階層で、Light_2D_Warehouseという名前の GameObject を見つけます。4 つのフリーフォーム ライトが取り付けられており、太陽が建物の上下左右にあるときに建物が投影する影を模倣しています。このスクリプトは、API を使用してさまざまなベクトル ポイントを移動し、スムーズな補間を作成します。
最初に上部の影が作成され、その後変更されて他の影が作成されます。各影に同じ数のポイントがあり、各影を作成するときにそれらのポイント間の遷移が考慮されていることを確認することが重要です。
影が作成されると、日中の各影の時間的な重みを示す正規化パラメータとともに、Light Interpolator コンポーネント スクリプトに追加されます。スクリプトの プレビュー時間 機能を使用すると、エディターでどのように表示されるかを事前に視覚化できます。
DayCycleHandler マネージャーは、昼から夜へのサイクルを調整するスクリプトです。いくつかの機能を詳しく見てみましょう。
Lights Root という名前のゲームオブジェクトは、日光と月光をシミュレートするためのスポット ライトを含む親です。DayCycleHandler スクリプトによってローテーションされます。
ナイトライト、アンビエントライト、リムライトは、それぞれの目的を表すために名前が付けられています。グラデーションは、適切な雰囲気を作り出すために各ライトが表示する色合いです。
「Day Duration in Seconds」 変数では、日中の継続時間を秒単位で定義し、開始時刻を設定できます。テスト時間では、エディターでさまざまな時間にゲームがどのように見えるかを事前に視覚化できます。
有限の影の効果を制御するパラメータは、Shadow Angle と Shadow Lengthです。これらの各フィールドでは、アニメーション カーブが 1 日を通しての時計回りの影の角度を示します。長さパラメータは、特定の瞬間の影の長さを定義します。たとえば、太陽が沈むときには長い影が必要になり、太陽がシーンを垂直に照らすときには短い影が必要になる場合があります。シャドウ角度とシャドウ長さの設定を更新するには、テスト時間スライダーを移動する必要がある場合があることに注意してください。
特にモバイル プラットフォームで 2D ライティングを使用する場合の一般的な懸念は、ゲームにライトを追加するコストです。サポートされている最低仕様で実際のターゲット ハードウェアでテストすることをお勧めします。パフォーマンスを向上させるために適用できる一般的な最適化もいくつかあります。
充填率をできるだけ低く保ちます。1 つの大きなライトは、複数の小さなライトよりもパフォーマンスが劣る可能性があります。
ライトはバッチ処理可能な場合に最もよく機能します。連続するレイヤー間で同じ照明設定を持つライトはすべて一緒に描画できます。
レンダリング スケールをできるだけ低く保ちます。レンダリング スケールは、照明をレンダリングするときに使用するテクスチャ サイズを調整します。テクスチャ サイズが小さいほど、レンダリングされるピクセルが少なくなります。
画面上の影を落とすライトの数を最小限に抑えます。影を描画するように切り替えると、パフォーマンスに大きなコストがかかります。
画面上のさまざまなブレンド スタイルの数を最小限に抑えます。ブレンド スタイルを描画するように切り替えると、かなりのコストがかかります。
プロジェクトのニーズに合わせて、Max Light Render Textures と Max Shadow Render の数を調整します。数値を大きくするとパフォーマンスが向上しますが (限度まで)、必要なメモリも増加します。正しい番号を見つける必要があります。
まだダウンロードしていない場合は、Unity での 2D ゲーム開発とレンダリング (3D および 2D) を解説した以下の高度な電子書籍を必ずダウンロードしてください。
アーティスト向けの 2D ゲーム アート、アニメーション、照明
上級 Unity クリエイター向けのユニバーサル レンダー パイプライン入門
Unity の HD レンダリング パイプラインにおけるライティングの決定版ガイド
さらに、他の 2D デモ「The Lost Crypt」 と 「Dragon Crashers」もご覧ください。
上級プログラマー、アーティスト、テクニカルアーティスト、デザイナー向けのリソースが 、Unity ベストプラクティスハブにさらに見つかります。