ジオメトリシェーダをモバイル(Android・iOS)で使うのってどうなの?コンピュートシェーダは?
意外といけちゃったりする?と思ったりしたので、対応状況を調べてみました。
あくまでネット上に散らばっている情報をベースにしているので、実行確認してみたわけではありません。
ジオメトリシェーダとコンピュートシェーダの概念の話はカットします。
以下ざっくり結論。
ジオメトリシェーダはダメ。コンピュートシェーダは低価格帯や古めのAndroidを切り捨てればアリ。
別々の概念なのにセットで調べてる理由は「CPUでもやろうと思えばできるけど負荷を考えたらGPUにやらせたいよね」って事をできるという点で共通していること。
Unityに限った内容ではないのですが今回はUnity上で動かすなら、というお話です。
目次
情報ソース
特定の機能が使用可能かどうかはシェーダーコンパイルターゲットレベルのページでグラフィックスAPIごとにサポートしているシェーダモデルを確認します。
特定のグラフィックスAPIが動作するGPUを搭載しているAndroidデバイス一覧はこちらを参考にさせて頂いています。感謝。
ジオメトリシェーダの対応状況
Android
グラフィックスAPIとしてOpenGLES3.2もしくはVulkanが必要です。
NexusやPixelなどの主要端末でも2015年頃から対応が始まっている状況なので、低価格帯のものも踏まえるとかなり絞られるという状況でしょう。
(2020/10/31追記)AndroidのDeveloperサイトで全世界ではありますがシェアを確認できます。ES3.2のシェアは現在62.38%です。意外と多いですね。
iOS
問題はiOSです。
最近のiOSは(Macも含め)Metalを基本としています。
Metalの仕様として、ジオメトリシェーダは動作しません。
GPU的にはOpenGLESも対応しているのですが、OS側の仕様でES3.0までしか対応していません。Unityの見解としても非推奨です。
ちなみにMacはOpenGLでの動作を指定することでジオメトリシェーダを動かすことが可能です。
しかし、グラフィックスAPI呼び出しによるCPUオーバヘッドが軽減されたり、GPUの処理効率を上げてくれるといったMetalのメリットを放棄することになり、得策であるとは言えません。
ジオメトリシェーダまとめ
以上のことを踏まえると、Android専用、それも最新機種に絞ってという場合でない限り、モバイルでのジオメトリシェーダの使用は現実的ではなさそうです。
Metalがそもそもジオメトリシェーダをサポートしないことから、数年経ったくらいではこの状況が改善されるということはないということが言えるでしょう。
ジオメトリシェーダはWindowsPCやコンシューマゲーム、シェーダー芸などのデモ向け用途がメインになりそうです。VR分野ではMacはあまり使わないので活躍しそうですね。
Stadia
希望があるとするならGoogleのStadiaです。
Vulkanが使えますし、PC上で動かすのと同じなのでこれから出てくる最新機能も取り込めます。
ジオメトリシェーダに限らず、モバイルゲームの開発者が端末側のサポート状況を意識せずに作れるようになるのは明るい未来ですね。
AAAタイトルに絞った運用が始まったばかりでまだまだこれからという状況ではありますが、モバイル専門だからとハイエンド向け技術の勉強をサボっていると時代に置いていかれるかもしれません(自分への戒め…)。
コンピュートシェーダの対応状況
続いてコンピュートシェーダです。
Android
OpenGLES3.1もしくはVulkanが必要です。
ジオメトリシェーダと比べてESの対応バージョンが3.2から3.1に下がっているので、利用可能な端末の幅が広がります。
2014年頃から発売のAndroidで対応率が高いようです。
ES3.1がアツい
コンピュートシェーダとは関係ない話ですが、SRP上で同一シェーダならマテリアルが別々でも描画をまとめてくれる機能であるSRPBatcherに対応しているのがUnity2019.2以降ならES3.1ということで、個人的にES3.1は大きな境界線の1つだと思っています。
とはいえ2017年までに日本で発売された端末リストを見ても、2016〜2017年の発売でもES3.0まで。というものがいくつかあります。
ES3.1以上の機能を使う場合は、ESのバージョンを見てグラフィックス品質設定を切り替える実装をしておくなど対策は必要になってくるでしょう。
iOS
コンピュートシェーダはMetalで動作します。
MetalのサポートはiPhone5s以降です(iPhone5、iPhone5cはダメ)。
2020年現在、iPhone5s以降をサポートできるなら十分といったところでしょう。
コンピュートシェーダまとめ
古めや低価格帯のAndroidを切り捨てるならアリです。iOS専用アプリならiPhone5s以降に絞れば問題なく使用可能です。
ジオメトリシェーダでやりたいことによってはコンピュートシェーダが代替手段になることも考えられるため、選択肢として持っておくのは良いと思います。
今回この件について詳しく調べたのは「そろそろ自分、ジオメトリシェーダとコンピュートシェーダちゃんと勉強した方がええんかな?」と思ったからです。
結論として直近で必要になることは無さそうといった感じですが、コンピュートシェーダは必要に応じて使うという選択が遠くない将来に来そうだと感じたため、入門しておこうと思った次第です。
おまけ:グラフィックスAPIの設定
今回のようにグラフィックスAPIごとの機能の対応状況を調べた上で、例えば「ES3.1以上だけサポートしよう」と決めた場合はUnity側でも設定しておく必要があります。
設定しておかないと、ES3.1未満の端末でもアプリ起動することはできるが該当するシェーダが使われた時にピンク色になるという事態が起きます。
あとはMacでMetalではなくOpenGLを使う場合なども設定が必要です。
PlayerSettingsから設定
今回はAndroidでVulkanをサポートしていればVulkanを使用し、そうでなければOpenGLES3.1のサポートを必須とする設定を行ってみます。
ProjectSettingsを開き「Player」からAndroidを選びます。もしくはBuildSettingsからAndroidを選んで、左下のPlayerSettingsを押します。
Androidの設定を開いたら、「Other Settings」のタブを開きます。
プロジェクトを作成したUnityバージョンによってデフォルトの設定状態が違うと思うので、上のスクリーンショットと同じ状態にします。
- Auto Graphics APIのチェックを外す
- Graphics APIsが「Vulkan」「OpenGLES3」の順になるようにする
- Require ES3.1にチェックを付ける
以上で設定は完了です。重要なのは以下の2点です。
- Graphics APIsは上にあるものが優先される
- OpenGLES3をリストに追加した時は更に要求するバージョンを指定できる(Androidのみ)