サウンドクリエイターの自由度を広げることは、同時にゲームのリソース配分の責任を、一部担ってもらうことも意味します。WwiseのエディターやSDKの機能を使えば、例え最低限のCPUバジェットしかなくても適応できる効率的でスマートなオーディオ環境を作成できます。一方で、芸術的な可能性やクリエイティブな手法が一式そろうため、CPUを使い過ぎてしまう恐れもあります。このため、ゲームのほかの場面にも処理能力を回しながら、スムーズなゲーミング体験を提供するために、効率的にWwiseを使うことが重要です。今回は、プログラマーとサウンドデザイナーの両者を対象に、オーサリングツール自体やWwise SDK内で貴重なサイクルを確保するためのソリューションを探ります。Wwiseを最適に使っているのかを判断するために検証すべき重要なポイントがいくつかあります。この記事では、Wwiseのプロファイラ機能を使いながらPerformance Monitorビューで取得できる重要なデータについて考えます。
まず最初に、Wwise Profiling機能をよく理解して、特に Performance Monitorに慣れることが大切です。 Wwiseを使ったプロファイリング、トラブルシューティング、デバッグの方法の記事も、非常に役立ちます。
また、ゲーム内で直接 AK::SoundEngine::StartProfilerCapture() を使えば、簡単にプロファイリングセッションの自動作成を設定できます。
Performance Monitorを使う時に、 ビューのカスタム設定 でグラフに必要な値を表示させることができます。特に、ピークがどこで発生しているのか、またAudio Thread CPU%のグラフとの関係はどうかを解明するのに便利です。
(画像をクリックして拡大)
上記の例では Audio Thread CPU のピークが、 Number of Transitions/Interpolations や Number of Voices (Total)のピークと同時に起きているようです。
Audio Thread CPU
Audio Thread CPUはCPUに関する最初の判断基準となります。Wwiseからハードウェアに送る最終的なオーディオフレームをレンダリングするのにかかる時間の、参考になります。オーディオフレームのサイズは、サウンドエンジンの初期化を行う時点で、AkInitSettings::uNumSamplesPerFrameで決まります。Windowsプラットフォームのデフォルトはサンプル数1,024です。ネイティブのサンプリングレートが48,000 Hzなので、Wwiseが21.333 ミリ秒(= 1,024 / 48,000)毎にオーディオフレーム1つを送信する必要があります。オーディオスレッドで1つのフレームを作成するのに21.333 ミリ秒かかると、Performance MonitorでAudio Thread CPUが100%になります。目安としてAudio Thread CPUを50%未満、つまり1フレームを成立させるのに10.666 ミリ秒 未満に抑えるようにします。
オーディオフレームが不足しても(つまりCPU消費が100%以上でも)、Wwiseがバックアップとして1フレーム以上のバッファーを事前に確保しているので、1つのオーディオフレーム不足であれば、問題になりません。事前に確保される数はNumber of Refillsとして指定しますが、デフォルトは4であり、設定は AkPlatformInitSettings::uNumRefillsInVoiceで行えます。Refill分を使い切ってしまい、今のフレーム中に次をレンダリングする時間がなくなれば、Voice Starvation(音声枯渇)のエラーが発生します。これが複数のフレームで起きると、耳に聞こえてしまうクリックとなります。なお、Capture Logで100%を超えていなくてもVoice Starvationエラーが発生することがあります。Performance Monotorは200 ミリ秒毎に更新されるので、CPUの急上昇を見逃してしまうことがあるからです。
Voice Starvationの原因は、主に次の3つです:
1)オーディオスレッド(別名EventManagerスレッド、LowerEngineスレッド)が、ゲームの別のスレッドに先を越された場合は、たとえWwise自体が行っている処理が少なくても、消費率が高く表示されます。デフォルトで、オーディオスレッドのプライオリティはAbove Normalです。このスレッドのプライオリティを高くしておくことが大事です。また、プラットフォームがアフィニティ強制をサポートしていれば、その設定を AkPlatformInitSettings::threadLEngine で行い、同じCPUコアで処理するようにします。
2) ゲームが、1つのWwiseコールバックファンクションで処理しようとする量が多すぎる場合。コールバックでロックがかかると、オーディオスレッドが待機となり、CPU消費率も高く表示されます。
3) Wwiseの処理量が多すぎる場合。Performance Monitorの様々な値を細かく監視することが大事です。
Number of Voices (Physical)
フィジカルボイス数は、CPUリソースに最も影響する値です。まず最初に確認してください。フィジカルボイス数の理想的な値は?これはどちらかというとデザインの問題で、どのようなミックスにしたいのかによります。ボイスによってCPU消費量が違いますが、どの種類のゲームでもフィジカルボイスの平均数は約30~70個です。チャンネル数、適用される組み込みプロパティ(LPF、HPF、ピッチなど)、コンバージョン設定の違いなど、ボイス毎のCPU消費に影響する要素はいくつかあります。 例えば、Vorbisファイルのデコードの方がPCMファイルよりもCPU消費が高くなります。 慎重にコンバージョン設定を決めることが、非常に大事です。
フィジカルボイス数を直接減らす方法として、プレイバックリミット、プライオリティ、バーチャルボイスシステムなどがあります。詳しくは Wwiseヘルプ や、この Wwise 101コースの教材を参照にしてください。
Number of Voices (Virtual)
バーチャルボイス数はI/O、メモリ、CPUサイクルなどを節約するための参照値ですが、これが500未満に抑えられていれば、アクティブなゲームオブジェクト数や "Number of Active Events"の数をゲーム側で十分に管理できていることを意味するので、この数値にもよく目を向けてください。Virtualとなったボイスの扱いは基本的に“Kill if finite, else virtual”に設定しておけば、無限でないボイスはキル(消す)、無限のボイスはバーチャルになります。これがバーチャルボイスの設定として一番簡単で、最も効率的です。聞こえないボイスのうち、ループしないものはキルして、ループするものはバーチャル状態で維持する設定です。
Total Plug-in CPU
プラグインのCPU消費を示すTotal Plug-in CPU値をPerformance Monitorで表示させ、Advanced ProfilerのPlug-insタブでも表示させるには、プロファイラ設定(Alt+G)でPlug-in Dataのボックスにチェックを入れます。このビューに表示されるのは、現在アクティブなインスタンス数と、それに消費されるCPUです。Total Plug-in CPUを左右するのが、アクティブプラグインのインスタンス数です。Actor-Mixer HierarchyやInteractive Music Hierarchyにインサートしたプラグインは、1つの再生中のサウンドに対して、1つのインスタンスを作成します。このようなサウンドを同時に多数再生すると、CPU負荷が一気に増えるので、メディアのWEMファイルにEffectを"bake"するrenderのチェックボックスにチェックを入れることを検討してください。一方、バスに適用したプラグインは、バス1つに対してインスタンスを1つ作成するだけです。つまり、CPU消費に影響するのは、実際に再生中のサウンド数ではなく、プラグインのあるアクティブバスの数となります。
プラグイン関連でCPUに影響する別の変数として、処理するチャンネル数があります。例えば、モノサウンドに対してアクティブなEffectのインスタンスが合計3つ(つまり3チャンネル)がActor-Mixer Hierarchyにあれば、7.1chのバスに対してアクティブな同じEffectの1つのインスタンス(つまり8チャンネル)の場合よりも、軽くなります。最終的に、Actor-Mixerに複数のエフェクトをインサートした時のチャンネル数が、バスの合計チャンネル数よりも少ない場合には、Actor-Mixerにインサートした方がメリットがあります。どのようなEffectプラグインでも、処理するチャンネル数に比例してCPU負荷も増えます。唯一の例外がリバーブで、チャンネル毎のパフォーマンスコストがほぼ横ばいなので、一般的にAuxiliary Busに使用するのがベストです。
Number of Registered Game Objects
これは登録中のゲームオブジェクト数を示す値ですが、長い間アクティブでないゲームオブジェクトが出ることがあります。それらは、整理して登録を外すと良いでしょう。そうすることで、オブジェクトのポジションなどのパラメータを更新する時に、ゲーム側から更新するにしろ、サウンドエンジン内部で処理するにしろ、長いリストを確認する必要がなくなります。ここでも気になるのが、登録するゲームオブジェクトの理想的な数です。オープンワールドゲームでも80以下に保てるゲームもあれば、プレイ中のマップやレベルに存在する全てのオブジェクトを恒久的にライブにすることに決めて1,000個以上となってしまいながらも、良好なパフォーマンスを維持できるデベロッパもいます。いずれにしても、ゲームオブジェクトのリストが長ければ長いほど、パフォーマンス問題の確率が高まります。また、登録ゲームオブジェクト数が少ないほうが、問題が発生した時にProfilingレイアウト内で突き止めやすくなります。
API Calls
ポジション、オクルージョン値、ゲームシンク値などは、ゲーム側でどれほど頻繁に更新されているのか?コールは、少数のゲームフレームに渡り複数あるのか、それとも1つのフレームに集中してSDKコールが発生しているのか?全てのゲームオブジェクトに関して、RTPC値をフレーム毎に更新するべきなのか?Profiler Settings (Alt+G)でAPI Callsのチェックボックスにチェックを入れれば、フレーム毎のWwiseに対するAPIコールが多すぎないか、または不要なコールがないかを、確認できます。
Number of Transition/RTPC Interpolation
Performance Monitorに表示されるトランジション数(音楽の遷移であるミュージックトランジションと混同しないように注意)は、一定の割合または一定のカーブ形状で変化しているプロパティ値の増減を表します。 最もよく起きるトランジションは、フェード中のVolume値の変化です。基本的に、RTPCでコントール可能な全てのプロパティで時間の経過とともにトランジションが発生する可能性があり、トランジションには必ずサウンドエンジン側で少量の処理が伴います。トランジション数が500を超えた場合は、CPU負荷急増の原因かもしれないと考えてください。トランジションが起きやすい例は、Game Parameterの遷移補間をDistanceなど組み込まれたパラメータと組み合わせた時で、ゲームオブジェクトやリスナーが動くたびにトランジションが発生してしまいます。
ローエンドプラットフォームやモバイルプラットフォーム
Wwiseのサブプラットフォームシステムを活用( プラットフォームの管理参照)して、 リンク や Excluded(除外) 機能も利用することが、パワーの少ないプロセッサを使う時に大事です。サブプラットフォームでは前述の推奨方法をさらに経済的に適用する必要が出てくるかもしれません。例えばローエンドのモバイル端末などでは、フィジカルボイスの基準数を70でなく30に下げて、プラグインのアクティブインスタンス数も減らしてみます。PCMの品質と負荷の少なさに着目する例も増え、特に短いサウンドや頻繁にリピートするサウンドに活用され始めています。
まとめ
CPUを左右する要素はWwiseで他にもあると思いますが、結論として、上記の数値がCPUの最適化で最も注目すべきポイントだと考えられます。
コメント