Game teardown

スケールでのレンダリング:大量のオブジェクト数を効率的にカウントするための戦略

MATTHEW WOJTECHKO / MEGA CAT STUDIOSLead Game Developer
Aug 14, 2026
Mega Cat StudiosとPlayground Productionsによるゲーム「Backyard Baseball 2026」の近所の風景
このウェブページは、お客様の便宜のために機械翻訳されたものです。翻訳されたコンテンツの正確性や信頼性は保証いたしかねます。翻訳されたコンテンツの正確性について疑問をお持ちの場合は、ウェブページの公式な英語版をご覧ください。

これは、メガキャットスタジオが執筆したシリーズの第4回目の記事です。この記事では、Matthew Wojtechko氏がURPとHDRPの両方を使用することで得られたパフォーマンス上の教訓を考察し、1ミリ秒単位のタイムラグが重要な草のレンダリングにおいて、カスタムバッチレンダラーグループの実装といった高度なソリューションを探ります。

このシリーズの他のブログ記事も読んでみてください。

フレーム落ちすることなく数千ものオブジェクトをレンダリングすることは、定数困難な課題である。密集した都市景観と広大な風景は、現代ゲームの特徴となっている。しかし、これらの景色はプレイヤーにとっては息を呑むほど美しいものの、毎秒60フレーム(fps)のスムーズな動作を維持する任務を負ったエンジニアにとっては頭痛の種となる可能性がある。

また、モバイルやワイヤレス端末など、処理能力の低いプラットフォームをターゲットにしている場合、問題となるのはそうした画面だけではありません。何らかの詳細情報が含まれる環境であれば、どんな環境でもハードウェアに大きな負荷をかける可能性がある。

Mega Cat Studiosでは、長年にわたりUnityのレンダリングシステムの性能を最大限に引き出すことに取り組んできました。そして、 Backyard Baseballの愛らしいアートスタイルを、芸術的な意図を損なうことなくPCとコンソール向けに実現するためには、あらゆる手段を尽くす必要がありました。

この記事では、静的バッチ処理や頂点アニメーションテクスチャといったテクニックを探る、これまでで最大の3Dタイトルで遭遇した問題点をいくつか共有。これらはすべて、オブジェクト数が爆発的に増加してもフレームレートをスムーズに保つための手助けとなることを目的としています。

一見単純に見える環境であっても、低スペックのハードウェアでレンダリングするのは困難な場合がある。
一見単純に見える環境であっても、低スペックのハードウェアでレンダリングするのは困難な場合がある。

レンダリングの問題の原因を調査し、最適化します。

レンダリングは、CPUとGPUの連携によって行われます。

「CPUはコーチであり、GPUはアスリートだ。」「CPUがプレーを指示し、GPUがそれを実行する」と、 Backyard Baseballの最適化エンジニアであるリアム・デュダスは述べている。

GPUが行うべき処理は、他のタスクよりも時間がかかる場合がある。複雑なメッシュ、シェーダー、ライティングは処理速度の低下を引き起こす可能性があり、パフォーマンスを向上させる最善の方法は、アーティストにこれらのアセットの最適化を依頼することで、複雑さを軽減することです。

また、CPUがGPUに何を要求しているかではなく、どのように要求しているかが重要な場合もある。

CPUは命令を最適に実行しているか?描画内容を判断するのに時間がかかりすぎて、CPUがゲームの残りの部分を実行せずに時間を浪費しているのでしょうか?CPUは冗長な情報を提供しているのか?優秀なコーチはチームから予想外の逆転劇を引き出すことができるが、最適化となると、これらのシステムに「もっと頑張れ」と指示するだけではダメなのだ。重要なのは、彼らが扱っている情報の内容と、それをどのように伝えるかを理解することだ。

これは、CPUがGPUに渡す描画呼び出しを最適化することに尽きる。1回の呼び出しで処理できる作業量が多いほど良い。特に、レンダリングするオブジェクトが数万個もある場合はなおさらだ。

これを実現するための方法はたくさんありますが、実行する前に一つ注意点があります。

