レンダリングツリーのパフォーマンスへの影響をどのように減らすことができますか?


24

低ポリ様式のゲームを作っています。水がある地形があり、たくさんの木が欲しいです。現時点では、10,000本の木が大量に配置されています。各ツリーは200個以下の三角形で構成されているため、負担がかかりすぎません。

主な問題は、湖があり、湖が非常に大きいことです。湖の反対側には実際には木が見えません。特にそこを歩いていると木が突然現れたとき、それは本当にひどく見えます。

これを修正するには、湖の向こう側に十分な量の木が見えるように木の距離を長くする必要がありますが、パフォーマンスは40〜50 fpsに低下し、ゲームにはまだ他にほとんど何もありません。それが役立つ場合は、GTX 1080を使用しています。

ツリーを増やしてゲームをより速く実行するにはどうすればよいですか?


IIRC、サイレントヒルは、霧を使用してファークリッピングプレーンのカットオフを非表示にしました。ゲームの雰囲気の変化から恩恵を受けるかもしれません。
コーディ

木々が窓の外を見るようにあなたを引き寄せているため、パフォーマンスが低下しています。
mbomb007

プロファイラーを実行しようとしましたか?もしそうなら、ボトルネックはどこですか?
ミカエルヘグストローム

錐台カリングの種類はありますか?
クリシック

錐台カリングとは何ですか?
mrマット

回答:


43

描画パフォーマンスを向上させるためにできることがいくつかあります。

  1. あなたは彼らがかなり遠くにいると言った。LODを使用して、これらのツリーの頂点数を減らすことができます。したがって、描画されているすべての頂点を通過するのに必要な時間を減らすことができます。これは目前の問題ではない可能性が高いですが(GTX1080にはそれぞれ10万個のツリーがあり、それぞれ200のトリスがあり、GPUには小さな数字があります)、私はそれを含めました。ビルボードは、LODレベルが最も低い場合に効果的なツールです。これは、本質的には常にツリーのレンダリングされたイメージがカメラに面する平面であるためです。深さの感覚が失われるため、プレイヤーは違いに気付かない可能性が最も高いため、最低レベルに適しています。

  2. バッチ処理を有効にしましたか?動的なバッチ処理は、通常、メッシュの頂点数がかなり少ない場合に自動的に実行されます。静的なバッチ処理は、親ゲームオブジェクトのユニティエディターのチェックボックスをオンにしてツリーを静的にすることでも試行できます。これは、アニメーションオブジェクトではうまく機能しません。この機能を実現するには、オブジェクトに共有マテリアルが必要です。

  3. カスタムバッチ処理を使用すると、まとまりを処理せずに自分でチャンクを生成してレンダリングを制御できます。また、より大きなメッシュのバッチ処理も可能になります。これはMesh.CombineMeshesによって簡単に行われます。これは、アニメーション化されたオブジェクトでもうまく機能しません。この機能を実現するには、オブジェクトに共有マテリアルが必要です。あなたはおそらくあなたの世界をある種のチャンクに分割し、それらからバッチを作成したいでしょう。これらのチャンクの生成方法は、カメラが世界でどのように動くかによって決まります。

  4. シェーダーでインスタンス化を有効にします。インスタンス化により、エンジンは1回の描画呼び出しで複数のオブジェクトを(同じメッシュで)描画できます。これを機能させるには、オブジェクトに共有メッシュと共有シェーダーが必要です。マテリアルはさまざまですが、シェーダーはさまざまなさまざまなプロパティをすべてサポートする必要があります。

    エンジンでインスタンス化されたレンダリングバッチをより適切に作成するには、おそらく同じメッシュをシーン内でグループ化する必要があります。また、1つのメッシュが常に同じマテリアルを持っている場合、マテリアルレンダーキューで遊ぶと良い結果が得られます。現在取り組んでいるモバイルゲームの開発中に、テストシーンでこれを使用してドローコールを半減させました。また、Unity 5.6以降Enable Instancingでは、素材のチェックボックスをオンにしてください。

  5. 一般的に、ドローコールとSetPassコールは控えておきます。これらは、GPUが原料を描画するための生の呼び出しであり、大きなオーバーヘッドがあります。drawcalls(これはバッチ処理とインスタンス化が行うことです)を減らすと、CPUが提供できる全体的なパフォーマンスが向上します。SetPass呼び出しは現在のシェーダーに対する変更であるため、多くの異なるマテリアルがある場合、複数のSetPass呼び出しが発生し、CPUも少し待機します。

  6. シーンが巨大で、CPU時間がシーン内のすべてのオブジェクトを通過する場合は、シーン内のオブジェクトを減らしてみてください。それらを個別に配置する代わりにいくつかのツリーをグループ化し、それらを単一のオブジェクトとして持つ。また、ツリーまたは親オブジェクトを移動していないことを確認します。これにより、Unityはキャッシュされたトランスフォームを破棄し、シーンツリー全体を再計算します。

  7. シーンが巨大で、CPU時間の大部分がシーンツリーを歩いてすべてのオブジェクトをレンダリングするリストを作成している場合、Unityにレンダリングを処理させないようにすることができます。描画可能なオブジェクトを追跡するより良い方法がある場合は、CommandBuffer.DrawMeshInstancedまたはGraphics.DrawMeshInstancedを使用してそれらを手動で描画できます。これはもっと高度であり、自分自身やその他のオブジェクトを選別する必要があるため、これについては詳しく説明しません。

