LoginSignup
8
6

More than 1 year has passed since last update.

【Unity】索敵範囲外を暗くする表現の実装

Posted at

自作ゲームに索敵要素を取り入れてキャラクターの視界外を暗くしたい、そんなときの実装の一例を書いてみます。
stage01.gif

環境

Unity 2020.3.20f1
Universal RP 10.6.0

手法

影を描画する手法のひとつであるステンシルシャドウボリュームを応用してみます。

ステンシルシャドウボリュームとは、影を落とすオブジェクトをライト方向から見たときの輪郭となる頂点を引き延ばし、その引き延ばされてできた領域内を影として描画する手法です。
ステンシルバッファを利用するためこの名前がついています。
ShadowVolume.png
こちらのサイトに概念がわかりやすくまとめられています。

トゥーン調のキャラクターの顔に落ちる髪の影を(ライトによってできる影だと形を制御しにくいため)ステンシルシャドウボリュームの応用で理想的な形に出す、というような使われ方もします。

実装

実装といってもコードはほぼ書かずに実現できます。

純粋なステンシルシャドウボリュームではなく任意の範囲を影にしたいため、その範囲を覆うメッシュをまず用意します。
わかりやすいようCubeのメッシュで見ていきます。
CubeオブジェクトのLayerは新しく追加したものに変更します。ここでは追加Layer名をCoverとしています。
cube1.png

影を描画するべきCubeの内側の範囲は、表面と裏面の差分で求まります。
Animation_.gif
差分を描画するために、ForwardRendererDataファイル(デフォルト名はUniversalRenderPipelineAsset_Renderer.asset)をインスペクタから編集します。

  1. Coverオブジェクトは通常描画しないので、FilteringプルダウンのCoverのチェックをはずす
  2. Coverオブジェクトの裏面部分のステンシル値を+1するRendererFeatureを追加
  3. Coverオブジェクトの表面部分のステンシル値を-1するRendererFeatureを追加
  4. ステンシル値が0未満の部分を描画するRendererFeatureを追加

追加した各RendererFeatureの設定は以下のようになります。
renderer_feature.png

裏面/表面の指定は RendererFeatureでオーバーライドするマテリアルのシェーダでやっています。
裏面のみを通すシェーダコードは以下です。表面のみを通すには"Cull Front"を"Cull Back"と書き換えるだけです。

CullFront.shader
Shader "Custom/CullFront"
{
    SubShader
    {
        Tags { "RenderType" = "Opaque" }

        Pass
        {
            ZWrite Off
            Cull Front
            Blend Zero One
        }
    }
}

3つめのRendererFeatureでステンシルが負の値の部分を描画して完成です。
cube3.png
もちろん表現はオーバーライドするマテリアルのシェーダ次第でなんとでも。
cube4.png

メッシュ生成

mesh.png
動的にメッシュ生成する場合、UnityのMeshクラスには三角形化した配列で渡します。
”三角形分割 耳刈り取り法” とかで調べると実装法がいろいろ出てきます:ear_tone2:
Animation_2.gif


ちなみに、ディファードレンダリングであればワールド座標を格納したGBufferと暗くしたい範囲を書き出したテクスチャを使って.. というアプローチもでき、複雑なメッシュを生成するより楽かもしれません。
UnivarsalRPはいまのところ(ver 10.6.0)ディファード非対応なので、やるならレンダーパイプラインに手を加えたりが必要です。

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6