単に巧妙なコードを書くというスリルだけを求めて、無計画に最適化してはいけません。まずは必ずベンチマークを取るべきだ。プロジェクトが最も苦戦している箇所を見つけ出してください。必ず最初に尋ねるべき質問は次のとおりです。ボトルネックはCPUですか、それともGPUですか?

この記事で紹介されている解決策の中には、CPU のスピードを向上させるものもあれば、GPU のスピードを向上させるものもあります。フレームレートの急上昇のソースが実際にはもう一方のプロセッサにある場合、一方のプロセッサーの最適化に夢中になりすぎるのは避けたいものです。ゲームがCPUバウンドなのかGPUバウンドなのかを判断したら、どちらの処理に最も時間がかかっているかを調査し、その処理を最適化してください。Unityのプロファイリングベストプラクティスガイドは、開始のに最適な資料です。このガイドには、しばしば難解に思われるプロファイリングのプロセスに関するガイダンスを提供する便利なフローチャートが含まれています。

「私は多くのプロファイリングを行わなければならない」とリアムは言う。「CPUが多くの処理を行っているのにGPUがそうでない時、あるいはその逆の時も、私には分かります。」実際、我々の最大のボトルネックは、時期は違えど、この2つ両方だった。

この記事の最後に、皆さんの自己プロファイリングの旅にヘルプ、私たちのお気に入りのリソースを多数掲載しました。

さて、前置きはこれくらいにして、最適化探るいきましょう。

簡素化とカリング

レンダリングを行う際には、どのメッシュをどこにレンダリングするかを決定する必要があります。

メッシュの数が増え、必要な描画呼び出しが増えるほど、GPUが次のジョブを待っている間、CPUは何をすべきかを常に考え続けなければなりません。

レンダリングするメッシュの数を減らすことで、処理スピードさせることができる。例えば、複雑なメッシュを偽物、看板、またはローポリゴンバージョンにスワップたり、広大な世界を一度にレンダリングする量が少ない小さなレベルに分割したりすることができます。これらは実績のある解決策であり、可能な限り使用すべきですが、環境の詳細度には制限があります。

この問題を回避し、かつ実装も簡単な最適化の一つに、オクルージョンカリングがあります。これは、カメラがビュー内にあるものをチェックし、プレイヤーが見えないものをレンダリングしないようにするものです。これはメモリ使用量の増加という代償を伴うものの、時間を節約できる。しかし、オフィスビル内の詳細な部屋など、多くの固定メッシュが存在する環境では、多くの場合、その価値がある。この最適化は業界標準ではあるものの、それだけでは不十分な場合が多い。

静的バッチ処理

多様性を損なうことなくレンダリングするメッシュの数を制限するもう一つの方法は、それらを単一のメッシュに結合することです。

これはご自身で手動で行うこともできます。または、メッシュが同じマテリアルを共有限り、 Unity はバッチ処理と呼ばれるプロセスでこれを自動的に実行できます。ゲームオブジェクトを静的に設定すると、 Unityは同じマテリアルを持つすべてのメッシュを自動的にまとめてバッチ処理し、描画呼び出しを削減します。このオプションは、木や壁など、静的ているものに適用してください。

これにより、RAMの使用量とCPUのオーバーヘッドが大幅に削減され、GPUが一度にレンダリングできるコンテンツが増加します。ただし、結合されたメッシュを保存するには、より多くのGPUメモリが使用されることに注意してください。

静的バッチ処理は、特にBackyard Baseballにおいて、私たちの1キー最適化プロセスであることが多いです。URPのバッチ処理システムは使いやすいので、最も難しいのは、できるだけ多くのモデルで、できるだけ少ない材料を使用する方法を見つけることです。その絶妙なバランス感覚こそが、当社の最適化とアートチームに、非常にクリエイティブな猫たちが在籍している理由なのです。

GPU インスタンシング

ここで、物事そのものと、その物事の事例を区別し開始のが良いでしょう。

メッシュがあるとしましょう。メッシュはアセットです。そして、そのマテリアルはアセットである。それらは、ファイル構造体内に存在する単一のファイルです。ゲーム内の3Dオブジェクトはオブジェクト、メッシュによってその形状が記述され、マテリアルによってその表面の外観が記述されます。

