3

VBO を使用して数百万 (最大 10) の三角形に基づいてモデルをレンダリングしており、ユーザーがこれらの三角形のどれをクリックするかを検出する必要があります。

「ネームスタック」と「ユニークカラー」がどのように機能するかを読んで理解しようとしています。name スタックには最大で 128 個の名前しか含めることができないのに対し、unique-color には最大 2^(8+8+8) = 16777216 の異なる色を含めることができますが、近似値が存在する場合があるため、変更された..

私のケースに最適な戦略はどれですか?

4

2 に答える 2

9

基本的に、2 つのクラスのオプションがあります。

  1. 「三角形ごとに一意の色の方法」。つまり、すべての三角形に ID をアタッチし、ID を別のレンダー ターゲットにレンダリングします。これは 32 ビット (RGB の場合は 8、A の場合は 8) にすることができますが、さらに多くのアイデアを得るために 2 番目のビットを追加することもできます。三角形ごとに ID を取得するのは面倒ですが、実装は比較的簡単です。ただし、パフォーマンスにかなりの悪影響を与える可能性があります (フィルレート)。

  2. 適切なレイ トレーシング。ほとんどの場合、アクセラレーション構造 (octree、kd、...) が必要ですが、フラスタム カリング用にすでに 1 つある可能性があります。1 つの光線は実際には多くありません。この方法は非常に高速である必要があります。

  3. ハイブリッド。おそらく最も簡単に実装できます。頂点バッファー ID (「バッファーごとに固有の色:)」をレンダリングし、どの頂点バッファーが選択されたかがわかったら、すべての三角形に対して光線をトレースします。

一般的なケースでは、2) が最良の選択肢であると言えます。何かをすばやく動作させたい場合は、3) を選択してください。1)はおそらくかなり役に立たないでしょう。

于 2012-03-01T15:50:55.817 に答える
6

GPU カードに OpenGL 4.2 が搭載されている場合imageStore()、GLSL の関数を使用して、画像内の三角形 ID をマークすることができます。私の場合、画面上の事前定義されたウィンドウの背後にあるすべての三角形を検出する必要があります。ピッキング (ウィンドウ上でレンダリングされた三角形を選択すること) も同様に機能します。選択はリアルタイムで実行されます。

画像 (またはテクスチャ) の最大サイズは >= 8192x8192 = 64 M である必要があります。したがって、最大 64 M のプリミティブを使用できます (2、3 画像を使用する場合はさらに多くなります)。

画面の背後にあるすべての三角形 ID を保存するには、次のフラグメント シェーダーを使用します。

uniform  uimage2D id_image;

void main() 
{
    color_f = vec4(0)
    ivec2 p;
    p.x = gl_PrimitiveID % 2048;
    p.y = gl_PrimitiveID / 2048;
    imageStore(id_image, p, uvec4(255));
}

画面にレンダリングされたすべての三角形 Id を保存するには: まず、深度バッファーを事前に計算し、次にわずかに異なるフラグメント シェーダーを使用します。

uniform  uimage2D id_image;

**layout(early_fragment_tests) in;** //the shader does not run for fragment > depth

void main() 
{
    color_f = vec4(0)
    ivec2 p;
    p.x = gl_PrimitiveID % 2048;
    p.y = gl_PrimitiveID / 2048;
    imageStore(id_image, p, uvec4(255));
}
于 2012-07-31T12:02:36.747 に答える