質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1847閲覧

URPを使用して2D画面でプレイヤーが物体の後ろにきたらシルエット表示にさせたい。

macarons

総合スコア33

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2022/10/22 00:21

実現したいこと

https://r-ngtm.hatenablog.com/entry/2020/12/16/133907
こちらのサイトを参考に、2Dでプレイヤーが物陰にかくれたらシルエットを表示させようとしています。
Y軸を基本に、物体の後ろにきたらプレイヤーの重なりが背面に、前にきたら全面にくるようにはできています。

現在のバージョンでは Universal RP ver12.1.6 では、ForwardRenderer が UniversalRendererになっています。

上記のサイトでは、
ForwardRenderer 
Filtering 
Opaque Layer Mask

の部分からPlayerを選択しているのですが、該当の場所がわかりません。

私の環境の中にあるのは、
Renderer 2D Data
Universal Render  Pipeline Asset 

で、下記の設定になります。

イメージ説明
イメージ説明

試しにCrateから追加してみた3D用の URP Asetts(New Universal Render Pipeline Asset_Renderer)というものを見てみたら、そちらには Filtering という項目がありました。

そもそも2Dだと使用することが出来ないのでしょうか?
この方法にこだわらず他の方法などがあれば教えて頂けると助かります。

他には、シェダーによる方法をこちらのサイトを参考にためしたのですが、通常の場合はできたのですがURPではできませんでした。
https://takap-tech.com/entry/2022/02/12/194032

補足情報(FW/ツールのバージョンなど)

Unity 2021.3.0f1
Universal RP ver12.1.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

【Unity 2020.2】物陰に隠れた部分を描画する - rn.log」はデプスを頼りにシルエットを描画する方式のようですね。このやり方ですとおそらく2Dゲームには不向きでしょうから、「【Unity】2Dゲームでプレイヤーがオブジェクトに回り込んだ時にシルエットを表示する - PG日誌」の方針で行った方がいいんじゃないかと思います。

ステンシル機能を使った方法を検討してみました。まずPackages/Universal RP/Shaders/2D/Sprite-Lit-Default.shaderを複製して別名(とりあえずSprite-Lit-Default-Stencil.shaderとしました)を付け、内容を下記のように変更しました。

ShaderLab

1// シェーダー名を変更して区別が付くようにする 2Shader "Universal Render Pipeline/2D/Sprite-Lit-Default (Stencil)" 3{ 4 Properties 5 { 6 _MainTex("Diffuse", 2D) = "white" {} 7 _MaskTex("Mask", 2D) = "white" {} 8 _NormalMap("Normal Map", 2D) = "bump" {} 9 10 // Legacy properties. They're here so that materials using this shader can gracefully fallback to the legacy sprite shader. 11 [HideInInspector] _Color("Tint", Color) = (1,1,1,1) 12 [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1) 13 [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1) 14 [HideInInspector] _AlphaTex("External Alpha", 2D) = "white" {} 15 [HideInInspector] _EnableExternalAlpha("Enable External Alpha", Float) = 0 16 17 // ステンシル用プロパティを追加する 18 _StencilComp ("Stencil Comparison", Float) = 8 19 _Stencil ("Stencil ID", Float) = 0 20 _StencilOp ("Stencil Operation", Float) = 0 21 _StencilWriteMask ("Stencil Write Mask", Float) = 255 22 _StencilReadMask ("Stencil Read Mask", Float) = 255 23 } 24 25 SubShader 26 { 27 Tags {"Queue" = "Transparent" "RenderType" = "Transparent" "RenderPipeline" = "UniversalPipeline" } 28 29 Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha 30 Cull Off 31 ZWrite Off 32 33 // Stencilブロックを追加する 34 Stencil 35 { 36 Ref [_Stencil] 37 Comp [_StencilComp] 38 Pass [_StencilOp] 39 ReadMask [_StencilReadMask] 40 WriteMask [_StencilWriteMask] 41 } 42 43 // 中略...主要部分は変更なし 44 } 45 46 Fallback "Sprites/Default" 47}

そして、これを使ったマテリアルを3種類作成しました。
キャラクター用は

  • Stencil Comparison: 8(常にステンシルテスト通過)
  • Stencil ID: 2
  • Stencil Operation: 2(Stencil IDをステンシルバッファに書き込む)
  • Stencil Write Mask: 3(ステンシルバッファの下2桁にのみ書き込む)
  • Stencil Read Mask: 255(ステンシルバッファのすべての桁から読み込む...読み込みは行わないのでこの設定は重要ではありません)

図1

として、遮蔽物用は

  • Stencil Comparison: 8(常にステンシルテスト通過)
  • Stencil ID: 1
  • Stencil Operation: 2(Stencil IDをステンシルバッファに書き込む)
  • Stencil Write Mask: 1(ステンシルバッファの下1桁にのみ書き込む)
  • Stencil Read Mask: 255(ステンシルバッファのすべての桁から読み込む...読み込みは行わないのでこの設定は重要ではありません)

図2

として、シルエット用は

  • Stencil Comparison: 3(Stencil IDとステンシルバッファ上の値が一致したらステンシルテスト通過)
  • Stencil ID: 3
  • Stencil Operation: 0(ステンシルバッファへの書き込みは行わない)
  • Stencil Write Mask: 255(ステンシルバッファのすべて桁に書き込む...書き込みは行わないのでこの設定は重要ではありません)
  • Stencil Read Mask: 3(ステンシルバッファの下2桁のみから読み込む)

図3

としました。

キャラクターにはキャラクター用の、遮蔽物には遮蔽物用のマテリアルをセットし、さらにカメラの子オブジェクトとして画面全体を覆うサイズの四角いスプライトを配置し、シルエット用のマテリアルをセットしました。
このシルエット用オブジェクトはSorting LayerやOrder in Layerを調整して、キャラクターや遮蔽物よりも手前に描画されるようにしておきます。

図4

このようにシーンを構成したところ、下図のようにシルエットが描画されました。キャラクターがステンシルバッファに2を書き込み、もしその上に遮蔽物が描画されるとステンシル値の下1桁が1になることでステンシル値は3となり、最後にステンシル値が3のところにシルエットを塗ればいいだろうと思ったわけです。
ちなみに、遮蔽物の描画後にさらにキャラクターが描画された場合はステンシル値が2に戻りますので、そこにはシルエットは描画されなくなります。

図5

投稿2022/10/23 00:54

編集2022/10/23 01:19
Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

macarons

2022/10/24 04:01

とても分かりやすい画像付きでの詳細の解説本当にありがとうございます。 ご説明頂いた通りに、無事できました。 通常のシェダーでできていたもは、そもそもURP用のシェダーをもとにしなければいけなかったのですね。 その書き方も、理解できていなかったので詳細にご説明頂いて本当に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問