静的または動的なバッチ処理が適切に機能していない場合(フレームデバッガーを確認することで確認できます)、実際に共有マテリアルを使用していることを確認する必要がありますmeshRenderer.material。を呼び出す.materialと、材料のコピーが作成され、バッチ処理が中断されます。.sharedMaterial代わりに使用してください。

Unity 5.6以降では、フレームデバッガーを使用して、特定のドローコールが以前のドローコールでバッチ処理されなかった理由を判断できます。これは、ゲームのドローコールを削減する際に非常に役立ちます。

インスタンス化には、静的/動的/カスタムバッチ処理よりも次の利点があります。

  • メッシュをメモリ内で複製する必要がないため、メモリの使用量が少なくなります
  • 複数のマテリアルを使用できます。共有シェーダーのみが必要です
  • オブジェクトをアニメーション化できます

また、欠点としてはUnityのかなり新しい機能であり、少し不安定になる可能性があります。また、古いGPUまたはモバイルデバイスGPUは、必ずしもインスタンス化をサポートしていません。


1.はい、LODを試しましたが、驚いたことに、実際にはさらに悪化しました。それぞれわずかに頂点数が少ない3つのツリーのバリエーションと、その上にツリーのレンダリングイメージがある1つの平面がありました。
ミスターマット

2.すべてのツリーが静的としてマークされています。私の知る限り、バッチ処理が可能ですか?あれは正しいですか?そして、あなたが共有素材と言うとき、あなたは単に、木が同じ素材を持っているということですか?
mrマット

3.これにより、実際にどのようなパフォーマンスの改善が行われますか?試してみる価値はありますか?
mrマット

1
2/3:私の経験では、Unityは動的バッチ処理ではあまりうまく機能せず、静的バッチ処理はビルドサイズを増加させるため、自分でバッチ処理を実装し、ロード時間を組み合わせたメッシュを実行しました。この手法を使用して、2500のドローコールを作成し、約300のドローコールに圧縮することができました。これは、ドローコールが重要なモバイルゲームにとって重要でした。不要な頂点を少し計算しました(画面外)が、それだけの価値はありました。
ラッセ

2
TFWあなたは木とパフォーマンスの低下についての質問を読んでいない時にビルボードについて単一の単語が失われた
のNum Lock

13

わかりましたので、問題は単純に、事前に計算されたリアルタイムGIを使用していなかったことです。少し前に確認しましたが、すぐには効果がなかったので、忘れて忘れてしまい、照明処理時間も非常に長くなりました。しかし、処理が終了したばかりで、私の言葉、fpsは3倍に跳ね上がりました。そのため、今のところはそのままにしておき、将来は常にプリコンピューターリアルタイムGIを使用するようにします。

パフォーマンスをさらに向上させるために私ができることが他にある場合は、私に知らせてください、私は最も感謝しています!


2
オクルージョンカリングは、シーンが大きい場合にも使用します。たとえば、多くの地形など、チャンクに分割して、ロードおよびアンロードすることを検討してください。
率直な月_Max_

あなたが問題を解決したように思えるなら、おそらくこの答えを受け入れるべきです。
ネムロック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.