カスタムシェーダーのコードを含んでいる場合は、Unity 4 から Unity 5 へ移行するときに注意しなければいけない点があります。
シェーダーは光の強度で2x の乗算を行いません。代わりにライトは自動で2倍明るくなるようにアップグレードされています。この作成方法はライトの操作に対して整合性とシンプルさをもたらします。例えば、白色の拡散面のディレクショナルライトの光はライトの色を正確に取得します。このアップグレードはライトの光の強度の値をアニメーションさせているものには影響しないのでアニメーションカーブ、スクリプトコードを約2倍に手動で変更する必要があります。
ライト機能を自身で定義するカスタムシェーダーを使用している場合は、*2 をしている部分を削除する必要があります。
//この問題を持つシェーダーコードの一般的なパターンはこのようになっています
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
// コード修正して以下のようにします
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten);
Unity 5 ビルトインのライティングパイプラインはより多くのテクスチャ座標インタポレーター、または(ノンユニフォームメッシュスケール、GI などを動作させるための)数学命令カウンタを使用します。現存しているサーフェイスシェーダーのいくらかは、特に(デフォルトの)シェーダーモデル 2.0 をターゲットとしている場合はテクスチャ座標か、ALU 命令リミットの問題と衝突するかもしれません。この問題については “#pragma target 3.0” と書き加えることで動作する可能性があります。リファレンスの http://docs.unity.cn/Manual/SL-ShaderPrograms.htmlを参照してください。
Unity 5.0 では、ノンユニフォームメッシュは CPU で “事前スケールされません”。これは法線ベクトルと垂直ベクトルが頂点シェーダーで正規化されない可能性があるという意味です。そこで手動のライティング計算を行っている場合、それらを正規化しなければならないかもしれません。Unity のサーフェイスシェーダーを使用している場合、すべての必要なコードは生成されます。
Unity 5.0 ではビルトインのフォグが Windows Phone とコンソール上で動作しますが、そうさせるためにフォグがどのように実行されるかを少し変更しました。サーフェイスシェーダーと固定関数シェーダーで、実行するために特別必要なものはありません – フォグは自動的に追加されます(フォグを明確にサポートさせないためにサーフェイスシェーダーの #pragma ラインに “nofog” と追加することができます)。
手動で頂点/フラグメントシェーダーを書くために、フォグは自動的に起こらなくなりました。#pragma multi_compile_fog 、フォグ操作マクロをシェーダーコードに追加する必要があります。例えば、Unlit-Normal ではどのように行っているか、ビルトインシェーダーのソースをチェックしてください。
デフォルトでは、すべての不透明なサーフェイスシェーダーはアルファチャンネルに 1.0 (“白”) を出力するようになりました。これを止めたい場合、“keepalpha” オプションを #pragma surface ラインで使用してください。
すべてのアルファブレンドされているサーフェイスシェーダーは (s.Alpha の代わりに)ブレンドファクターとしてライティング関数によって計算されたアルファ成分を使用します。カスタムライティング関数を使用している場合、おそらく “c.a = s.Alpha” などをその最後付近に追加したいと思うでしょう。
Unity は Forward 描画ループにおいてマテリアルインデックスによるソートを行わなくなりました。それらのステート変更無しでより多くのオブジェクトが描画できるのでパフォーマンスが改善されました。これによって、ソート方法としてマテリアルインデックスに依存するコンテンツの互換性が失われました。Unity 4.x ではマテリアルが2つあるメッシュは常に一つ目のマテリアルが最初に、2つ目のマテリアルが2番目に描画されていました。Unity 5 ではこの限りでは無く、順序はシーン描画のためのステート変更がもっとも少ないことによります。
Unity 5.0 は以下の固定関数シェーダー機能のサポートを撤廃しました。
上記のいずれも現在は動作せず、シェーダーのインスペクターはそれらの使用方法について警告を表示します。プログラマブル頂点 / フラグメントシェーダーを代わりに用いて、影響を受けるシェーダーを書き直すべきです。最近では、すべてのプラットフォームがそれらのサポートをしており、どんな場合においても固定関数シェーダーを使用する利点は少しもありません。
あなたのプロジェクトで Projector か、Water シェーダーパッケージを合理的に使用したい場合、それらのシェーダーでこの機能を使用するとよいかもしれません。パッケージを 5.0 バージョンにアップグレードしてください。
部分的な固定関数シェーダーとプログラマブルシェーダー(例えば、固定関数頂点ライティングとピクセルシェーダー、または頂点シェーダーとテクスチャコンバイナー)の併用はすでにサポートされていません。併用はモバイルやコンソール、 DirectX 11 など、どのプラットフォームでも一度も動作していませんでした。この結果を受けて、Legacy/Reflective/VertexLit シェーダーが頂点ごとのスペキュラサポートを失うことがないように挙動を変える必要がありました。一方、よい側面としてはそれらがプラットフォーム間で一定の動作をするようになったことがあげられます。
この変更は分かるようなものではないかもしれません(コードから生じるバグが少なくなり、わずかにシェーダーが速くなったくらいのものです)。しかし、HLSL コンパイラーは文法に少しだけ難があるかもしれません。いくつか例を見ていきましょう。
“unity_Scale” シェーダープロパティーは削除されました。4.x の unity_Scale.w はトランスフォームの 1 / uniform Scale であり、Unity 4.x はノンスケールか、均一にスケーリングされたモデルのみを描画していました。他のスケールは CPU 上で実行されていましたが、それらはとても負荷が高く、メモリのオーバーヘッドの懸念もありました。
Unity 5.0 では、シェーダーにノンユニフォームスケールのあるマトリクスをシンプルに受け渡すことにより、これらはすべて GPU 上で実行されます。それゆえに、unity_Scale はスケールすべてを表現できないために削除されました。“unity_Scale” が使用されるほとんどの場合では、まず代わりにワールドスペースに変換することをお勧めします。法線を変換する場合、常に変換された法線で正規化を使用しなければいけません。頂点シェーダーにおいて、この方法を用いるとわずかながら負荷増加の原因に繋がることもあります。
// Unity 4.x
float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal * unity_Scale.w);
// Unity 5.0 ではこのようになりました
float3 norm = normalize(mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal));
// Unity 4.x
temp.xyzw = v.vertex.xzxz * unity_Scale.xzxz * _WaveScale4 + _WaveOffset;
// Unity 5.0 ではこのようになりました
float4 wpos = mul (_Object2World, v.vertex);
temp.xyzw = wpos.xzxz * _WaveScale4 + _WaveOffset;
前面に描画されたディレクショナルライトのシャドウは “shadow collector” パスと分けて考えられなくなりました。それらはカメラデプステクスチャを用いて(deferrred ライティングのように)スクリーンスペースのシャドウを計算します。
これはシェーダーの LightMode、すなわち ShadowCollector パスが何にも使用されていないという意味です。シェーダーからそれらを単純に削除できます。
デプステクスチャ自身はすでにシェーダー置換を使用して生成されません。代わりに ShadowCaster シェーダーパスを伴って描画されます。これはオブジェクトが適切なシャドウをキャストできるのと同じくらい長いという意味で、カメラのデプステクスチャにも適切に表示されるようになります(これはカスタム頂点アニメーションや、ファンキーなアルファテストを行いたい場合、以前まではとても難しいことでした)。また、Camera-DepthTexture.shader が何にも使用されなくなったという意味でもあります。さらに、すべてのビルトインシャドウシェーダーはバックフェイスカリングを使用していませんでした。これは、通常のレンダリングのカリングモードに変更されました。