その場でスタックチャンクをロードする方法は?


8

私は現在、Minecraftに触発された無限の世界に取り組んでいます。チャンクは 16x16x16のブロックで構成されています。ブロック(キューブ)は1x1x1です。

これは、私のコンピューターで12チャンク(12x16)のViewRangeを使用して非常にスムーズに実行されます。いいね。
チャンクの高さを256に変更すると、これは-明らかに-途方もない遅延になります。

だから私が基本的にやりたいことはチャンクを積み重ねることです。つまり、私の世界は[∞、16、∞]チャンクが大きくなる可能性があります。

問題は今、その場でチャンクを生成する方法ですか?
現時点では、自分の位置を中心にして(ほぼ遠くに)存在しないチャンクを生成しています。まだチャンクをスタックしていないので、これはそれほど複雑ではありません。

ここで重要な注意点として、私はまた、最小/最大の高さが異なるバイオームを持ちたいと思っています。だから、バイオームに平地ブロックと最も高い層は、8(8×16)になります-バイオームで山脈のブロックと最も高い層は、14(14x16)になります。例として。

私ができることは、例えば私の上と下に1チャンクをロードすることです。
しかし、ここでの問題は、異なるbioms間の遷移がyの1つのチャンクよりも大きくなる可能性があることです。




バイオーム間の遷移




私の現在のチャンクの読み込みアクションで

チャンクロードの例



完全を期すために、現在のチャンクは「アルゴリズム」をロードしています

private IEnumerator UpdateChunks(){
    for (int i = 1; i < VIEW_RANGE; i += ChunkWidth) {
        float vr = i;
        for (float x = transform.position.x - vr; x < transform.position.x + vr; x += ChunkWidth) {
            for (float z = transform.position.z - vr; z < transform.position.z + vr; z += ChunkWidth) {

                _pos.Set(x, 0, z); // no y, yet
                _pos.x = Mathf.Floor(_pos.x/ChunkWidth)*ChunkWidth;
                _pos.z = Mathf.Floor(_pos.z/ChunkWidth)*ChunkWidth;

                Chunk chunk = Chunk.FindChunk(_pos);

                // If Chunk is already created, continue
                if (chunk != null)
                    continue;

                // Create a new Chunk..
                chunk = (Chunk) Instantiate(ChunkFab, _pos, Quaternion.identity);
            }
        }
        // Skip to next frame
        yield return 0;
    }
}

回答:


1

プレーヤーがサーフェス上にある場合、特定のスタックでサーフェスの上下に1つのチャンクをロード/作成することを考慮する必要があるので、生成アルゴリズムは、プレーヤーがチャンクではなく、チャンクではなくトップレベルのスタックを考慮する必要があります。現在のチャンクレベルの上と下の地下1つで問題ありません。明確にするために、スタックは岩盤から成層圏までのチャンクの垂直列です:)

別の見方をすると、サーフェスがプレーヤーの現在のチャンクレベルを下回っているかどうか、つまり、サーフェスと1つ下を生成します。それ以外の場合は、現在のレベルと1つ上と下を生成します。

したがって、あなたの世界は256チャンクの高さになるとしましょう(* 16 = 4096ボクセルブロック)。スタックがビュー範囲内にある場合はいつでも、そのスタックには1から3チャンクが実際にロードされてレンダリングされます。

バイオームは、エッジで高さをブレンドするという追加の問題を引き起こしますが、サーフェスおよびサブサーフェスフィーチャーを生成するために呼び出されるバイオーム固有のコードでそれを処理できます。perlin / simplexノイズを使用して高さを生成している場合、チャンクが異なるバイオームであるチャンクに隣接していると、両方のバイオームタイプが生成するノイズ値を取得してから平均化できます。


0

あなたができることは、チャンクをy方向に256の高さにして、それをそれぞれ16ブロックの高さの16のセクションに分割することです。次に、チャンクのデータを生成し、セクション内にジオメトリを構築します。

1つの利点は、完全なチャンクのデータにアクセスできることです。これにより、セクションの上下のデータに簡単にアクセスできます。

これには、視錐台の内側にない多くのジオメトリを簡単にカリングできるという利点もあります。また、まったくジオメトリがないセクションも多数あります。

まだ使用していない場合は、チャンクを別のスレッドにロードすると、各チャンクのデータを生成しながら、フレームレートを向上させることができます。


1
まあ、多分私は私の漠然とした自己について説明しました。私はすでに1つのチャンクを16のレイヤーに分割することを計画しています。 しかし、どのレイヤーをロードするかをどうやって決めるのですか?すべてのバイオームには独自の最小/最大の高さがあります。想像してくださいバイオームA [100,20]バイオームB [160,200]-私は両方のバイオームの端にいます。彼らはスムーズな移行を持っています。どのレイヤーをロードするかを決める方法は?しかし、これを書いているときは、上のレイヤーが空/透明のときにすべてのレイヤーを(上から下に)チェックして作成する必要があると思います。最初のレイヤーが作成されたら停止します。あなたがこれを入手することを願っています;)コメントに空白行を追加できないのは面倒です
Brettetete

3
あなたの言ってる事がわかります。しかし、貪欲なメッシュのようなアルゴリズムを実装すると、パフォーマンスを大幅に低下させることなく、すべてのレイヤーをロードできるはずです。あなたは貪欲なメッシュについての記事をここで見つけることができます。ボクセルエンジンでも同じことをしていますが、これまでのところうまくいきます。
user000user 2014

このテクニックは素晴らしいです。これを私のエンジンに実装してみます。与えられたコードは少し奇妙です、あなたの実装を共有しますか?:)
ブレッテテ2014

2
ここに C ++実装を貼り付け、コメントを追加しました。それがお役に立て
ば幸い

すばらしい、これは非常に役立つようです。ありがとうございました!これを翻訳してみます。しかし、#67-#68にはダブル&&があります-コピーするものを誤って/誤ってダブルにしましたか?:)そして、SHIFT_メソッドについて簡単に説明/投稿できますか?また、私はtmpの宣言/使用を見ません-さて、その質問すべてに
申し訳ありませ

0

トランジションの問題があるため、特定のレイヤーをロードするだけではこれができないと思います。

私の傾向は、各チャンクにいくつかのメタデータを保存することです:

1)ブロックは完全に空気です。もしそうなら、それをレンダリングする必要はありません。

2)ブロックの各面は不透明です。不透明な面は、次のチャンクを考慮する必要がないことを意味します。(ただし、チャンクの場所に応じて、最大3つの面が関与する可能性があることに注意してください。3つの面のいずれかが不透明でない場合は、チャンクをレンダリングする必要があります。 b1が表示され、不透明ではない面f1があるか、b2が表示され、不透明でない面f2またはb3が表示され、不透明でない面f3があります。

残念ながら、12チャンクの視界範囲内には7000チャンク以上あります。ただし、実際には、チャンク数をおそらく1500以下に削減するこのアプローチを使用してレンダリングする必要がある3つを超える垂直チャンクを持つ場所は少ないと思います。

私はチャンク内に同じ種類のロジックを適用します-チャンクをロードするときに、どのジャンクションが透明で、どのジャンクションが不透明で不透明なタッチであるかを計算します-実際に面をレンダリングする必要があるのは、誰かがそれらを見ることができるところだけです。(Minecraftでは、ガラス、ドア、フェンスなどの3種類のブロック(透明、不透明、視覚変化)があることに注意してください。スキップできるのは、透明-透明と不透明-不透明のみです。)

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