iOS 8 の新しいグラフィクス API。ワクワクしますね!

先のWWDCでAppleはMetalを発表しました。Metalは省オーバーヘッドで高効率、A7チップ用に設計された新グラフィクスAPIです。Metal はiOS搭載ハードウェアの機能をフルサポートしており、これまでよりずっとリアルで緻密でインタラクティビティにも優れたアプリケーションを作ることができるでしょう。

私たちは間もなくMetal でのレンダリングをサポートします。それに先立って、この新テクノロジーを皆さんにご紹介し、Metal がどんなにすばらしいかご説明させていただきたいと思います。

Metal の概要

Metalは小さなオーバーヘッド、揺らぎの少ない安定したパフォーマンス、プログラムのしやすさを実現するためにいくつかキーと成るアイデアを備えています。

  • Metalではリソースをできるだけ前もって作成し、評価するようになりました。シェーダーのコンパイルと一部の最適化はオフラインで行われます。レンダリングパイプラインに関係するステート、シェーダー、頂点レイアウト、ブレンディングモード、レンダーターゲットのフォーマットなどはレンダリング開始に先立って作成、評価されるようになりました。これにより ドローコール毎のステートチェックは不要となり、それに使われていた多くのCPUパワーが解放されます。
  • これまでより多様なマルチスレッディング処理ができるようになります。リソースはどのスレッドからも作成ができ、マルチスレッドで平行してドローコールの準備が可能です。
  • すべての iOS デバイスは CPUとGPUでメモリーを共有しています。CPUが持っているデータをビデオメモリーにコピーする”フリ”はもう必要ありません。バッファーを作ってポインターを取得するだけですみます。それは GPU から見えるメモリーと同じものです。
  • ユーザー(エンジン)が同期を処理します。OpenGL ESでありとあらゆるシナリオで動かすためには、その内部的な挙動を推測して動かさなくては成らないところがありました。Metalではユーザー(エンジン)の責任で CPUとGPU間のデータ同期を行うことになります。我々にはこれらをコントロールするためのノウハウがすでにあり、エンジン側で今までよりずっと良いケアを行うことができます。
  • iOS デバイスはすべてタイルベースの遅延レンダリングアーキテクチャを採用しています。特に レンダーターゲットに関して、Matal API は明らかにこれを意識して作られています。フレームバッファに関連したアクション、タイルのロードとストア、アンチエリアスのリゾルブ処理は明確に実行されます。
  • 上に述べたことは少ないCPUオーバーヘッドといまよりずっと安定した揺らぎの少ないパフォーマンスにつながります。
  • 最新のC/C++11ベースのプログラミング言語がグラフィクスとコンピュートシェーダー用に発表されました。これはコンピュートシェーダー、アトミック処理、任意のバッファ書込み機能による魅力的な手品が iOSでも実現できることを意味します。
  • 過去のしがらみとは決別しました。APIは非常にシンプルで合理的なものです。あー、それからめちゃくちゃ使える “debug layer”のオプションもあります。エラーやプログラムミスの確認や通知に使えるでしょう。

では、もっと詳しく見ていきましょう!

ドローコール問題

あなたがゲーム開発者、特にモバイルゲームの開発者ならドローコール問題をご存知でしょう。ゲーム内で描画されるすべてのオブジェクトの描画には CPUコストがかかります。今のところモバイル機では200から300体のオブジェクトの描画も難しいものがあるでしょう。実際のゲームでは、CPUパワーをレンダリングよりもゲームロジック、物理演算、AI、アニメーションなどもっと他のことに使いたいとお考えでしょう。Unity はドローコール数を削減する機能を備えています。例えば、スタティックバッチングとダイナミックバッチング、オクルージョンカリング、LOD、そして距離ベースのレイヤーカリング。またオブジェクトをまとめたり、テクスチャーをアトラス化してマテリアル数の削減を計ることもできます。

なぜ描画するのにCPUコストがかかるのでしょう? 結局、実際に働くのはGPUなのに — いい質問ですね。

