【Unity】HDRPカスタムパスでステンシルを使った穴のくり抜き

投稿者: | 2024-02-23

HDRPのカスタムパスでオブジェクトに穴をあけてみました。ステンシルバッファを使って、オブジェクトで他のオブジェクトをくり抜きます。

移動可能な穴が作れます。リアルタイムライトも機能します。

ステンシルで穴をあけるために、穴の形状のオブジェクトをマスクとして使います。

まず、カメラにオモテ面を向けた、遮蔽されている部分でリファレンス値をステンシルバッファに書き込みます。

カメラに裏面を向けた、遮蔽されていない部分も書き込みます。

書き込み

ステンシルテストによって、書き込んだ部分以外にCull Frontで描画します。

これでオブジェクトに穴を開けることができました。

今回はHDRPのDraw Renderersカスタムパスでやってみました。

法線を反転させる

マテリアルのCull Modeを「Front」にすると、オモテ面を除外できます。

裏面が描画されると、ライトをあてても暗くなります。

ノーマルマップの値を反転させると治ります。

反転させる

Blenderなどで面を裏返してもうまくいきます。

レイヤーマスク

マスクのゲームオブジェクトに専用のレイヤーを設定します。

CameraコンポーネントのCulling Maskでマスクのレイヤーを除外します。

マテリアル

マスクに使うゲームオブジェクトのマテリアルでは、Surface Typeを「Transparent」にしました。Cull Modeは「Front」にします。面を裏返した場合は「Back」にします。

Depth Testも設定できます。

Opaqueだと穴を開けたいゲームオブジェクトのSSAOが表示されました。

SSAOをオフ

カスタムパス

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

このゲームオブジェクトに2つ目のCustom Pass Volumeコンポーネントを追加します。

それぞれのコンポーネントにDraw Renderers Custom Passを追加します。Injection PointとPriorityで実行順を制御できます。

ステンシルバッファに書き込む

ステンシルバッファに書き込むためのCustom Pass Volumeコンポーネントを設定します。こちらが先に実行されるようにします。

2つのDraw Renderers Custom Passを付けます。Layer Maskに専用のレイヤーを設定します。

Cameraカラーバッファにレンダリングすると除外したい部分が残るので、Target Color BufferはNoneに設定しています。

Camera
None

Override Modeを「Material」にして、マテリアルをアタッチしています。マテリアルでは「Cull Mode」を制御します。オモテ面をカリングして裏面だけ描画します。

カスタムパスのDepth Testを「Less」にしているので、遮蔽されていない裏面がレンダリングされます。

予め面を裏返した場合は、遮蔽されていないオモテ面を使います。

Override Stencilのチェックを入れています。Comparisonを「Always」、Passを「Replace」にして、常に「User Bit 0」をバッファに書き込みます。

次のDraw Renderers Custom Passも同様の設定にします。

マテリアルとDepth Testを設定して、遮蔽されているカメラ向きオモテ面だけを描画するようにします。

裏面を描画

もう一つのCustom Pass Volumeコンポーネントで裏面を描画します。Injection PointとPriorityを設定して後に実行されるようにします。

Target Color Bufferを「Camera」にしています。Depth Testを「Disabled」に設定して無効にしています。遮蔽されている部分も描画されます。

ステンシルバッファの内容とリファレンス値の「User Bit 0」を比較します。Comparisonが「Not Equal」なので、両者が等しくない場合にレンダリングされます。

これで、ステンシルを使って穴をあけられました。

参考:https://docs.unity3d.com/ja/2018.4/Manual/SL-Stencil.html

コメントを残す

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