休暇の予定
夏休み目前にして未だに休暇中の予定が真っ白な皆さんこんにちは。社会人にも短いながら夏休みというものはあるんですが非リア充の人間には海にも山に旅行にも行く予定はなく、部屋にこもってゲームを作るだけの休暇になりそうです。まぁ、対外的には「コロナのための自粛」と言って誤魔化していますが。
フレームレート
今更言うまでもないのですが、ゲームの性能対策で一番の指標となるのはフレームレート(FPS)です。
TVや映画といった被写体が動く映像は連続した静止画を短い間隔で表示することで動画となる仕組みですが、ゲームも同様に画面の描画を短い間隔で行うことで背景やキャラクターが動く映像を作り出しています。
このため、その描画の更新間隔が短ければ短い(FPSの値が高いほど)ほどゲーム内のキャラクターは滑らかに動き、長くなる(FPSの値が低いほど)程ぎこちない動きに見えます。
なので、最近のゲームでは画面の美麗さと共に、このFPSもできるだけ大きな値を維持する事が求められています。
前置きが長くなりましたが、要は制作中の3D脱出ゲームがあまりにもカクカクした動作だったのでStatusからFPSを調べてみると
17.9FPS!!
で、早急な対応が必要!・・・というのが今回の記事の趣旨となります。
低レートの原因
フレームレートなどの性能対策を行う場合、本来ならProfilerを利用してボトルネックとなっているところを探っていくのですが、今回は明らかにDraw CallやSetPass Callの値が大きいことが原因となっています。
Draw CallやSetPass Callは画面の描画の為にレンダリング処理がどのくらい行われているのかを測るための指標となる値で、それぞれの値についての意味はLIGHT11さんのブログで詳しく紹介されています。
SetPass CallやDraw Callを減らすには
- 影を描画しない
- テクスチャアトラスを作り、複数のマテリアルのテクチャを纏める
- メッシュを結合する
等の対応が有効です。
ただ今回に関しては影に関しては元々影が描画されないように全オブジェトに反映しているし、MeshBakerというアセット使ってメッシュの結合とテクスチャアトラスの作成を行って見ましたが、微減(SetPass Callが15000⇒11000)に留まり根本的な解決になりませんでした。
オクルージョンカリング
オクルージョンカリングとはカメラから見て壁等のオブジェトで遮蔽されていてカメラに写されないオブジェトを、最初から描画対象から外してしまおう、という機能で、描画対象から外れる=レンダリング処理が行われない=SetPass Call、Draw Callが減る、という効果があり、結果としてフレームレートが向上します。
ただし、オクルージョンカリングを行うにはカリングのための情報を事前に用意しておく(Bakeする)必要があります。
今回の対象となるのは下の図のようなステージで、長い廊下部分を通った先に左右に部屋が用意されたホールがある、という間取り。
プレイヤー(カメラ)が長い廊下部分にある場合、当然ながらその先にある左右の部屋は見えないのでオクルージョンカリングの対象となることがわかると思います。
まず、他のオブジェクトを遮蔽するオブジェクト(廊下の壁等)に対してInspectorからOccluder StaticのチェックをONに設定します。
逆に遮蔽される側のオブジェクトに対してはInspectorからOccludee StaticのチェックをONに設定します。
または、遮蔽する側、遮蔽される側どちらともにStaticのチェックを設定しても同様の設定として判定されます。
後はWindow > Rendering > Occlusion Cullingから設定ウィンドウを開き、Bakeボタンを押すだけです。
これで遮蔽物の情報が保管されます。
もし、Bake後に遮蔽する側、遮蔽される側の位置を変更したり、新しオブジェクトを作った場合は再度Bakeを行う必要があるので注意がしてください。
Bake後にゲームを動かしてみると
23.3FPS
まぁ、先程よりは随分改善されました、が、できれば30FPSぐらいには持っていきたいtところです。
SetActiveで非表示化
そもそもプレイヤー(カメラ)が長い廊下部分にある場合は、その先にある左右の部屋はアクティブである必要はないので部屋を丸ごとSetActiveで非表示化する事にしました。
プレイヤーが廊下を通ってホールの入り口のドアを開けると左右の部屋はアクティブ化され表示されるようにスクリプトを組みます。
そうすると
39.5FPS!!
目標としていた30FPSを軽くオーバーする結果になりました。
つまり、フレームレートを向上させるには
- 遮蔽される(見えない)オブジェクトは無闇にアクティブ化しない
という事でしょうかね。