見出し画像

Unityで半透明化のためにRender Queue(レンダーキュー)やZWriteと戦ってみた

ここに書いてある内容は下記のサイトやドキュメントを参照しつつ、自分で色々いじり、調査した結果をまとめたものになります。
内容の確実であるという保証は出来ません、その点ご理解ください。

まえがき

暑い。こういう時はグラスに冷たいものを注いで飲んだり、透明なガラス系のアイテムがすごく恋しくなるシーズンですね。
ということで、ガラス系のアイテムを作ってみようと思いました。

シンプルに球体の中に三角錐を入れてみました。

メッシュが多いとなんたらかんたらという話もあるので、とりあえずマテリアルはバラバラに、メッシュは結合して1つにしちゃおう。

球体と三角錐が同じマテリアルになっちゃうと両方透けちゃうからね

Blenderでとりあえず作りましたし、じゃあUnityに持っていきましょう。
ほい。

見事に球面だけ。これでは中身が見えませんね?

さて、ここまでが前書きです。
ここから透過やアレコレとの戦いを始めてまいりましょう。

戦闘開始

マテリアル設定

プロジェクトビュー(ファイルが表示される部分)で右クリックすればこういう感じでメニューが出てきます。

「Create」→「Material」ですね。
とりあえずこれでマテリアルを作りましょう。

そうしたら作ったマテリアルを割り当ててあげましょう。

「Mesh Renderer」や「Skinned Mesh Renderer」に
「Material」という項目があるのでそこにドラッグアンドドロップで割当て。
もし複数個ある場合はモデリング時の設定に沿って割り当てましょう。

特に何も…変わりませんね…?
※マテリアルは初期ではStandardシェーダーなので…

立派な球体だなあ。

しょうがない(?)のでliltoon辺りでも割り当ててみましょう。

見え方は変わり申した…が透過されないね…

透明になってよ

そうだ、liltoonなら半透明って設定がありましたね。
半透明にしたうえで更にメインカラーのアルファ値(透明度)を調整すれば…ヨシッ!???!!

???????
透過はされたのに中身が無いんだが??????

Render Queue(レンダーキュー)やZWriteをちょっと学んでみよう

Render Queueについて

Render Queue(以下はレンダーキューとカタカナ表記にします)というのは描画する順番となります。
これは1から順番にどんどん描画されていく、という感じになります。

例えば以下の画像のように、各色が自分の番号(レンダーキュー)を主張しています。

アイデンティティです。

そのうえでこのように横と前後にずれて並んだ場合…

なんと、Unity上では赤を食い気味に青が混ざり、このように表示されます。

※設定によります。後述するZWriteが入ってない(設定を切った)シェーダー設定でのみ発生するので普通はそうそう発生しません

更に緑の位置関係を変えて前から見ると…

なんと、赤が見えなくなりました。
完全に隠れてしまっています。

さようなら、赤

このような現象が起きる理由がレンダーキュー(描画順番)となります。

最初に赤は「1番目に描画してほしい」と言いました。
そのため、「じゃあ、位置関係ガン無視で描画するね(ZWriteオフにするね)」となった場合には
例え赤の後ろに緑や青が居ても「後から描画される色を優先」で上書きされてしまう(=赤が2番目・3番目の色で上書きされて見えなくなる)のです。

ZWriteについて

ZWriteは基本的には「深度情報」というものです。
こちらはシンプルに「カメラ(我々の視点)から見た各オブジェクトの距離」になります。

例えば前述のレンダーキューのこの配置の状態からZWriteをオンにすると…

この通り、想像したようにちゃんと並び順で描画されてますね…!!

ZWriteが敢えてオフになっているシェーダーはあんまりないと思うので
「なんか位置関係と見え方にズレがある…??」という時には
各マテリアルのレンダーキューを優先して見ると良いと思います。

学んだところで見直そう

現状

現状では位置関係としては
球体 → の中に三角錐 となっております。

本来ならこの中で透過された三角錐がちゃんと表示されるはずなのに…

ということで、レンダーキューを確認してみましょう…

球体くん
三角錐くん レンダーキューが透過物より大きいとかお前なんなんだよ

これにより、『透過したい部分(ガラス)』より『内部のオブジェクト』のレンダーキューが大きくなっているということが分かりました。

つまり、
位置関係(ZWrite):ガラス>三角錐 の順番(三角錐のほうがガラスより遠い)
レンダーキュー:ガラス<三角錐 が大きい
という矛盾(?)が原因で内部の三角錐がちゃんと表示されない事態が発生しているようです。

直そう

じゃあ三角錐のレンダーキューを直して(ガラスより小さくして)みましょう。

これでガラスより小さいレンダーキューの値になりました。
知識の賜だな。

やりました!無事に球体の中に三角錐が表示されました!!!

この見え方が欲しかった。

ちなみに、三角錐のレンダーキューが大きい状態でZWriteをオフにすると…

三角錐が球体の後に描画されるので変な見え方になった。
こういう見せ方もありかもしれないが…今回はちょっとNGで…

番外編

水面越しだと消えちゃうよ!?問題の実践

liltoonで半透明モードにするとこういう警告が出てきます。
※他のシェーダーでも警告が出てこないだけで、同じ事象は発生します

ということで、レンダーキューが球体(2460)と同じ半透明なマテリアルを適用させた板を用意してみました。
さあ、これで板越しにこの作品を見るとどうなるのでしょう。

ドキドキ

こちらが結果のGifアニメになります。

Oh…ガラス部分が消えてしまいました…

半透明に半透明を組み合わせるシチュエーション…例えば、『ガラス越しにアバターを見る』『水の中にいる3Dモデルを陸から水面越しに撮影する』『半透明なパーティクル(バリア)越しにアバターを見る』
という状況ではこのような状態になりがちですので、もし半透明系の衣装を使用する際はこのような事象には気をつけましょう。

…と言っても「ワールド(や他人)の透過オブジェのレンダーキューを把握して対応する」のは無理ゲーなので、「ワールド作者の配慮」or「事象を発見したらレンダーキューの値を変更してアバターをアップロードし直しておく」くらいしか対策は取れないのですが…

「ちなみにレンダーキューを変に高い値にすると
それはそれで別の問題が発生するから
アバター側なら+10とか-1ずつとか小さめに調整しておくといいよ」
「極端な値にするとワールド側の演出を妨害する可能性もあるので、
ある程度(+10とか-1ずつくらい)の値にしておくといいと思うの」

あとがき

レンダーキューやら透過やら…Unityのシェーダーの設定値などを調べたりすると結果的にグラフィック系のアレコレを学ぶことが多いですね…
もし「透過したうえで~」といった衣装を作る上で少しでも参考になれば幸いです。

Noteを書くきっかけになった人

✚A/D✚ さま
https://twitter.com/AiDcollection 

ありがとうございました!!