ワールドによってQuestのアバターやパーティクル、ペンの色が黒くなるのを防ぐ
概要
VRChatのQuest(Mobile)対応アバター向けの記事です
Standard LiteのEmissionを利用して、明るさの下限を設定できるようにすることで、アバターの色がワールドのライトによって黒くなり過ぎるのを防ぎます
ワールドによってパーティクルやペン(Trail Renderer)の色が黒くなり過ぎてしまう問題もこの方法で解決できます
この方法をアバターに利用した例が以下の動画の一番右の状態になります。
環境
- Unity 2019.4.31f1 (64-bit)
- VRChat SDK - Base 3.4.2
- VRChat SDK - Avatars 3.4.2
明るさの下限の設定方法
Quest版VRChatのリリース当初からQuest対応してくださっている & なんといっても可愛い、mio3io様制作の薄荷ちゃん(Quest版)を例に取り解説していきます
- メッシュのマテリアルに割り当てられているShaderをStandard Liteに設定する
- 目的の「明るさ下限値」から「AlbedoのColor」と「EmissionのColor」のRGB値を設定する
明るさの下限値が0%だとEmissionを追加していない素のStandard Liteと同じ状態、
明るさの下限値が100%だとライティングによって全く暗くならないUnlitの状態になります
普段Standard Liteを使っている私的には、明るさの下限値は5~20%くらいが好きです
普段ToonLitを使っていて、Standard Lite特有の陰影をあまり出したくない方は50%などの高めの値を設定しても大丈夫です
明るさ下限値5%の場合の「AlbedoのColor」と「EmissionのColor」の設定例
コピー&ペースト用↓
明るさ下限値 [%] | AlbedoのColorのRGB値 | EmissionのColorのRGB値 |
---|---|---|
0 | 1.000 | 0.000 |
5 | 0.977 | 0.256 |
10 | 0.953 | 0.351 |
15 | 0.929 | 0.422 |
20 | 0.904 | 0.481 |
25 | 0.877 | 0.533 |
30 | 0.850 | 0.579 |
35 | 0.822 | 0.621 |
40 | 0.793 | 0.659 |
45 | 0.762 | 0.696 |
50 | 0.730 | 0.730 |
55 | 0.696 | 0.762 |
60 | 0.659 | 0.793 |
65 | 0.621 | 0.822 |
70 | 0.579 | 0.850 |
75 | 0.533 | 0.877 |
80 | 0.481 | 0.904 |
85 | 0.422 | 0.929 |
90 | 0.351 | 0.953 |
95 | 0.256 | 0.977 |
100 | 0.000 | 1.000 |
効果確認
Directional Lightを非アクティブにした状態で、
UnityのWindowタブ → Rendering → Lighting Settingsを開き、
Environmentタブ → Environment Lighting項 → Intensity Multiplierの値を0にすることで、アバターの色が真っ黒になる環境を再現できます
最終的にはQuestやAndroidスマホなどのMobile環境で、ライティングの調整ができるアバターテストワールドや、実際にアバターの色が真っ黒になるワールドに行って確認することをお勧めします
-
ライティングの調整ができるアバターテストワールド
Avatar Testing Chamber - By Ziggor
https://vrchat.com/home/world/wrld_a5e9ec13-36b1-4e63-ae0c-dab9023401f9 -
パーティクル、ペンの色が真っ黒もしくはかなり黒くなってしまうワールド
VRChat Home - By vrchat
https://vrchat.com/home/world/wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd
VRChat Homeでパーティクル、ペンの色が黒くなった際の参考動画・画像
明るさの下限を設定する仕組み
私自身Shaderのことをちゃんと理解してないので、
間違ったことを書いているかもしれないことをご了承ください
ものすごく大雑把に説明すると、
Emissionが有効にされたStandard Liteで最終的に表示される色(RGB)は、
「Albedoから計算されたRGB」と「Emissionで計算されたRGB」が足し合わされた色です
「Albedoから計算されたRGB」はワールドのライトによって色が変化し、
「Emissionで計算されたRGB」はワールドのライトによって色は変化しません
Standard Liteで最終的に表示される色の内訳
VRChat標準のShaderの中身は
Packages\com.vrchat.base\Runtime\VRCSDK\Sample Assets\Shaders\ 内で確認できます
この記事の主題としているアバターの色が黒くなってしまう原因は、
下図のように「ライティング計算によって決まるRGBの係数」が0になっているためだと考えられます
そこで本手法では、Standard LiteにEmissionを追加し、
「AlbedoのColor」と「EmissionのColor」を上手に調節することで、
ワールドのライトの明るさが最大の場合は、素のStandard Liteと同じ結果になるように、
ワールドのライトの明るさが最低の場合は、Emissionの色が残るようにしています
上図からわかる通り、明るさの下限の設定方法の章で出てきた「明るさ下限値 [%]」は、ワールドのライトの明るさが最大の場合に出力される色の中に「Emissionで計算されるRGB」が占める割合になります
ここからまたややこしい話になるのですが、明るさの下限の設定方法の章の表を見てもらうと、明るさの下限値が50%であっても、「AlbedoのColor」と「EmissionのColor」のRGB値は0.5ではなく、0.730という中途半端な数字になっています
これは、標準のUnityやVRChatでは、リニアワークフローというカラーマネジメントが採用されており、カラーパレットで指定した色は、Shaderで処理される前に「sRGB色空間」から「リニア色空間」に色空間の変換が行われることに起因しています
例えば、
「sRGB色空間」から「リニア色空間」に色空間の変換が行われたShader内で、色の値が0.5になるようにしたければ、カラーパレットには0.5を1/2.2乗した0.730という値を設定しておく必要があります
(※色空間変換に近似式を利用した場合)
色空間やUnityのカラーマネジメントについては以下の記事が大変参考になるので、気になる方は一度読まれることをお勧めします
以上のことを踏まえ、色空間変換に近似式を利用した場合の、
「明るさの下限値」から「AlbedoのColor」と「EmissionのColor」のRGB値を計算する計算式は以下のようになります
実際に、明るさ下限値が5%の場合の「AlbedoのColor」と「EmissionのColor」のRGB値を計算してみます。5[%]は0.05[-]です
Discussion