rita
プログラマーのritaと申します。10年少々ゲームエンジン開発に携わっており、今回はそこで得た知見から最適化のテクニックをご紹介します。
ゲーム開発者でなくても、普段見ている画面の裏側にどんな工夫が隠れているのかを知ると、 きっと今までとは異なる視点でゲームを楽しめるはずです!
ゲーム内の空間が画面に映るまでの仕組み
『ゼルダの伝説 ティアーズ オブ ザ キングダム』(画像はストアページより引用)
昨今の3Dゲームでは、キャラクターや建物などの3Dモデルがリッチに描かれるようになり、光の反射や影の表現も正確に行われるようになりました。
画面内に表示されるオブジェクトも多く、プレイヤーが到達できるエリアがフィールドの遠くまで広がる『ゼルダの伝説 ティアーズ オブ ザ キングダム』のようなオープンワールドゲームも作られています。
3D空間をテレビやディスプレイに映し出す仕組み
多くの3Dモデルが配置された空間を、ゲームはどのように画面に映し出しているのでしょうか?
3D空間をテレビなどの2D画面に映し出すには、カメラが収めている空間を2Dの画像に変換(投影)する必要があります。画像は「ピクセル(画素)」と呼ばれる単色の小さなドットが集まって構成されているため、2D画像への投影は各ピクセルの色を決定することと同じ意味になります。3D空間をもとにピクセルの色を決める処理を、3DCG用語で「レンダリング」といいます。
カメラが3D空間(左)の一部分を切り取り、写っていた範囲を2Dの画像(右)へと変換する
ピクセルの色は、3Dモデル自体の色や、その3Dモデルに当たっている光などから計算されます。コンピューターは、カメラの位置と角度から、各ピクセルにはどの3Dモデルのどの部分が映っているのかを計算します。加えて、光源の位置や反射を計算して、3Dモデルに当たっている光の強さも算出します。
なお、3DCGによる表現やカメラについては、こちらでも解説しています。
1秒間に30回レンダリングを行えば30FPS。60回なら60FPS!
多くのゲームが、画面のレンダリング処理を1コマ(1フレーム)ごとに繰り返しています。プレイヤーの操作に応じてゲーム内の状況はどんどん変わっていくため、ゲームの進行をスムーズに画面に映し出すために、おおむね1秒間に30回ないし60回のレンダリングが行われています。
繰り返し (ゲームが動いている間ずっと)
{
新しいフレームの処理をはじめる
オブジェクトの更新処理(どのように動くのかを決める)
オブジェクトの描画処理(画面に3D空間を描画する)
}
この繰り返しを「ゲームループ」と呼び、ループ1回分の処理がゲームの1フレームに対応します。
このゲームループが回る早さによって、動きのなめらかさや、操作に対する反応の良さが決まります。ゲーマーにはお馴染みの「60FPS」や「30FPS」などの数値は、1秒間に何回の状態更新と描画処理が行われるかが示されています。もちろん、この数字が多ければ多いほど、スムーズにゲームが動いているように感じられます。
「処理落ち」が起きる原因とは?
60FPSでの動作を目指す場合、1回の更新・描画処理に使える時間は約16ミリ秒です。
たった16ミリ秒という時間で、どれほどの処理が行えるでしょうか。豊かな自然!そこに息づく生き物たち!流れる水!その中を走り回るプレイヤー!リッチなオープンワールドに存在するものすべてを本来のクオリティで描画しようとすると……到底16ミリ秒では間に合いません!
なぜなら、コンピューターには時間あたりに計算できる回数が限られているからです。計算を行うパーツ「CPU」や「GPU」の計算能力には当然限界がありますし、計算に必要となる3Dモデルのデータを読み込む時間も必要になります。
3Dモデルなどのデータが保存されているのは「HDD」や「SSD」と呼ばれる記憶媒体(ストレージ)です。ただ、データの転送速度が非常に遅いため、高精細でデータの大きい3Dモデルの読み込みには長い時間がかかります。CPUによる計算時間もギリギリなのに、データのロードまで時間がかかってしまってはレンダリングどころではありません。
この対策として、高速な記憶媒体である「メモリ」にデータを一時的にロードしておき、CPUと直接やり取りをしてもらう仕組みが生まれました。「必要なデータだけをメモリにロードしておく」というのはゲームに限った話ではなく、コンピュータの基本動作のひとつです。ただ、メモリがためておけるデータ量はそれほど多くありません。
最新のゲーム機やコンピュータであっても、今いる場所に存在するものすべての描画を全力で処理しきろうとすると、計算能力が足りなかったり、メモリの容量よりも圧倒的に大きなデータを要求してしまったりして、16ミリ秒では計算が完了しなくなってしまいます。
処理にかかるコストは「処理負荷」と呼ばれます。1フレームの負荷が高く、処理にかかる時間が本来よりも長くなると、その分ゲーム内の時間も遅くなり、いわゆる「処理落ち」が発生します。極端な例として、1秒間に4回しか画面が更新されなければ、プレイヤーは0.25秒ごとに画面が切り替わるカクカクしたゲーム体験になってしまいます。
しかし、実際にリリースされているリッチなオープンワールドゲームは、処理落ちせずに動いています。一体どうやって、クオリティと低負荷を両立させているのでしょうか?
クオリティと低負荷を両立させる3つの最適化手法
連載第1回ではクオリティへの影響を抑えつつ処理負荷を軽減する、代表的な3つの最適化手法「カリング」「LOD」「ライトベイク」を紹介します。
それぞれの技術的な要素や仕組みについては第2回以降で詳しく紹介する予定のため、今回は「どんなものがあるの?」という種類だけ頭に入れていただくだけで大丈夫です!
カメラに映らないものは描画しない「カリング」
プレイヤーの周りにあるすべての物体やキャラクターがカメラに写るわけではありません。つまり、見えていない箇所は計算しなくても、レンダリング結果には影響がありません。写らないものを適切に省く処理を「カリング」と呼びます。カリングによって、映らないのに計算するというムダを大幅にカットできます。
カリングにもさまざまな種類があり、画面外のオブジェクトを描画しない「フラスタムカリング」や、手前のオブジェクトに完全に隠れるオブジェクトを描画しない「オクルージョンカリング」などがあります。
「LOD」で遠くにあるものは簡略化
3Dモデルはポリゴン数が多ければ多いほど、描画処理に負荷がかかります。とはいえ、遠くに存在するオブジェクトはカメラに大きく映らないため、細かく描画する必要はありません。
アニメや漫画において、アップになるキャラクターの顔はしっかりと描きこみますが、遠くにいるキャラクターはデフォルメして簡略化した表現に切り替えます。こういった省エネ思考が、CGの描画にも必要なのです。
このように、描画する3Dモデルを簡略化することで処理コストを下げるアプローチを「LOD(Level Of Detail)」と呼びます。
LODのイメージ。「LOD」の後に続く数字が簡略度を示している。「LOD 0」は元の3Dモデル、「LOD 1」は1段階簡略化した3Dモデル
LODを行わない場合、カメラのすぐ近くにいるキャラクターも、はるか遠くで点のようにしか見えないキャラクターも、同じ処理コストを割いて描画することになります。近くにあるオブジェクトはそのままに、遠くにあるオブジェクトを簡略化して描画コストを下げることで、画面全体のクオリティを保ちつつ処理時間を短縮できます。
ただ、簡略化した3Dモデルは一般的に人の手で用意する必要があるため、制作コストがかさむデメリットも存在します(※)。
※自動でLODを生成する技術も一般化されている。ただし、特に人型のキャラクターモデルに関しては、関節周りが自動でリダクションされた関係でアニメーションが破綻したり全体シルエットがおかしくなったりするケースがあるため、人の手で制作されるケースが多い
ライティングの計算を事前に行う「ライトベイク」
ゲームの実行中に行っていた計算を事前に行い、実行中は事前計算の結果を使うようにできれば、大きく負荷が減らせます。
事前計算の代表例として、場所ごとの光の当たり具合(ライティング)の計算結果をテクスチャに書き込んでおく「ライトベイク」があります。ライトベイクとは、光が当たった状態の見た目をテクスチャに描き込んでおくこと。光源と周囲のオブジェクトが静止していれば、フレームごとにライティングの結果が変わることがないため、常に同じ事前計算結果を使うことができます。
右が事前計算したライティング結果。実行時は常にこのライティング結果が使用される(画像はアンリアルエンジン公式ドキュメントより引用)
ライトベイクは負荷を減らせるメリットを持つ一方で、プレイヤーなど、事前計算のとき空間に存在しない物体の影は落とせないデメリットも持ち合わせています。そのため、負荷軽減かライティングの正確さ、どちらを重視するかによってライトベイクの採用/不採用が決まります。
事前にライティングを計算できないケースもあります。例えば天候や時間がダイナミックに変化するゲームでは、ライティングを事前に描き込んでおいても意味がありません。天気は雨なのに、晴れ模様のさんさんと輝く太陽光が当たったようなライティングになってしまっていては、違和感があります。逆に、常に夜のシーンしかないゲームや、屋内が舞台のゲームでは、計算の大半を事前に行えます。
まとめ
今回は、以下の2点をお伝えしました。
- ゲームループ1回に使える時間は、3D空間上のすべてのものに対して描画処理を行うには短すぎる
- 見た目に影響の少ない部分で処理を簡略化することで、リッチなゲームは処理落ちせずに遊べる
次回以降は、上記で述べた「カリング」「LOD」「ライトベイク」などの最適化手法について、より具体的に解説を行う予定です。どうぞご期待ください!
▼「カリング」にフォーカスした第2回はこちら
ゲームエンジンプログラマ。シリコンスタジオ、ゲームフリークを経て、現在はフリーランス的に活動中。低レイヤ・描画などのランタイムから、ツール・アセットパイプラインまで、ゲームに関する技術はなんでも守備範囲です。RPG・音ゲー・格ゲー・紳士ゲー・お馬さんなどなど幅広く嗜みます。新作を待ちわびているのは『世界樹の迷宮』『ブレイズアンドブレイド』『バーチャロン』など。