ボクセルフェースクロール(メッシュの単純化、場合によっては貪欲を使用)


9

編集:これは私自身の学習経験のためだけのものであり、私がこの質問をするのはパフォーマンス上の理由のためではありません。

これはMinecraftのような地形エンジンに関するものです。ブロックをチャンク(16x256x16ブロック)に格納します。チャンクを生成するときは、複数の手順テクニックを使用して、地形を設定し、オブジェクトを配置します。生成中は、チャンク全体(ソリッドまたは非ソリッド)に1つの1D配列と、ソリッドブロックの個別の1D配列を保持します。

生成後、隣接するソリッドブロックを繰り返し処理して、隣接するソリッドがないブロック面のみを生成します。生成する顔を独自のリストに保存します(これは、可能な顔/法線ごとに1つずつ、6つのリストです)。チャンクをレンダリングするとき、カメラの現在のチャンクのすべてのリストと、他のすべてのチャンクのカメラに面するリストのみをレンダリングします。これを行うには、6つのリストすべてを1つのバッファーに格納し、描画する範囲を変更します。

Andrew Russellが提案したこの小さなシェーダートリックで2Dアトラスを使用して、類似した面を完全にマージしたいと思います。つまり、それらが同じリストにある場合(同じ法線)、互いに隣接している場合、同じライトレベルである場合などです。最終的には四角形になることはわかっていますが、頂点の数を簡単に50%削減できるはずです私の見積もりが正しい場合はそれ以上。

私の仮定は、6つのリストのそれぞれを、それらが置かれている軸、次に他の2つの軸でソートすることです(ブロックの上部のリストは、Y値、X、Zの順にソートされます)。

これだけでも、非常に簡単に顔のストリップをマージできますが、可能な場合は、ストリップだけではなく、マージすることを目指しています。私はこの貪欲なメッシュアルゴリズムについて読みましたが、それを理解するのに多くの問題を抱えています。

だから、私の質問:説明されているように顔のマージを実行するには(動的なテレイン/ライティングの悪いアイデアであるかどうかを無視して)、実装が簡単なアルゴリズムがあるのでしょうか?また、私は貪欲なアルゴリズムをはるかに簡単な方法(リンクまたは説明)で案内する答えを喜んで受け入れます。

実装が簡単な場合や、ストリップを実行するよりも少しだけ優れている場合でも、パフォーマンスが少し低下してもかまいません。ほとんどのアルゴリズムは四角形ではなく三角形に焦点を当てているのではないかと心配しています。現在の方法で2Dアトラスを使用すると、現在のスキルに基づいて三角形を実装できるかどうかわかりません。

PS:私はすでにチャンクごとに錐台カリングを行っており、説明したように、ソリッドブロック間のフェースもカリングします。私はまだ閉塞淘汰をしていないし、決してしないかもしれない。

*編集:私は独自の小さなテクニックを実装しましたが、おそらく名前が付いていますが、6つのリストをたどります。これらのリストは、それらが置かれている軸、ブロックタイプ、照明レベルの順に並べ替えられています。私はそれらを反復処理し、移動しながら新しい長方形を作成し、同時に(特定の軸に向かって大きなバイアスをかけて)それらを成長させます。明らかに最適ではありませんが、実際には非常に高速であり、頂点数を平均で50%近く削減します。Byte56のコメントは、私が本当の答えを考えているクローゼットですが、答え/報奨金としてそれを選択することはできません。

これは、最適化をほとんど行わずに完全な初期地形を生成した後、この問題を処理する私の速くて単純な方法です。与えられたすべての正方形が同じ画像、光レベル、法線などであると仮定します。各色は、私がレンダリングする異なる四角形です。私のリストはそれらがそうであるようにソートされているので、これは非常に簡単/高速なアプローチです。


すべての最適化後も、パフォーマンスの問題が発生していますか?コードをプロファイリングして、問題の場所を確認しましたか?
MichaelHouse

@ Byte56ああ、それは現在のところまったくパフォーマンスの問題ではありません。私が学んでいるものを実際のゲームで使用することを試みるとき、それは将来のものになるかもしれません。今のところ、私は単に学びたいと思っています。単にそれらを学ぶために物事を学びたいだけの場合、私はあまり助けを得ないように見えるので、私はそれらのいずれも述べませんでした。
神話2013

私が実際にこれを使って適切なゲームに挑戦するのを回避するならば、私は目に見える世界が巨大であってほしいと私はまた言うべきであるように感じます。私は、キャラクターがMinecraftや他の多くのように高さ2ブロック、幅1ブロックになるのではなく、幅/長さ3ブロック、高さ6-9のようにしたいと思います。おそらく静的な地形です。
神話2013

1
ああ、オーケーティム。説明ありがとう。私がゲームのエンジンを作っているときに私はこれについていくつかの研究をしました。私の風景はダイナミックなので、何かが変更されるたびにパフォーマンスコストに見合う価値があるとは思いませんでした。ただし、この記事では、最大四角形の問題に関するいくつかの使用法を見つけることがあります。基本的には、似た顔をマージするためにあなたが話しているアルゴリズムです(貪欲ではないかもしれませんが、最適です)。幸運を!
MichaelHouse

