Zugalu EntertainmentがスローライフのRAM使用量を20GBから500MBに削減した方法:ヘビー・ライズ・ザ・クラウン

このウェブページは、お客様の便宜のために機械翻訳されたものです。翻訳されたコンテンツの正確性や信頼性は保証いたしかねます。翻訳されたコンテンツの正確性について疑問をお持ちの場合は、ウェブページの公式な英語版をご覧ください。
スローライフ:ヘビー・ライズ・ザ・クラウンは、リアルタイム戦略要素を持つ中世の都市建設ゲームです。プレイヤーの決定が王国の運命を左右するゲームで、シングルプレイヤーと協力型マルチプレイヤーの機能があります。プレイヤーは戦略的に領土と王国を拡大し、大きなマップに沿ってビルドすることができます。
チームがタイトルの開発を始めると、パフォーマンスを向上させる際に障害に直面しました。広範なテストの後、ボトルネックがどこにあるか、何をしなければならないかを学びました – アニメーションベーキングシステムをビルドし、カスタム植生システムを作成することです。ゲーム内のキャラクターアニメーションをどのように強化したか。
課題:
キャラクターアニメーションによって引き起こされるパフォーマンスボトルネックを克服する
プラットフォーム:
PC
開発拠点:
アルバータ州、カナダ
プロジェクトのスタッフ:
16
スローライフ:ヘビー・ライズ・ザ・クラウン:Unity のケーススタディ
スタジオは、数百のキャラクターをアニメーションさせながらパフォーマンスを最適化するにはどうすればよいか?
ゲームが形を成すにつれて、Zugalu Entertainmentチームにはパフォーマンスが最大の課題になることが明らかでした。彼らはかなり低いシステム要件を目指していました – GPU用のNVIDIA GeForce GTX 750 Tiグラフィックスカードと、CPU命令を読み取り実行する4つの独立したユニット(コア)を持つクアッドコアプロセッサーです。
「システムをターゲットにしたいときは、望ましいフレームレートは60 fpsです。私たちのシステムの中には、パフォーマンスの大部分を占めていて本当に変更できない部分があったので、できる限りの場所から利益を見つけなければなりませんでした」と、Zugalu Entertainmentのリードコンセプトアーティスト兼テクニカルアーティストのジャッキー・リーは言います。
パフォーマンスを向上させるエリアを探していると、膨大な量のキャラクターアニメーションがRAMを大量に使用し、多くのプレイヤーシステムがクラッシュする原因となっていたため、修正が必要だと判断しました。

成果
- RAMの使用量を20GBから500MBに縮小しました。
- 同時に画面上に数千のキャラクターをアニメーションさせました。
- キャラクターの描画コールの数を1,000から20のインスタンス描画コールに減少させました。
- GTX 750 Tiグラフィックスカードで約3.5ミリ秒から2080 Tiグラフィックスカードで0.35ミリ秒にパフォーマンスを向上させました。
頂点からボーンベーキングに移行しました。
キャラクターアニメーションプロセスを最適化するために、チームはアニメーションベーキングシステムを構築しました。彼らは同時に画面上に数百のアニメーションキャラクターを持つ必要があり、最初は頂点アニメーションアセットソリューションを検討しました。これは彼らのVRAMとRAMの使用にとって大きな問題でした。別の解決策を見つけられなかったため、彼らは自分たちのものを構築することに決めました。
アニメーションシステムのために、チームは頂点ベーキングを使用し始めました。これは、アニメーションのすべてのキーフレームを取得し、そのデータを頂点ごとにベーキングすることを含みます。「1つのテクスチャには1つのアニメーションが含まれますが、その1つのアニメーションのテクスチャのサイズはかなり大きいです。メモリコストは、頂点の数にベークされたフレームの数を掛けたものです。したがって、5000頂点×100フレームは、32ビット浮動小数点RGB形式で6MBのテクスチャになります」とLiは言います。「多くの異なるアニメーションが多様なキャラクターの大人数に掛け合わされる必要があると、メモリコストは極端になり始めます。」
彼らはそれを大幅に削減する必要がありましたが、アニメーションを加速するためにGPUを使用する能力を維持する必要がありました。彼らはボーンベーキングに移行することに決めました。これは、Unityのメッシュレンダラーが頂点を変換するためにボーンを使用するため、データを少なくする簡単な方法を提供しました。

