【Unity】HDRPカスタムパスでステンシルを使ったマスク表現

投稿者: | 2024-02-21

HDRPのカスタムパスで、ステンシルを使ったマスク表現をしてみました。オブジェクトで他のオブジェクトをマスクします。

マスクするレイヤーではステンシルバッファに書き込み、マスクされるレイヤーではステンシルテストを利用してバッファの値に基づいて描画を制御します。

レイヤーマスク

まずマスクするレイヤーとマスクされるレイヤーを作りました。シーンにCubeとSphereを追加し、それぞれ専用のレイヤーを割り当てます。

Sphereにマスクされるレイヤーを設定しました。赤いSphereには不透明マテリアル、緑には半透明マテリアルを割り当てています。

カメラのCulling Maskから、マスクされるレイヤーを除外します。

カスタムパス

ヒエラルキーでCustom Passゲームオブジェクトを追加します。

ゲームオブジェクトにCustom Pass Volumeをもう一つ追加します。それぞれのコンポーネントにDraw Renderers Custom Passを一つずつ作ります。

Injection Pointでマスクされるレイヤーが後に描画されないようにします。

1つ目のDraw Renderers Custom Passでマスクするレイヤーを描画しています。Priorityを上げて先に実行されるようにしています。

Override Stencilのチェックを入れます。HDRPによって予約されていないステンシルビットが2つあります。ReferenceとWrite Maskに「User Bit 0」を設定します。Comparisonを「Always」にすると、ピクセルを常にレンダリングします。Replaceで参照値をバッファに書き込んでいます。

もう一方のDraw Renderers Custom Passで、マスクされるレイヤーを描画します。Priorityをより低い値にしています。

「User Bit 0」をマスクとして使用します。参照値がステンシルバッファの値と等しいときにレンダリングします。

深度テストを無効化

マスクされるゲームオブジェクトが遮蔽されていると、ステンシルテストの前に深度テストによって破棄されます。Depth Testを「Disabled」や「Always」にして無効にしています。

これでオブジェクトでマスクすることができました。

Sorting

Sortingで結果が少し変わりました。

Back To Front
Common Opaque

マスクするゲームオブジェクトを無効化

カメラのCulling Maskでマスクするレイヤーを非表示にできます。

参考:https://shibuya24.info/entry/unity-shader-stencil
https://docs.unity3d.com/ja/2021.3/Manual/SL-Stencil.html
https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@14.0/api/UnityEngine.Rendering.HighDefinition.UserStencilUsage.html

コメントを残す

メールアドレスが公開されることはありません。