1

ジオメトリ シェーダー N (N は 10000 などの非常に大きな数) の頂点を渡して、次のようにレンダリングできるのはなぜですか。

for (int i = 0; i < gl_VerticesIn; ++i) {
    gl_Position = projectionmodelview_matrix_ * gl_PositionIn[i];
    EmitVertex();
}

...しかし、このような N 個の頂点を生成することはできません (単一の頂点を渡すだけの場合):

for (int i = 0; i < N; ++i) {
    float f = float(i);
    gl_Position = projectionmodelview_matrix_ * vec4(f, f, f, 1.0);
    EmitVertex();
}

OpenGL はどうすればこの 2 つを区別できるのでしょうか?

*注: gl_PositionIn[0] などにアクセスするようにコードを変更しましたが、それでも 2 番目のコードでエラーが発生します。

4

1 に答える 1

3

これはすべて、GS が行っていることに対する根本的な誤解に基づいています。

「ジオメトリ シェーダー N 頂点を渡す」ことはありません。ドローコールgl_VerticesInの頂点数ではありません。ジオメトリ シェーダーは、描画呼び出しのすべての頂点を一度に処理するわけではありません。ジオメトリ シェーダーはプリミティブを操作します。そして、ドローコールは 1 つ以上のプリミティブを生成します。プリミティブの頂点の数です。これは、GS が動作する特定のプリミティブ タイプに対して修正されます。gl_VerticesIn

GL_TRIANGLES をプリミティブ タイプとして 30 個の頂点を描画すると、10 個の三角形プリミティブが生成されます。したがって、GS は 10 回呼び出されます。GL_TRIANGLE_STRIP をプリミティブ タイプとして 30 個の頂点を描画すると、28 個の三角形プリミティブが生成されます。したがって、GS は 28 回呼び出されます。

GS は 1 つのプリミティブを入力として受け取り、0 個以上のプリミティブを出力として放出します (頂点シェーダーが頂点を取得して放出し、フラグメント シェーダーがフラグメントを取得して放出するのと同様に、GS を「プリミティブ シェーダー」と呼ぶ必要があるのはそのためです)。ただし、出力にはさまざまな出力サイズの制限があります。これが、2 番目の GS がチョークする理由です。出力サイズの制限に違反しています。

于 2013-07-23T19:20:01.123 に答える