Unityで、PhotoScanのスタジオで撮影して作られた人体モデルに対して、ライティングが必要な案件がありました。その時起きた問題と対処したことを書きます。
問題
フォトスキャンのスタジオで作られたモデルは、シェーダーをUnlitにしたときが一番いい感じになって実写のようにも見えるくらいなんですが、これではライトの影響を受けられません。
なので、standardシェーダーを使って、ライティングを試みたのですが、なんか不自然になっちゃって調整が難しかったです。
対処
そこでstandardのシェーダーを少し改造し、emissionを使って、standardとunlitの中間の値を探れるようにしてみました。 まあ陰影のコントラストを下げてるってだけですが、今回の案件ではこの調整で十分でした。
左:調整前(Albedo100%) 右:調整後(Albedo50%,Emission50%)
Shader "Custom/UnlitStandardMix" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_BumpMap ("Normal", 2D) = "white" {}
_BumpScale ("_BumpScale", Range(0,1)) = 0.0
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_Amount ("_Amount", Range(0,5)) = 0.0
_Emission ("_Emission", Range(0,1)) = 0.5
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard addshadow
#pragma target 3.0
sampler2D _MainTex;
sampler2D _BumpMap;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
float _Amount;
float _Emission;
float _BumpScale;
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
o.Albedo = c.rgb * (1-_Emission);
o.Emission = c.rgb * _Emission;
fixed4 n = tex2D(_BumpMap, IN.uv_MainTex);
o.Normal = UnpackScaleNormal(n, _BumpScale);
}
ENDCG
}
FallBack "Diffuse"
}
以上です!