カスタムデプスバッファを使って、壁越しに遮蔽されているメッシュを描画してみました。
遮蔽された部分は単色で、遮蔽されていない部分は通常の色で表示します。
レイヤーを設定
まず、新しいレイヤーを作って、キャラクターのプレハブの体や服、アイテム等のメッシュのあるゲームオブジェクトに設定します。
このレイヤーを持っているものだけが透過します。
カスタムパスを作成
ヒエラルキーで、カスタムパスの設定をする「Custom Pass Volume」コンポーネントの付いたゲームオブジェクトを作ります。
カスタムパスには、画面全体に適用する「Full Screen Custom Pass」とゲームオブジェクトに適用する「Draw renderers Custom Pass」があります。Projectウィンドウで右クリックから作成できます。
対象のゲームオブジェクトが一つなら、Custom Pass VolumeコンポーネントのDepth Testを「Greater」にするだけで壁を透過できました。シェーダーではすべてのピクセルを単色で塗りつぶしています。
しかし、複雑な形状のメッシュだとうまくいきません。
そこで「Draw renderers Custom Pass」でまずカスタムデプスバッファに必要な値を書き込み、「Full Screen Custom Pass」でそれを使ってみました。
Injection Point
Custom Pass Volumeコンポーネントでは、「Injection Point」で Custom Pass Volumeを実行するタイミングを設定できます。今回は「Before Post Process」にしました。
「Before Transparent」では、壁の後ろで透過させて、さらにBake Typeが「Transparent」のマテリアルで遮ると表示されなくなります。
透明なオブジェクトで直接遮蔽した場合は、どちらも通常の色で表示されます。
カスタムパスを追加
「+」ボタンで「Custom Passes」にカスタムパスを追加できます。カスタムパスの種類を選べます。
「Draw renderers Custom Pass」の後ろに「Full Screen Custom Pass」を追加します。順番が違うと正しく描画されません。
Draw renderers Custom Pass
「Draw renderers Custom Pass」では、カスタムデプスバッファに書き込むために「Target Depth Buffer」で「Custom」を選択します。
「Clear Flags」で深度バッファを消去しないと、遮蔽された部分が画面に残ります。
「Layer Mask」で対象のレイヤーを選択します。
「Override Depth」のチェックを入れて、Depth Testを「Less」にし、「Write Depth」を有効にすることで、カメラからより近いものに遮蔽されていない部分のみ書き込みます。
Full Screen Custom Pass
「Full Screen Custom Pass」では、作成した「HDRP Custom FullScreen Pass」が設定されたマテアリルをアタッチします。
シェーダーでは、カスタム深度値とカメラ深度値を比較して、描画する色を決定しています。
float4 FullScreenPass(Varyings varyings) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
// カスタム深度値を取得
float customDepth = LoadCustomDepth(varyings.positionCS.xy);
// カメラの深度値を取得
float depth = LoadCameraDepth(varyings.positionCS.xy);
// 遮蔽されていない部分
if (customDepth == depth || customDepth == 0)
{
// カメラカラーバッファを読み込む
return float4(CustomPassLoadCameraColor(varyings.positionCS.xy, 0), 1);
}
// 遮蔽されている部分
else
{
// 白を描画
return float4(1, 1, 1, 1);
}
}
足が床に埋まる
足が少し床に埋まっていて、常に足元が白くなってしまうので次はこれを改良してみます。