HDRP:オブジェクトを他よりも手前に表示する
Show object always on top in HDRP
※このページの内容は古いため今のバージョンのUnityでは動かない可能性があります
背後にあるオブジェクトを
前面に表示
例えば「目的地を示す矢印オブジェクト」だけは他のオブジェクトより手前に表示させたい、みたいな用途につかうやつです。
でもuGUIでスプライトを表示するとかの話ではなく、その矢印も3Dオブジェクトな場合の話。
思いつくところでは次のような手段があるかと思います。
シェーダーを書く
カメラを分けてレイヤー別にレンダリング
カメラを分けてレンダリング結果をテクスチャに書き出して最後に合成
今回は2(複数カメラ)でいこうと思ったのですが、HDRPではできなかったので、カスタムパスなるものを使いました。
メインカメラとは別に前面表示用のカメラを使う手法(ダメだった)
UnityのレンダーパイプラインがLWRPとHDRPに分かれる前は、特定のオブジェクトをほかのオブジェクトより常に前面に表示させたい場合のよくある手法としては「メインカメラとは別にもう一つカメラを作り、前面表示用のレイヤーだけ2つ目のカメラでレンダリングする」というやり方でした。FPSカメラとか呼ばれたりするやつですね(FPSで銃だけは壁にめり込んだりしないよう常に手前に表示させる)。
これをHDRPになった今やってみたら、一応前面に表示することはできたものの次のような症状が。
FPSが落ちる(=重い)
ライトに反応せず真っ黒
ライトを作り直したら反応するけど今度は白飛びしてる
とか、(①はともかく)なんかよくわからない症状が。
③はLux値を100000から1に変更すると白飛びしなくなるのですが、そもそも正しい値は100000の方なので本末転倒です。それで色々調べてみると、HDRPではカメラスタッキング(複数のカメラを重ねてレンダリング)をサポートしない、みたいな感じらしいです。
ただでさえ高コストな処理を行うHDRPでさらに複数のカメラがあると、カメラごとに初期化処理とかポストエフェクトとか処理しなくてはならなくてパフォーマンスが落ちるとかあると思うので(上でFPSが落ちてたのも多分そのせい)合理的ですね。
LWRPの後継のURPではカメラスタッキングがサポートされたorされるらしいんですが、とりあえずこの人はHDRPで前面表示がしたいです。
先に挙げた「シェーダーを書く」とかはShaderGraphがある今ではたぶん簡単そうですが、なんか「前面に表示する」ためだけにわざわざシェーダーを作るというのも面倒だし(それはそれでシェーダー間の仕様差で見た目が変わったりとか色々面倒くさそう)、あとはカメラスタッキング時代のように、レイヤーを変えるだけで簡単に「前面に表示」のON/OFFを切り替えたい。
そしたらその条件を満たす簡単な方法がありました。
カスタムパスを作る手法(うまくいった)
前面表示用のレイヤーを作っておきます(今回はForefrontという名前にしました)
GameObject > Volume > Custom Passを作成。これでCustom Pass Volumeコンポーネントを持つゲームオブジェクトができました
Custom Pass Volumeを以下の通りに設定
Injection Point = Before Post Process
Custom PassesにDrawRenderersCustomPassを追加し次の2か所を変える
Clear Flags = Depth
Filters > Layer Mask = "Forefront"
あとは前面に表示したいゲームオブジェクトのLayerを上の手順1で作ったレイヤー(ここでは"Forefront")に変更するだけです。
これだけで、Forefrontレイヤーのオブジェクトは前面に表示されるようになりました。
(ただ、上のようにQueueがAll Opaqueになっていると、半透明なマテリアルのオブジェクトは表示されなくなるようです(前面に表示されるどころか、どこにも表示されなくなってしまう)。その際はQueueをAllにしたらとりあえず解決しました(適合した設定なら別のやつでもたぶんいける))カメラの方も何も変える必要ないし、シェーダーもマテリアルも変える必要がない。オブジェクト側でしなければならないのはLayerをForefrontに設定するだけです。
まさにこんなのを探していたので良かったです。
でもビルド後も動くかどうかは試してないです。試してダメだったらこのページは消すかも