6

オブジェクトの整数 ID を整数テクスチャ バッファに適切にレンダリングするにはどうすればよいですか?

内部フォーマット GL_LUMINANCE16 の texture2D があり、それをカラー アタッチメントとして FBO にアタッチするとします。

オブジェクトをレンダリングするとき、整数 ID をシェーダーに渡し、この ID を整数テクスチャにレンダリングしたいと考えています。

ただし、fragmentshader 出力のタイプは vec4 です。ID を 4 コンポーネントの float に適切に変換し、最終的に整数テクスチャ ターゲットの整数値がレンダリングしたい整数 ID に対応するような変換の不正確さを回避するにはどうすればよいですか?

4

3 に答える 3

5

ここに明確な答えがあるとはまだ思えません。そこで、2D テクスチャを使用してどのように機能させたかを以下に示します。

// First, create a frame buffer:
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// Then generate your texture and define an unsigned int array:
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, w, h, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// Attach it to the frame buffer object:
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textureid, 0);

// Before rendering    
glBindFramebuffer(GL_FRAMEBUFFER, fbo);    
GLuint buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; // this assumes that there is another     texture that is for the render buffer. Color attachment1 is preserved for the element ids.
glDrawBuffers(2, buffers);

// Clear and render here
glFlush(); // Flush after just in case
glBindFramebuffer(GL_FRAMEBUFFER, 0);

GLSL 側では、フラグメント シェーダーが持つ必要があります (4.3 コア プロファイル コードはこちら):

layout(location = 0) out vec4 colorOut; // The first element in 'buffers' so location 0    
layout(location = 1) out uvec4 elementID; // The second element in 'buffers' so location 1. unsigned int vector as color

// ...
void main()
{
//...

elementID = uvec4( elementid, 0, 0, 0 ); // Write the element id as integer to the red channel.

}

ホスト側で値を読み取ることができます。

unsigned int* ids = new unsigned int[ w*h ];
glBindTexture(GL_TEXTURE_2D, textureid);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, ids);
于 2013-12-20T15:12:30.957 に答える
4

あなたの質問にはいくつかの問題があります。

まず、「整数テクスチャ」でGL_LUMINANCE16はありません。正規化された符号なし整数値を含むテクスチャです。整数を使用して範囲 [0, 1] の浮動小数点数を表します。実際の整数を保存する場合は、実際の整数イメージ形式を使用する必要があります。

次に、ルミナンス テクスチャにレンダリングすることはできません。カラーレンダリング可能な形式ではありません。実際にシングル チャネル テクスチャにレンダリングする場合は、シングル チャネル イメージ フォーマットを作成する必要があります。したがって、 の代わりにGL_LUMINANCE16を使用しますGL_R16UI。これは、16 ビットの単一チャンネルの符号なし積分画像形式です。

これを正しく設定したので、それはかなり簡単です。uintフラグメント シェーダー出力を定義し、フラグメント シェーダーにuint値を書き込みます。これuintは、頂点シェーダーまたはユニフォームから発生する可能性があります。しかし、あなたはそれをしたいです。

明らかに、テクスチャまたはレンダ バッファを FBO にアタッチする必要もありますが、そのことは十分承知しています。

最後に 1 つ: 「テクスチャ バッファ」という語句は、これらのいずれかを意味しない限り使用しないでください。そうしないと、混乱します。

于 2012-05-12T22:49:02.480 に答える
0

あなたの整数 ID は一連のプリミティブの識別子だと思います。実際、シェーダー ユニフォームとして定義できます。

uniform int vertedObjectId;

レンダリングしたら、フラグメント処理を整数 textureに格納します。整数テクスチャは、整数ベクトル (すなわち)を返す整数サンプラー ( ) でサンプリングされることに注意してください。isampler2Divec3

このテクスチャは、フレーム バッファ オブジェクトにアタッチできます (フレーム バッファの完全性に注意してください)。フレームバッファ アタッチメントは、整数の出力変数にバインドできます。

out int fragmentObjectId;

void main() {
    fragmentObjectId = vertedObjectId;
}

いくつかの拡張機能のサポート、または高度な OpenGL バージョン (3.2?) が必要です。

于 2012-05-12T12:11:46.283 に答える