5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UnityのShaderとAssetBundleの謎な関係

Posted at

ShaderはAssetBundleに含まれるのか?本当のところどうなの?

例えばModelとMaterioalをAssetBundle化して配信したとします。
その時AssetBundleに含まれるのはShaderへの参照のみなのか、それとも?

実際に検証してみた

※検証環境はUnity5.5系です
※アプリは検証対象のShaderをストリッピングしないようにしています。

検証1

  1. 既存のアプリにはない新規Shaderを適用したAssetBundleを配信してみる
  • この状態では正しくレンダリングされない
  1. 新規Shaderを含んだアプリで同じAssetBundleを読み込んでみる
  • 想定した通りのレンダリング結果となる

AssetBundleに含まれるのは参照のようなもので、あくまでアプリ側にShaderが含まれている必要があるように思える。

検証2

  1. 既存のShaderの処理本体(CGPROGRAM〜ENDCG)を書き換えたアプリで、以前作ったAssetBundleを読み込んでみる
  • 書き換えた通りにレンダリング結果がかわる
  • また、この時新しいPropertyを追加していたとしても、そのPropertyにアクセスできる(そのままだとデフォルト値だけど)。

このパターンも検証1での結果と同じ結論になりそう。

検証3

  1. 既存のShaderに対して、ZWriteやZTestなどの設定を書き換えて作ったアプリで、既存のAssetBundleを読み込んでみる。
  • 書き換える前のShaderと同じ動作をする!

なぜ!?
Propertyの値やレンダリング順序に関しては、AssetBundleを作った時のMaterialのプロパティに含まれているため、
そこが参照されるのはわかる。

でも、ZWriteやZTestの変更が適用されないのはなんでだ?
もしやShaderのセッティング(Tagsとか)に関してはAssetBundleに含まれている!?
気のせい!?気のせいなの?
何かミスった?

これだとあとでShaderの実装をまとめて変更しようとした場合、内容によってはすでに配信しているAssetBundleが大量にあったら困っちゃう。

検証3のケースへの(とりあえず)対応

アプリの実行時に「Shader.Find(material.shader.name)」的なコードでShaderを再設定してあげると、正しく変更が適用されました。

結論

色々ググったりしてみたものの、結局のところAssetBundleにどこまでの情報が含まれているのかは謎。
試した範囲では参照を含んでいるっぽい挙動をしているけど、場合によって変な対応を強いられる。

うーん。。。何かAssetBundleを作るとき(あるいはプロジェクト)の設定によるとかあるのかなー。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?