しかし、 Unityは詳細を簡略化しているため、ゲームが実行されているとき、実際にはこれらのオブジェクトの複数のコピーがゲームワールドにインスタンス化されていることに気づかない開発者もいます。プレイヤーが森林を探索する際、ゲームファイルにアセットとして保存されている、同じ木が多数複製された場所を移動することになります。

これが、 『Backyard Baseball』の植物の表現にGPUインスタンス化を使用した理由です。CPUは、ツリーの各コピーをGPUへの個別の呼び出しによってレンダリングする代わりに、GPUに対してすべての同一モデルを一度にレンダリングするように要求する。注意しないと、森林中の木がすべて同じように見えてしまう可能結果がある。しかし、マテリアルのシェーダーに効果的なパラメータ(例えば、葉の色をカスタマイズする値など)をいくつか使用すれば、個々の木を個別に要求するのではなく、1つのモデルとマテリアル、そして各木固有の色をGPUに渡すことができます。

葉の描写は、GPUインスタンス化に適した場合が多い。
葉の描写は、GPUインスタンス化に適した場合が多い。

マテリアルの[インスタンスを有効にする]設定をトグルと、同じマテリアルを使用する異なるマテリアルインスタンスを同じドローコールに結合するようにUnity に指示します。これは、メッシュのバリエーションとパフォーマンスの両方をバランスよく実現する優れた方法です。また、静的バッチ処理とは異なり、GPUインスタンス化はシーン内で移動するゲームオブジェクトにも使用できるため、壁や木といったものだけでなく、残骸や事務用品といった小道具も最適化の対象となります。

頂点アニメーションテクスチャ

静的バッチ処理とGPUインスタンス化は、メッシュとマテリアルを最適化する2つの異なる方法です。しかし、場合によっては、アニメーションがボトルネックになっていることもあります。先ほどの単純な森林の例を考えてみましょう。さあ、その枝や葉がそよ風に揺れている様子を想像してみてください。どれも独特で自然なアニメーションます。1万個もの異なるアニメーション処理を通常の方法で実行しても、到底十分とは言えません。気をつけないと、かわいそうなCPUが息苦しくなるぞ!

一つのコツは、頂点アニメーションテクスチャ(VAT)を使用することです。VATはGPUの処理能力を乗っ取ってアニメーションに挑戦します。

Mega Cat Studiosのシニア開発者であるDavid Chávez Armenterosにとって、VATを使用して群衆をシミュレートすることは、最適化する上で最も好きなグラフィックス実装の1つだった。

「 アニメーターで標準的なスキンメッシュレンダラーを使用すると、パフォーマンスが低下し始める前にレンダリングできるキャラクターは数十体程度です」と彼は述べています。「しかし、VATとGPUインスタンス化を組み合わせることで、数千ものアニメーションオブジェクトを一度に画面に表示させることができます。」

VATでは、各メッシュ頂点は、フレームごとにテクスチャからアニメーションされた位置を読み取ります。そのためには、位置情報と回転データをRGB値にエンコードします。次に、特殊なシェーダーがテクスチャ内のすべてのピクセルを読み取り、すべての頂点をどのように移動させるかを決定します。

これは、 Backyard Baseballで揺れる芝生を表現するために使用したものです。これは滑らかなアニメーションを作成する効率的な方法ですが、あくまで視覚的な効果であり、ココライダーは変化しないことに注意してください。このため、VATは、移動が不可欠であるものの、正確な衝突判定が不要なシナリオに最適です。

Backyard Baseballでは、揺れる芝生は頂点アニメーションテクスチャ(VAT)によって実現されています。
Backyard Baseballでは、揺れる芝生は頂点アニメーションテクスチャ(VAT)によって実現されています。

そして、あらゆる最適化にはトレードオフが伴う。VATはCPUの負荷を軽減する一方で、RAMへの負荷を若干増加させる。これらはすべて、ゲーム内の他のレンダリングソリューションとのバランスを考慮する必要がある。

「このシステムで最も大変だったのは、メモリ使用量とGPUコンピューティングに基づくカリング計算のバランスを取り、無線接続デバイスの限られたリソースに対応することでした」と、 『Backyard Baseball』のテクニカルアーティストであるジョーダン・ラッタは述べています。