スローライフ:重い王冠 | Zugalu Entertainment | PlaySide Studios
「私たちが必要だったのは、メッシュスキニングプロセスを取り、3Dメッシュをスケルトンまたはリグにバインディングし、スケルトンがアニメーションされたときにメッシュが現実的に変形し、動くことを可能にし、それをGPUに移すことでした」とZugalu EntertainmentのCTOであるGarrett Hauは言います。
彼らは次に、フレームごとのボーンの変換を取得し、それをテクスチャとしてベーキングしました。その種の情報を圧縮することで、彼らは多くのメモリを節約しました。「ボーンベーキングを使用すると、同じボーン構造を持つ異なるキャラクターがベイクされたアニメーションデータを共有できます。」農夫や労働者のようなキャラクターがいて、彼らのボーン構造は同じでした。「私たちは、さらに多くの節約を得るために、複数のキャラクターで同じベイクデータを再利用しました。」とLiは説明します。
最終的に、ゲームにはたくさんのキャラクターとアニメーションがあるにもかかわらず、RAMの使用量を20GBから500MBに削減しました。

ベイクされたアニメーションのエディタ内プレビュー
GPUインスタンシングの恩恵を受ける
アニメーションに関しては、チームはスキンレンダリングに焦点を当て、メッシュにマテリアル、シェーダー、テクスチャを適用して、肌の色、シェーディング、テクスチャをシミュレートしました。Liは、「GPUコンピュートベースのスキンレンダリングの利点は、GPUインスタンシングにアクセスできたことです。」と説明します。「各キャラクターを一度に1つずつレンダリングする代わりに、異なるアニメーションを持つ複数のキャラクターを1つのドローコールでレンダリングしました。」
これは、アニメーションデータ、テクスチャを取得し、それらを1つのテクスチャ配列にパックしたため可能でした。これはGPUにとっては単一のテクスチャのように見えます。「1つのドローコールを使用してすべてのキャラクターをレンダリングすることは可能ですが、より柔軟性を持たせるために、ボーンを共有するキャラクターは4体だけでした。」

インスタンス化されたドローコールのキャプチャ
頂点ベーキングからボーンベーキングに移行する際、チームはキャラクタードローコールの数を1,000から20のインスタンス化されたドローコールに削減しました。「頂点ベーキングは難しかったです。なぜなら、各個別のサブメッシュが異なると見なされていたからです。キャラクターは複数のパーツを持ち、それぞれにドローコールが必要です。」とHauは言います。
ボーンベーキングでは、ゲームにどれだけの異なるタイプのキャラクターがいるかによって異なります。各キャラクターは、すべてのサブメッシュを1つのメッシュに統合するため、最大でも1つのドローコールになります。「例えば」とハウは説明します。「画面上に10種類の異なるキャラクターがいて、それぞれに複数のサブメッシュがあっても、描画コールは10回だけです。」

