起こったこと
Unity に MMD4Mecanim を用いてMMDモデルを取り込んだところ、普通にSceneの描画やRunはできるが、Buildは通らなくなってしまった。
エラーメッセージ
Shader error in 'MMD4Mecanim/MMDLit-NoShadowCasting-BothFaces': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on metal)
Shader error in 'MMD4Mecanim/MMDLit-NoShadowCasting-BothFaces': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on glcore)
Shader error in 'MMD4Mecanim/MMDLit-Transparent': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on metal)
Shader error in 'MMD4Mecanim/MMDLit-Transparent': syntax error: unexpected token ';' at Assets/MMD4Mecanim/Shaders/MMD4Mecanim-MMDLit-Surface-ForwardAdd.cginc(49) (on glcore)
Error building Player: 4 errors
環境
Mac OSX High Sierra バージョン 10.13.4
MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
Unity Version 2018.1.0f2 Personal
MMD4Mecanim 2018/03/04 版 (β)
解決方法
以下の4ファイルを変更する。
...
inline half3 frag_core(in v2f_surf IN, half4 albedo)
{
-- float atten = LIGHT_ATTENUATION(IN); // SHADOW_ATTENUATION() might be 1.0 (Can use LIGHT_ATTENUATION() only.)
++ UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz); // SHADOW_ATTENUATION() might be 1.0 (Can use LIGHT_ATTENUATION() only.)
#ifndef USING_DIRECTIONAL_LIGHT
half3 lightDir = normalize((half3)IN.lightDir);
...
...
struct v2f_surf {
float4 pos : SV_POSITION;
-- float2 pack0 : TEXCOORD0;
++ float4 pack0 : TEXCOORD0;
half3 normal : TEXCOORD1;
half3 vlight : TEXCOORD2;
...
inline half4 frag_core(in v2f_surf IN, half4 albedo)
{
-- float atten = LIGHT_ATTENUATION(IN);
++ UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz);
half shadowAtten = SHADOW_ATTENUATION(IN);
half3 c;
...
...
struct v2f_surf {
float4 pos : SV_POSITION;
++ float4 pack0 : TEXCOORD0;
LIGHTING_COORDS(0,1)
};
...
MMDLIT_CLIP(alpha)
-- half3 c = MMDLit_Lighting(albedo, LIGHT_ATTENUATION(IN), half3(0.0, 0.0, 0.0));
++ UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz);
++ half3 c = MMDLit_Lighting(albedo, atten, half3(0.0, 0.0, 0.0));
c = min(c, 1.0);
c *= alpha;
...
...
struct v2f_surf {
float4 pos : SV_POSITION;
++ float4 pack0 : TEXCOORD0;
LIGHTING_COORDS(0,1)
half3 vlight : TEXCOORD2;
...
MMDLIT_CLIP(alpha)
-- float atten = LIGHT_ATTENUATION(IN);
++ UNITY_LIGHT_ATTENUATION(atten, IN, IN.pack0.xyz);
half3 c;
...
これでビルドが通るようになった。
原因究明までの道のり
エラーメッセージでググるも、一切ヒットせず。
エラーメッセージから、LIGHT_ATTENUATION()
マクロが文末にセミコロンを持ってしまっているのではないかという予測を立て、MMD4Mecanim
プロジェクト内でLIGHT_ATTENUATION
を検索した。
ifdef
側でヒットしたのが以下。
...
#undef LIGHT_ATTENUATION
#ifdef POINT
#define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL)
#endif
#ifdef SPOT
#define LIGHT_ATTENUATION(a) ( (a._LightCoord.z > 0) * UnitySpotCookie(a._LightCoord) * UnitySpotAttenuate(a._LightCoord.xyz) )
#endif
#ifdef DIRECTIONAL
#define LIGHT_ATTENUATION(a) 1.0
#endif
#ifdef POINT_COOKIE
#define LIGHT_ATTENUATION(a) (tex2D(_LightTextureB0, dot(a._LightCoord,a._LightCoord).rr).UNITY_ATTEN_CHANNEL * texCUBE(_LightTexture0, a._LightCoord).w)
#endif
#ifdef DIRECTIONAL_COOKIE
#define LIGHT_ATTENUATION(a) (tex2D(_LightTexture0, a._LightCoord).w)
#endif
このファイルをいろいろ弄ったりしていたのだが、結局このファイルが読み込まれていない部分でもエラーが出ていたので、その時間は全部無駄になった。
検索してもあまりにも何もヒットしないので、Unityの最新版でのみ起こるバグではないかと考え、検索キーワードにUnity5
を追加、検索ツールで1年以内を指定。これが効いて、以下のサイトがヒットした。
マクロがdeprecatedになっていたのが原因だったことが判明。
UNITY_LIGHT_ATTENUATION
マクロの第3引数がよくわからなかったので、実用例を探す。(ドキュメントなどというものはどうやらないらしい。闇。)
このdiffがわかりやすかった。
どうやら、第3引数にはセマンティクスがTEXCOORD0
になっている変数を指定するらしい。
シェーダーセマンティクスについてはこれがわかりやすかった。
https://qiita.com/sune2/items/fa5d50d9ea9bd48761b2
また、型がfloat2
に指定されているものを、float4
に勝手に変更してもいいのか、なども調べた。(結論としては大丈夫っぽい。)
以上を踏まえてLIGHT_ATTENUATION
マクロを撲滅したのが先述したdiffになる。
感想
独自言語とマクロとドキュメントのないAPIは全員まとめていますぐ爆発四散してほしい。