エンジン側にもオーバーヘッドがあります。見えているオブジェクトを列挙する、どのシェーダーパスが描画に必要かを見つける、オブジェクトに当てるライトはどれかを判断する、マテリアルに必要なパラメーターを反映する、などなどといった仕事をCPUがしなくてはなりません。このいくらかはキャッシュされ、いくらかはマルチスレッド化されています。通常これらはプラットフォーム依存のコードです。すべてのUnityのリリースで私たちはこの部分の最適化に務めています。基本的にこの部分でMetalの恩恵を受けることはほとんどできません。

しかしながら、CPUオーバーヘッドはグラフィクスAPIとドライバーの中にもあります。ゲームにもよりますがこの部分の影響はなかなか大きいものがあります。Metalは現代的なハードウェアへの最適化により、この部分の負荷を取り去ろうとしています。ローレベルのアクセスによりOpenGL ESで必要だった推測での実装を撤廃すること、事前のレンダーステート作成と評価、レンダーターゲットに関するロード、ストアの明確化、API内での同期処理がもたらしていたパフォーマンス揺らぎの撤廃。– これらのすべてがCPUオーバーヘッドの削減に寄与しています。

私たちのこれまでのテストによると、APIとドライバーによるオーバーヘッドはCPUタイムでほんの数パーセントにまで減りました。これまで15-40%を費やしていたのと比べると大幅な改善がみられます。今後はCPUオーバーヘッドの大部分が我々のエンジンのコードによるものとなります。私たちは最適化を続けなくてはなりませんね :)

私たちは Metalでマルチスレッドによるレンダリングを活用するのを楽しみにしています。最適化の道が広がって非常に面白い方法をとることができるでしょうから。

GPUコンピューティングでの利用

Metal があれば典型的な 頂点+フラグメントのシェーダー以外の演算にGPUを使うことができます。– これはコンピュートシェーダーとして知られています。GPU内部のたくさんの小型プロセッサを使って並列演算処理を行う機能です。コンピュートシェーダーは”ローカルストレージ”の概念を持っています。きわめて高速に平行動作するGPU内部メモリーをアイテム間のデータシェアに使います。この特徴的なメモリーが頂点/フラグメントシェーダーでは表現できなかったGPUの使い方を可能にしています。
コンピュートシェーダーには数千もの興味深い用途があります。例えば、最適化されたポストプロセスエフェクト、パーティクルシステム、シャドウ、ライトのカリングなどなど。
私たちはUnityでコンピュートシェーダーをまだあまり使ってはいませんが、もっとたくさんのことに使うのを楽しみにしています。これから面白くなると思いますよ!

FAQ

  • いつ手に入りますか?
    私たちだって、もう待ちきれません。でも正確な日付を約束することは控えさせてください。既に多くは完了しています。でも、出荷できるようになるためにはまだやらなければならないことがあります。現在のプランでは CPU側のパフォーマンスを大幅にアップする Metal の機能をインテグレートするのが最初の目標です。できれば Unity 5.0で。それからコンピュートシェーダーのサポートを行います。(コンピュートシェーダーのサポートにはUnityの他の機能追加も含まれるでしょう)
  • サポートされるプラットフォームは?
    Metalを使うにはiOS8 と A7ベースのデバイス(iPhone 5S, iPad Air, iPad Mini Retina) が必要です。
  • Metalの 省CPUオーバーヘッドの恩恵を得るには何かする必要がありますか?
    通常、何も必要ありません。私たちが Unity でMetalのサポートを始めたら、特に意識することなく使えます。
    今、お持ちのすべてのプロジェクト、シェーダー、グラフィクスエフェクトは動きます。低いCPU負荷でお楽しみください。
  • しかし、シェーダーはどうなんですか? Metalのシェーダー言語は今までとは違うんですよね?
    私たちはこれにも対応します。今のところシェダーは Cg/HLSL で書かれており、OpenGL ES用にはユーザーに見えないところでコンバート処理しています。Metalについてもほぼ同じ方法でコンバートを行います。
  • CPUオーバーヘッドが小さくなって何が出来るのかもう一度教えてください。
    より良い物理計算、AIやもっと複雑なゲームロジック。今までより、たくさんのオブジェクトをスクリーン上に配置できます。また省バッテリー化による長時間駆動を楽しむのも良いでしょう。すべてはあなた次第です。

この記事は Metal, a new graphics API for iOS 8 をローカライズしたものです。