@ Byte56ありがとう、ありがとうございます。それは確かに、私が探している種類のアルゴリズムに近く見えます。1回の実行ですべての最大の四角形を取得できるかどうかを確認するには、少し調整する必要があります。質問と詳細な回答の両方が将来的に他の多くの人を助けることができると思うので、私はこれについても少し賞金を上げるかもしれません。
神話2013

回答:


4

あなたはストリップ、または最高の状態で長方形をやりたいだけです。解決可能または役立つ他の形状はありません。

また、チャンクごとに6つのリストを保持することにより、任意の時点で、チャンクからの5つのリストを基本方向に使用し、少なくとも3つを他のリストごとに使用することも指摘しておきます。ここで時間を無駄にしています。ビデオカードがこの最適化を行うことができるだけでなく、自分でそれを行ったとしても、すべての面を1か所に保持し、法線をカメラ(ベクターの研究DOT積)。

CaptainRedMuffの、すでに見た貪欲なメッシュに関するリンクは、問題の答えです。また、最終的には「縞模様」のメッシュになることも明らかですが、それらは完全に効果的であり、より最適なものを使用することはより複雑になり、貪欲なメッシュはすでに複雑すぎると述べました。

単一のチャンクでパフォーマンスの問題が発生している場合、他の問題が非常に間違っていると思います。

私の最初の推測では、描画操作を頻繁に呼び出すことになります。ハードウェアにもよりますが、毎秒50から400〜回描画するようにグラフィックカードに指示することができます。.setDataまたは.draw ____ Primitivesへの呼び出しを何回行っていますか?


長方形は私が欲しいものです。Byte56はアルゴリズムを貪欲なものよりもはるかに簡単にリンクしましたが、コメントを回答として受け入れることはできません。彼はアルゴリズムを説明するのではなく、アルゴリズムにリンクするだけだったので、代わりに彼がコメントしたと思いました。私のリストについてどういう意味かわかりません。通常、チャンクごとに1〜2回の描画呼び出しがあります。私のリストはチャンクごとに1つのバッファーに保存されます。フレームごとに描画する範囲を変更します。私は間違っている可能性がありますが、不要なデータをGPUに送信すると逆効果になります。チャンクごとに1つまたは2つの追加の描画は、より多くのデータをgpuに送信して強制的にカリングするよりも優れているようです。
神話2013

パフォーマンスの問題はありません。私は単にこれらのことを学ぶことを楽しんでいます。私は質問を編集してこれを言うつもりですが、Byte56にも言ったように、私がやろうとしていることが実際に問題を解決していない場合、私はあまり助けを得ることができません。あなたの質問に答えるために、私は現在フレームあたり最大200-260のチャンクをレンダリングしています。これは、フレームあたりかなり一般的な500のDrawIndexedPrimitivesです。私は定期的にvsyncなしで100〜130 FPSを取得し、毎秒65,000回の呼び出しを行っています。私は失礼なことをするつもりはありませんが、あなたが言ったことはほとんど意味がありません。分からないかもしれませんので、誤解されている場合は詳しく説明してください。多分それはXNAと関係があるのでしょうか?
神話2013

ああ、申し訳ありませんが、毎秒ではなく、フレームごとに言うつもりでした。上限に近づきつつあり、地形のみを使用している場合は、ほとんど不足しています。
Phil

私はいくつかの改善点を思いついたので、答えを+1しましたが、質問とは関係ありません。また、可能な
コールドローコール

私が読んだ記事を400-500を限度として引用しなければなりません。簡単なグーグルは私を助けませんでした。
Phil

0

リンク先の記事は、実際にはメッシュを生成するためのアルゴリズムを提供していません。それは可能な解決策を評価する方法を述べています。

一般的に、しかし、記事は良い要約を提供します:1)素朴な解決策は悪いです、2)最適な解決策がありますが、それは書くと実行するのに時間がかかります、3)迅速なカリングははるかに良い結果を与えます(そしてこれはMinecraft自体が行うすべてです)、そして最後に4)よりスマートなソリューション(貪欲なアルゴリズム)があるかもしれません。

質問の画像に含まれる「解決策」、貪欲なアルゴリズムです。あなたの質問は「私は彼のソリューションを正しく実装しましたか?」私は「彼は解決策を与えなかった。あなたはこれを自分で解決した」と答えなければならない。

あなたの解決策はより良いですか?ええ。承知しました。おそらくそれだけの価値はありません。次のステップでは、オクルージョンカリングまたはLODの方が良いと思います。Minecraftは、地下にいるときでも地表を描くのに十分な数のサイクルを浪費し、水上にいるときは洞窟と地雷システムの広大なネットワークを描きます。メッシュが適切に分解されたら、ええ、覆い隠された表面を取り除くことは良いことです。ただし、(たとえば)一般に、CPUで行うよりも、ビデオカードで裏面カリングを行う方が高速です。

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