2

OpenGL4.3.0でボクセルレイキャスターを実装しています。同じサイズの3Dテクスチャにfloat値の256x256x256ボクセルデータセットを保存する基本バージョンがあります。

ただし、八分木を使用してLODスキームを作成したいと思います。ホスト側の1D配列にデータを保存しています。ルートのインデックスは0、ルートの子のインデックスは1〜8、次のレベルのインデックスは9〜72などです。八分木には全部で9つのレベルがあります(最後のレベルは完全な256x256x256の解像度を持っています)。octreeは常に満杯になるため、構造は暗黙的であり、ポインターを格納する必要はありません。ボクセルごとに1つのfloat値のみです。1Dインデックス作成とトラバーサルアルゴリズムがすべて設定されています。

私の問題は、これをテクスチャに保存する方法がわからないことです。GL_TEXTURE_MAX_SIZEは、イン​​デックス付けを理解した1D配列アプローチを使用するには小さすぎます(16384)。これを3Dテクスチャに保存する必要があり、そこに1D配列を詰め込もうとするとどうなるかわかりません。また、無駄にならないようにサイズと1D->3D変換スキームを選択する方法もわかりません。空間または時間。

私の質問は、誰かがこの八分木構造全体を1つの3Dテクスチャに格納するための優れた戦略を持っているかどうか、そしてその場合、どのように寸法を選択してインデックスを作成するかです。

4

2 に答える 2

3

最初に、1Dアレイソリューションを直接移植する方法について説明します。

まず、Mortennobelがコメントで述べているように、最大​​テクスチャサイズはおそらくそうではなく 3397、それはの列挙値にすぎません(この値を定義するopengl.hGL_MAX_TEXTURE_SIZEヘッダーは、ハードウェアとドライバーの制限をどのように知る必要がありますか?)。実装から実際の値を取得するには、を使用します。しかし、それでもこれはあなたには小さすぎるかもしれません(多分8192または同様のもの)。int size; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);

ただし、はるかに大きな1D配列をシェーダーに取り込むには、バッファーテクスチャ(OpenGL 3以降のコアであるため、DX10クラスのハードウェアに存在します)を使用できます。これらは、標準のOpenGLバッファオブジェクトからデータを取得するテクスチャです。ただし、これらのテクスチャは常に1Dであり、整数texCoords(いわば配列インデックス)によってアクセスされ、フィルタリングされません。したがって、これらは実際には実際にはテクスチャではありませんが、シェーダー内の線形1D配列としてバッファーオブジェクトにアクセスする方法であり、ニーズに完全に適合します(実際、通常のフィルター処理および正規化された1Dテクスチャよりもはるかに適合します)。 。


編集:以前と同じように単純な3Dテクスチャを使用することも考えられますが、階層の上位部分に自家製のミップマップレベル(はい、3Dテクスチャにもミップマップを含めることができます)を使用します。したがって、ミップマップレベル0は細かい256グリッドであり、レベル1には粗い128グリッドが含まれています...しかし、このデータ構造を効果的に操作するには、シェーダーで明示的なLODテクスチャアクセスが必要になる可能性があります(textureLodフィルタリングを使用しない場合は、texelFetch)、OpenGL3も必要です。


編集: OpenGL 3をサポートしていない場合でも、3Dテクスチャを使用して1D配列を配置することはお勧めしませんが、Rahulが回答で示唆しているように2Dテクスチャを使用することをお勧めします(1D-2Dインデックスマジックはそうではありません)本当に難しい)。ただし、OpenGL 3を使用している場合は、線形1D配列レイアウトを直接使用するためにバッファーテクスチャを使用するか、単純な八分木マッピングのためにミップマップを使用する3Dテクスチャを使用します(または、完全に異なる、より洗練されたデータ構造を考え出すこともできます)。そもそもボクセルグリッドの場合)。


編集:もちろん、完全に細分化された八分木は、実際には八分木のメモリ節約機能を有利に使用していません。八分木を3Dテクスチャにパックする、より動的でメモリ効率の高い方法については、八分木テクスチャに関するこの古典的なGPUGemsの記事からインスピレーションを得ることもできます。基本的に、すべての八分木セルを2x2x2グリッドとして任意に3Dテクスチャに格納し、このテクスチャの子へのポインタとして内部ノードの値を使用します。もちろん、今日では、浮動小数点数と一緒に整数を格納したり、素敵なビットエンコーディングを使用したりするなど、これにあらゆる種類の改良を加えることができます(内部ノードにもデータを格納する必要があるようです)が、基本的な考え方は非常に単純です。

于 2013-03-19T09:20:16.517 に答える
1

ソリューションのスケッチ/概要は次のとおりです。

2Dテクスチャを使用して256x256x256を保存します(4096x4096になります-4k x 4kテクスチャをサポートするOpenGLプラットフォームを使用していることを願っています)。

次に、1Dデータを行優先順に保存します。レイキャスター内で、行/列の変換(1Dアドレスから4k x 4kへ)を実行し、必要な値を検索します。

私はあなたが残りを自分で理解することを信じています:)

于 2013-03-19T03:38:38.143 に答える