URPとHDRPの比較

グラフィックスを最適化する際に最初に行う選択は、プロジェクト開始時にどのレンダリングパイプラインを選択するかということです。ユニバーサルレンダーパイプライン (URP)(URP)は、優れた基本性能を備えており、モバイルやワイヤレスデバイスには絶対に欠かせないものです。HD レンダーパイプライン (HDRP)(HDRP)は、高忠実度のビジュアルを対象とし、より特殊なインスタンス化動作を提供します。

一般的に、 UnityではHDRPよりもURPを使用することをお勧めします。もしかしたら、 HDRPを必要とするユースケースをお持ちかもしれませんが、私たちは次のようなシンプルな原則に基づいて行動しています。レンダリングはできる限り効率的に行ってください。

HDRPは高度な機能を提供しますが、リアルな映像表現を追求していないのであれば、使用しないことをお勧めします。

さらなる最適化テクニック

画面上に何千ものオブジェクトが表示される場合、問題はレンダリングそのものにあるとは限らない。それはあなた自身のコードです。そのような場合、以下のような工夫が役立ちます。

  • 数千もの更新ループを1つに統合する。各ゲームオブジェクトにそれぞれ独自の MonoBehaviour を与えるのではなく、それらを 1 つに統合して、同じ Update 関数を共有ようにします。集中管理型の管理システムは、数千もの個別の更新ループを回避するのに役立ちます。
  • すべてを同じスレッドで実行するのではなく、マルチスレッドを使用してください。ジョブシステムBurstコンパイラーがあなたのゲームにとって良い選択肢となるかどうか検討してみてください。
  • キャッシュを活用して現金を手に入れよう。毎フレーム、メインカメラやゲームオブジェクトのTransformを取得する代わりに、それらを一度キャッシュして、その参照を再利用します。タロデフ氏は、パフォーマンスの向上を実演するとともに、その他の最適化についても説明しています。

次のプロジェクトで得られるレンダリング性能向上策として、おそらく最も効果的なのはUnityの最新LTSバージョンを使用することでしょう。Unity 6.3 LTSは、パフォーマンス向上のための最適化をはじめとする数多くの改善点を誇っています。

Backyard Baseballの場合、最もシンプルで最適化的な最適化は、テクスチャの使用量を抑えることでした。

意図せず必要なテクスチャの倍数を使ってしまう、いくつかの巧妙な方法があります。

  • シェーダー:シェーダーが同じテクスチャを異なる2つの場面で使用する場合、かつ同じ参照を共有しない場合、メモリ内の複数の場所にテクスチャがロード可能性があります。
  • スクリプト:同様に、コードベースの異なる部分で、異なる参照を介して同じテクスチャを読み込むことになる可能性があります。
  • Version Control:2人の開発者が同じファイルをそれぞれのローカルブランチに追加した場合、ブランチがマージされた際に両方のファイルが保持されることがあり、無駄なストレージ容量を消費してしまう。

私たちはこうした落とし穴を事前に認識し、発生する前に防ぐように努めていますが、厳格すぎると、迅速な反復サイクルが遅くなってしまいます。そこで、プロジェクトが開発サイクルの後期段階に入った際に、シェーダー、アセット、スクリプトを監査するために、当社の最適化担当者が登場します。

Mega Cat Studiosでは、これらの戦略によって、ほんの数年前には考えられなかったようなシーンをレンダリングすることが可能になりました。

私たちにとってレンダリングは基本的に魔法のようなものです。想像できるものは何でもリアルタイムで作成できますが、そのためには秘密のテキスト(Unityのドキュメント、ブログ記事、YouTubeチュートリアル)を注意深く研究する必要があります。幸運なことに、私たちのスタッフには、そういったドキュメントを徹底的に読み込み、その成果をチームと共有することを何よりも好む、まさに魔法使いのような人材が何人かいます。

そしてもちろん、最も恩恵を受けるのは選手たちです。ファンの方々には、バックヤードベースボールの世界を存分に楽しんでいただき、その世界をリアルに感じさせるためにどれだけの血と汗と魔法が注ぎ込まれたかを気にすることなく、その世界を体験していただければ幸いです。

詳しく見る