入力ジオメトリなしでジオメトリシェーダーでプリミティブを生成する方法はありますか?


17

数年前、私はこのGPU GemをOpenGLに実装して、マーチングキューブを使用して3D手続き型地形を生成しようとしました。この記事では、効率を最大限に高めるために、ジオメトリシェーダーにマーチングキューブを実装することを提案しています。つまり、ドメイン内のすべてのボクセルに対してシェーダーを1回実行する必要があり、そのセルでジオメトリ全体が生成されます。

私がつまずいた問題の1つは、シェーダーの外部で実際に何もレンダリングせずに、ジオメトリシェーダーを実行する方法でした。私の解決策(かなりハッキーに思えた)は、各セルにポイントをレンダリングし、ジオメトリシェーダーでそれを破棄し、代わりに三角形を放出することでした。適切な解決策が見つからなかったため、この回避策は最終的なコードに残っていました。

だから、とにかくOpenGLに入力ジオメトリなしでジオメトリシェーダーからレンダリングパスを開始するように指示することはありますか?または、物事を実行するために、常にいくつかのダミーポイントをGPUに送信する必要がありますか。

回答:


15

いいえ、実際にそれを行う方法はありません。

ジオメトリシェーダーの呼び出しには入力プリミティブが必要であり、0個以上の出力プリミティブを生成します。入力プリミティブがなければ、ジオメトリシェーダーを実際に呼び出す方法は実際にはありません。もちろん、各入力プリミティブに対してジオメトリシェーダーの出力プリミティブの最大数の制限を拡張することができます(実際の制限は今のところわからない、おそらく数千のオーダーであるはずです)。したがって、各ポイントに対して1024個の三角形を生成できますが、常にいくつかの入力プリミティブが必要です。

あなたが必要としませんがして、ジオメトリの実際の概念です。妥当な位置に3Dポイントをレンダリングする必要はありません。抽象的なインデックスやテクスチャ座標、または属性として何でも持つことができ、必ずしも意味のある3D位置とは限りません。頂点がどの属性を持つかは誰も指示しません。また属性なしで頂点レンダリングすることもできます。しかしプリミティブに実際の属性がない場合でも、いくつかのプリミティブをレンダリングしてジオメトリシェーダーを呼び出す必要があります(ただし、ジオメトリシェーダーで出力ジオメトリを計算する方法は別の質問です)。

しかし、実際に行ったこと、各グリッドセルのポイントをレンダリングし、そこからそのセルのマーチングキューブの三角形を生成することは、まさに簡単なアプローチです。もちろん、このセルに含まれる属性はユーザー次第です。3D位置、3Dテクスチャへのテックスコード、その他何でもかまいませんが、これらはレンダリングするグリッドセルです。純粋に意味論的に話されているので、実際にそれらのポイントを「破棄」してから三角形で「置換」するのではなく、各ポイントを三角形のセットに「変換」します。それがまさにジオメトリシェーダーの目的であり、「ハッキング」または「不適切」なものは何もありません。ジオメトリシェーダーは、入力が「適切」であるのと同じ出力プリミティブタイプを生成する必要があるとは言いません


ボクセルグリッドをレンダリングする主に入力のない方法を実現するためにできること(そして、これは実際に求めていたものかもしれません)は、属性のないポイントのセットを描画することです。これは、属性配列をまったく必要とせず、それらをすべて無効にし、glDrawArrays必要な数のセルで単純な配列を呼び出すことを意味します。次に、頂点シェーダーまたはジオメトリシェーダーで、必要な3Dグリッドセルインデックスを入力頂点IDから少しのインデックスマジックで生成し(つまりgl_VertexID、これが唯一の情報です)、ルックアップからマーチングキューブジオメトリを計算します3Dボリュームテクスチャ(または任意のデータ構造)。

したがって、振り返ってみると、最初からステートメントを相対化する必要があります。入力プリミティブなしでプリミティブを生成することはできませんが、入力ジオメトリなしで生成することはできます

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