画像のようにワールドによって顔と体の明るさが変わってしまう問題について解説
原因は頭と体のSkinned Mesh RendererコンポーネントのAnckorOverridesの値がNoneもしくは異なるためです。適当にHumanoidボーンのHead,Chest,Spineあたりで統一すれば解決します。
技術的な解説
ここからは技術的な解説
Anchor Overrideとは?
メッシュの明るさは各面のライトマップが決めますが、その全体はライトプローブが決めます。全体の明るさってのは一体どこで決めるんだ?って話ですが、それはUnity公式リファレンスによるとバウンディングボックス(下記画像の白いCube)の中心点となります。この中心点に強いライトが当てられるとメッシュ全体は明るくなり、ライトが何も当たっていないとメッシュ全体は暗くなります。
そのため、2つのメッシュをつなぎ目のように隣接させたアバターを作成し、2つのライトの取得座標がまったく違う光の情報を取得してしまうと、つなぎ目で明るさが異なることが顕著になるため「あれ?このアバター頭と体で明るさが異なるんだけど」ということになります。
そこで、 ライトの取得座標を統一するためにAnchor Overrideという設定値が存在します。
というわけで、アバターの頭か体でライトの影響を計算すればいい感じになるので、 Anchor Override の値はHumanoidボーンのHead,Chest,Spineあたりに設定するのがベストということになります。
ライトプローブとは
ところでライトプローブってなんだ?って話ですが、あらかじめ光の情報をワールドに焼き付けて(Bake)おく技術の1つです。↓こんな感じでライトプローブの区域にライトの取得座標が侵入するとオブジェクトが光の影響を受けます。
ちなみに、ライトプローブの作り方はLightのModeをBakedに変更して、LightProbeGroupというコンポーネントを追加すれば作成できます。Lightingタブでベイクをするのを忘れずに
Anchor Overrideの値がNoneの場合はアバターの足元でライト情報を取得するのでは?
ライト情報の取得位置ですが、さきほどUnity公式リファレンスによるとバウンディングボックスの中心点で取得すると説明しましたが、どうやらフレンドやtwitterの情報によるとオブジェクトのアンカー位置らしく大抵は足元(x=0,y=0,z=0)で取得するらしい・・
どっちが正しいのか検証してみた。
アンカー位置をかなりズラしたCubeをBlenderで作成して、事前に作った2つのライトプローブに設置。
うん、バウンディングボックスの中心点が正しいね
参考文献
Unity Documentation – ライトプローブとメッシュレンダラー
Unity Documentation – Skinned Mesh Renderer
Unity Documentation – リフレクションプローブ