スローライフ:重い王冠 | Zugalu Entertainment | PlaySide Studios
“「Unity には、あなたが望むことを正確に行う多くの API があります。」これには、インポートされた FBX から特定の情報を取得すること、シェーダーキーワードを簡単に切り替えること、使いやすいインスペクター API でカスタムエディターツールを作成することが含まれます。”
Jackie Li - Zugalu Entertainment
Lead Concept Artist and Technical Artist行列変換の構築
メッシュスキニングを学ぶことで、チームは大きなアニメーションのハードルを克服しました。彼らは、道中で役立つように Unity API を使用しました。
ボーン変換を取得するために、SkinnedMeshRenderer.bones. のパブリックプロパティにアクセスしました。この API は、他のゲームオブジェクトの変換に関する情報を含む変換の配列を返します。パフォーマンス測定のために、彼らはローカルネットワーク上の他のコンピュータで実行されている開発ビルドの自動検出を使用しました。これにより、彼らはメインコンピュータから作業しながら、最小要件システムでゲームをプロファイリングできました。
パフォーマンステストチームは、 ProfilerMarker.Begin() と ProfilerMarker.End() API を適用して、フレームごとのパフォーマンスをサンプリングしました。これらは、ProfileMarket.struct を作成し、CPU タイミングをテストしたい場所に前の 2 つのメソッド呼び出しを挿入することで使用できます。この結果は、Unity Profiler に表示されました。

スローライフ:重い王冠 | Zugalu Entertainment | PlaySide Studios
リは「Unity の API は素晴らしい」と言います。彼らは開発の特定の部分をシームレスにするのに役立ちました。チームが経験した唯一のバグは、GPU の座標空間に関するものでした。「ワールド空間は得られましたが、ボーン空間が必要でした。」
ベーキング中にボーン変換のフレームをサンプリングしている間、彼らは初期ボーン位置に対する変換、すなわちバインドポーズが必要でした。これを達成するために、彼らは行列変換を構築しました。まず、SkinnedMeshRenderer.sharedMesh.bindposesからバインドポーズ行列を取得しました。次に、ボーンのワールド変換行列をバインドポーズ変換行列(例:boneTransform.localToWorldMatrix * bindpose)と掛け合わせました。

Shader Graphにおけるキャラクターシェーダーのエディター内ショット
“「Shader Graphは、シェーダーコード自体を深く理解することなくシェーダーを作成するためのUnityの答えです。私たちがシェーダー全体を自分たちで書き直す必要がなかったので、本当に便利でした。」”
Garrett Hau - Zugalu Entertainment
CTO簡単にシェーダーを作成する
アニメーション用のシェーダーを制作する際、チームはShader Graphを選びました。「それは、シェーダーコード自体を深く理解することなくシェーダーを作成するためのUnityの答えです。私たちがシェーダー全体を自分たちで書き直す必要がなかったので、本当に便利でした」とHauは言います。
メッシュスキニングのために、彼らは多くのシェーダー計算を行う必要があり、Shader Graphが提供するノードによってそれを完了することができました。Liは「それはテクスチャサンプリングと行列計算です」と説明します。もし望むなら、Unityのカスタム関数ノードを使用してコード自体を書くこともできます。」
エディターツールのために、アニメーションディレクターは、彼がすべて自分で作成したため、アニメーションをベイクするための特定の要件を持っていました。「C#とUnityのAPIを使えば、シェーダーの補間をオンとオフにするのは非常に簡単でした。彼らはまた、ベイクするボーンの数とそれらをベイクするフレームの数を変更するのを手伝ってくれました」とLiは言います。「ユーザーフレンドリーなインスペクターAPIにより、これらのエディタ機能をベイキングツールに簡単に追加できました。」

Shader Graphでの行列テクスチャのサンプリング
楽観的で注意深くいること
結局のところ、ゲームの開発は浮き沈みが多かったが、チームはGTX 750 Tiグラフィックスカードで約3.5ミリ秒から2080 Tiグラフィックスカードで0.3ミリ秒にGPUパフォーマンスを向上させました。
Liが言うように、「私たちはパフォーマンスの節約とゲームの出来に非常に満足しています。」

スローライフ:重い王冠 | Zugalu Entertainment | PlaySide Studios
Unity Pro を今すぐダウンロード
強力なツール、サポート、検証済みのパートナー、活気あるコミュニティの助けを借りて、大手スタジオのリリースに競い、超える品質と成功を持つゲームを作成し始めましょう。