プレイヤーに見えるブロックを取得する方法は?


15

Ogreエンジンを使用してMinecraft風のゲームを書いていますが、問題があります。ゲームを最適化する必要があります。10000ブロックを描画しようとすると、2 FPSがあるため...平面の表示をブロックし、見えないブロックを非表示にするというアイデアを得ました。しかし、私には問題があります-一度にどのブロックがプレーヤーに見えるかをどうやって知るのですか?

そして、もしあなたがそのようなゲームのための他の最適化方法を知っているなら、Ogreでそれらをどのように使うかを書いてください。

回答:


16

さて、Ogreはすでに錐台カリングを実装しています(これは基本的にはカメラからは見えないものを描画しません)が、あなたの問題は別のものだと思います。

実際に10000ブロックを表示してはいけません、一般的に行われていること(または、少なくとも、私が見たクローンのようないくつかのOgre3dベースのMinecraftでは(これも作成しています)、オリジナルでは)メッシュを作成しています(いくつかのNxNxN領域のチャンク)に、示されている立方体の外面があります。つまり、2つのキューブを並べて配置すると、接触している2つの面は見えないため、描画する必要はありません。

これらの面は、次のようなものでも描画する必要があります。http//www.ogre3d.org/tikiwiki/tiki-index.php? page = DynamicGrowingBuffers 最新のビデオカードは、100ポリゴンの1000メッシュに対して100000ポリゴンの1メッシュを好みます。


10

この問題にはいくつかの側面があります。まず、10000ブロックをどのように描画しますか?実際に10000個の別個のオブジェクトとして描画していますか?その場合、これはほぼ確実にボトルネックであり、オクルージョンカリングの欠如ではありません。描画呼び出しを減らすために、これらのブロックを少数のメッシュ(メッシュあたり数千)にグループ化する必要があります。

あなたの実際の質問に関しては、思い浮かぶ3種類のオクルージョンカリングがあります。

1)視錐台の外側のブロック。これはあなたの後ろまたは2つの側にあるブロックを意味します。Ogreは、視錐台カリングを介してこれらをすでに削除しています。

2)「地下」または他のブロックに完全に囲まれているため、どの角度からも見えないブロック。これらを特定するには、siz隣接ブロックを調べます。それらがすべて固体の場合、ブロックは非表示になります。GPUはこれらのブロックについても耳にすることはありません-表面を表すメッシュを構築しているときはスキップする必要があります。

3)表面にあり、レベル内のいくつかの位置から見えるが、現在は丘(または何か)によって隠されているブロック。これは私が対処していない最も難しいケースですが、ハードウェアオクルージョンクエリをこのケースに使用できる可能性は十分にあります。

それは恥知らずなプラグインですが、Ogreを使用する人も含め、Minecraftクローンの開発に使用しているかなり成熟したライブラリがあります。ボリュームのコンテンツを定義すると、レンダリング可能な表面メッシュが生成されます。ホームページは次のとおりです。

http://www.thermite3d.org/

そして、これはそれを使用している他の誰かのプロジェクトのビデオです:

http://www.youtube.com/watch?v=Jju6WRPEK7o


4

バックフェースカリングを使用して、プレーヤーに面していない頂点とそれに関連するピクセルをカリングできます。深さのバッファリングが残りを処理する必要があります。10kブロックはそれほど多くありません。私の5770は1500fpsで10万個の頂点をレンダリングできます。あなたは何か他のことをかなりひどく間違っていると思います。


同意する。これは、他の何かの問題です。
ノタベン

1

10000個の個別のオブジェクトがある場合、ボトルネックはおそらく頂点、ポリゴン、または塗りつぶしではなくプリミティブカウントです。速度を上げるために、オブジェクトを少数の高ポリゴンオブジェクトにベイクします。

Minecraftにはキューブブロックの概念がありますが、現時点では参照が見つかりません。

ここにあります私の実験では、様々な技術とキューブのトンを描く上でも。ベーキングは含まれていません(まだ)。


0

私がしていることは、ブロックの配列を作成した後ですが、頂点を作成する前に、UpdateBlockVisiblilityと呼ばれるサブルーチンを実行します。

潜水艦はブロックの隣人をチェックし、それに応じてBlocks facevisible booleanを更新します。

#define BLOCKFACE_NORTH 0

#define BLOCKFACE_SOUTH 1 

etc etc etc

if(IsBlockAt(NorthOfBlock))
  Blocks[Whatever].facevisible[BLOCKFACE_NORTH] = false;

次に、顔が見える場合にのみ顔の頂点を作成します!シンプル:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.