見出し画像

水中に入るとアバターが消える原因と対応について

概要

VRChatで水中に入ったアバターの姿が消える現象が起きることが有る。
これは水とアバターで使用しているシェーダーの相互作用により発生する。
ここでは原理と対応方法について記する。

結論

先に結論を記す。
アバターに使用しているRender Queueの値を2000にする。

水中でアバターが透ける原理※かずやまの独自考察

Unityの描画で使用するシェーダーにはRender Queue(レンダーキュー)というパラメータがある。
Render Queue では描画する順番を指定します。順番は1を先頭として数が増えるほど後に描画される。

もう一つzwrite(深度情報)というものが有り。視点からの距離を表す。
水中のアバターという状況なので、水面が近い(浅い)アバターが遠い(深い)という関係になる。

これらの条件が組み合わさり水中でアバターが透けるという現象が発生する。

先ず深度情報の影響ですが、通常物体が近いものと遠いものがある場合は遠いものは近いものにさえぎられて描画されない。物体が不透明であればこの判断で問題はない。
しかし、水は透明なので自分より遠い場所の物も見えるようにしなければいけない。
ここで描画順序が関係してくる。
描画順序がアバターの後に水であればアバターを描画した結果を使用して水の中にある表現が作れる。
逆に描画順序が水の後にアバターの場合、水の中の表現にアバターの描画結果を使用できないため、結果として水中のアバターが消える。

対応方法について

描画順序でアバターを水の前に描画すればよいので、Render Queueの値をアバター<水にする。
Render Queue の説明には下記のような記載があり、アバターのRender QueueをGeometry(2000)にすれば消失現象は解決する。

Background 1000 最初の描画用。一般的には背景。
Geometry 2000 ほとんどの不透明なものの描画用。(今回の例ではアバター)
AlphaTest 2450 アルファテストを伴う描画用。
Transparent 3000 透明な水やガラス、パーティクルなどの描画用。
Overlay 4000 レンズフレアなどオーバーレイ効果の描画用。

なお、2500までは不透明で2501以上は透明(水等)とみなされる。

上記の詳細については https://docs.unity3d.com/ja/2019.4/Manual/SL-SubShaderTags.html を参照すること。

現象の実例

水については他人のワールドの物なので、Render Queue=3000と仮定

アバターのRender Queue=3000の場合(水中で消える)
アバターのRender Queue=2000の場合(水中で消えない)

補足

宝石のような透明なアクセサリーなどを通すと服が消える原因等にもなっているらしい。

いいなと思ったら応援しよう!