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

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

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

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

Q&A

解決済

1回答

5978閲覧

Unityでspritemaskがシェーダーによっては機能しない

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2021/05/27 11:12

編集2021/05/28 13:48

やりたいこと

spritemaskの機能を使いたいのですが、マスクしたいSprite Rendererによっては機能しないことがあります。
spritemaskのドキュメントについてはこちらです
https://docs.unity3d.com/ja/current/Manual/class-SpriteMask.html

やったこと

イメージ説明
↑の画像をごらんください。
画像の左上、濃い青のボタンの画像をSprite Rendererを使用して画面に表示し、星型のマスクを設定しました。その結果、上2つのケースでは正常に星の形にマスクされており、下3つのケースではマスクされていません。
それぞれのケースでは「Sprite RendererのSpriteの画像は同じ」、「Sprite Maskの設定しているSpriteやそれ以外の項目は同じ」、「Sprite RendererのMaterialのみ異なる」といった状態です。

変更したマテリアルは右上のものはSprite Renderer作成時にデフォルトで設定されているSprites-defaultマテリアルで、それ以外の4つはアセットに含まれているものや自作したものなど、適当に選んだマテリアルを設定しています(なので、ボタンの表示がおかしいものになっているものもありますが、それは一旦置いておきます)

それ以外に影響しそうな項目、スプライト自体のMask InteractionやSprite Rendererのlayerの設定などは変更しておらず、マスクしたい画像のマテリアルに何が設定されているかによってマスクされるか否かが決まっているように見えます。
しかし、上記ドキュメントにこのような、シェーダーの設定によってはマスクできないから気を付けてね!という記述もなく、検索しても情報が見つからないため、シェーダーが原因なのか、日ごろの行いが悪いからか、それ以外の原因なのかわからず、Sprite Maskにも同じMaterialを設定すればいいのでは?と思ったりもしますが、Sprite MaskにはMaterialを設定することすらできず、解決することができません。

この問題の解決方法、あるいはspritemaskはこう使うのが常識だろ!など情報をお持ちの方は教えていただけないでしょうか_(┐「ε:)_

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

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

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

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

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

guest

回答1

0

ベストアンサー

私もマニュアル内を探してみたものの、おっしゃるようにマスクを効かせるためのマテリアルに関する注意点だとかは見つからないですね...

ちょっと試してみたところ、どうやらSprite Renderer側に使っているマテリアルのRender Queueの影響を受けそうでした。
半透明対応のマテリアルは、一般的にはキューが3000に設定されているかと思います。Frame Debuggerで描画過程を見てみたところ、この場合は下図のようになりました。

図1

描画過程の中の「Draw Dynamic」がSprite Rendererによるリンゴの絵の描画で、それを上下に挟んでいる「Draw Mesh」がSprite Maskによるかじり痕の形のマスクの描画です。マスクにはステンシル機能が利用されており、まずSprite Maskによってマスクの形にステンシルバッファの値が設定され、Sprite Rendererはステンシル値に応じて切り抜かれた形で描画を行い、最後にSprite Maskが書き換えたステンシル値を元に戻すようです。

キューを2501まで下げても、描画過程に変化は見られませんでした。

図2

キューを2500まで下げると描画過程が変化し、「Draw Dynamic」が半透明オブジェクト用の「Render.TransparentGeometry」から不透明オブジェクト用の「Render.OpaqueGeometry」に引っ越されてしまいました。2つの「Draw Mesh」に挟まれた位置で描画しないとステンシル抜きが正常に効かないはずですので、かじり痕がなくなってしまいました。

図3

ご質問者さんの場合、マスクが正しくかかったマテリアルと失敗したマテリアルのRender Queueはどのようになっているでしょうか?
もし前述のように「失敗したマテリアルはRender Queueが2500以下になっている」といった共通点がありましたら、Render Queueを2501以上に上げればマスクがかかるようになるかもしれません。

ですが、マテリアルによっては何か描画上の理由があって不透明キューでレンダリングするよう設定している可能性も考えられます。もしかすると別の描画不具合が起こってしまうかもしれませんので要注意でしょうね。

投稿2021/05/27 19:39

Bongo

総合スコア10807

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

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

退会済みユーザー

退会済みユーザー

2021/05/28 15:25

確認したところ、成功したマテリアル2種は「Render Queueが3000」で、失敗した3種は「Render Queueが2000」でした。 また、確かに「Render Queueが2500」を超えるとマスクが機能するようになりました。 ですので、Render Queueを弄ることで当面は解決できそうですが、そもそもこれが正しい処理なのか不明なで、unity本体のバージョンアップなどで処理が変わったら無意味になったりしないか不安ですね_(┐「ε:)_ 公式に問い合わせたいところですが、公式への連絡手段が封じられているため、それも叶いません。 不安が残る所ですが対処方法が分かったため解決とさせていただきます。ご丁寧にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問