忙しい人のための「2Dアニメーションに3Dライトを適用する話」

AvatarPosted by

こんにちは!この記事はGRIPHONE Advent Calendar 2021 9日目の記事です。

今年9月、3DXの活動として、2Dゲームにおけるリッチなグラフィクス表現の研究に関してCA BASE CAMPで発表を行いました。
今回は、それに関連して素早く簡単に「2Dアニメーションに3Dライトを適用する」方法を紹介します。

作成したもの

左が元の2Dアニメーションで、右が此方に3Dライトを適用した状態のオブジェクトです。

3Dライトの影響を受けるよう一つ一つ実装していくことが理想ですが、
今回はこちらをとにかくお手軽に実装することを目的として、
ベースのシェーダに予めライティングが反映されているデフォルトのLitシェーダ(URP)を使用しました。

デモ用の2Dアニメーション用の素材は、Unityが提供しているDragon Crashers -2D Sample Projectを使用しました。
Spine風アニメーションにライティングを適用させるサンプルアセットなので、最初からNormal Mapが用意されているので非常に使い勝手が良いです。

3Dライトの反映

ひとまずサンプルの2DアニメーションPrefabをシーンに配置し、
デフォルトのLitシェーダをコピーしたものをアタッチします。

テクスチャ等が外れているため、マテリアルの設定からBase MapNormal Mapをアタッチします。

テクスチャが表示されましたが、各パーツの描画が重なってしまい、Zファイティングが起こっています。

これを解決するためFowardパスにZTest Alwaysを追加し、全てのジオメトリが描画されるようにしました。

Tags{"RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "UniversalMaterialType" = "Lit" "IgnoreProjector" = "True" "ShaderModel"="4.5"}
        LOD 300

        // ------------------------------------------------------------------
        //  Forward pass. Shades all light in a single pass. GI + emission + Fog
        Pass
        {
            // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with
            // no LightMode tag are also rendered by Universal Render Pipeline
            Name "ForwardLit"
            Tags{"LightMode" = "UniversalForward"}

            Blend[_SrcBlend][_DstBlend]
            ZWrite [_ZWrite]
            Cull[_Cull]

            ZTest Always // 追加

            ~~~
        }

※ZTestに関するドキュメント
https://docs.unity3d.com/Manual/SL-ZTest.html

シャドウの追加

最後に落ち影を追加する対応をします。
該当するSpriteのInspectorの右上からDebugモードを選択すると、
隠れていたCast Shadows, Receive Shadowsパラメータが表示されます。

Cast ShadowsをOnに、Receice Shadowsにチェックを加えることで、
スプライトに合わせて影が落ちるようになりました。

最後に

今回はなるべくお手軽に「2Dアニメーションに3Dライトを適用させる」実装を紹介しました。
この方法ではリッチで高品質な表現は厳しいですが、
モック作成や絵作りの確認等には十分活用できるかと思います。

またデモの素材として最初からNormal Mapがアセットを利用しましたが、
Laigter等のツールを使用することで各種Mapを作成することもできます。