4

計算シェーダーからテクスチャーにデータを出力しようとしていますが、imageStore() は何もしないようです。シェーダーは次のとおりです。

#version 430

layout(RGBA32F) uniform image2D image;

layout (local_size_x = 1, local_size_y = 1) in;
void main() {
    imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(0.0f, 1.0f, 1.0f, 1.0f));
}

アプリケーションコードは次のとおりです。

GLuint tex;

glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);

glBindImageTexture(0, tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
glUseProgram(program->GetName());
glUniform1i(program->GetUniformLocation("image"), 0);

glDispatchCompute(WIDTH, HEIGHT, 1);

次に、そのテクスチャで全画面クワッドがレンダリングされますが、現在、ビデオ メモリからのランダムな古いデータのみが表示されます。何が間違っている可能性がありますか?

編集:

これは、テクスチャを表示する方法です。

// This comes right after the previous block of code
glUseProgram(drawProgram->GetName());

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(drawProgram->GetUniformLocation("sampler"), 0);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);

glfwSwapBuffers();

drawProgram は次のもので構成されます。

#version 430
#extension GL_ARB_explicit_attrib_location : require

layout(location = 0) in vec2 position;
out vec2 uvCoord;

void main() {
    gl_Position = vec4(position.x, position.y, 0.0f, 1.0f);
    uvCoord = position;
}

と:

#version 430

in vec2 uvCoord;
out vec4 color;

uniform sampler2D sampler;

void main() {
    vec2 uv = (uvCoord + vec2(1.0f)) / 2.0f;
    uv.y = 1.0f - uv.y;

    color = texture(sampler, uv);
    //color = vec4(uv.x, uv.y, 0.0f, 1.0f);
}

フラグメント シェーダーの最後のコメント行は、次の出力を生成します

頂点配列オブジェクト (vao) には、6 つの 2D 頂点を持つ 1 つのバッファーがあります。

-1.0、-1.0

1.0、-1.0

1.0、1.0

1.0、1.0

-1.0、1.0

-1.0、-1.0

4

3 に答える 3

7

これは、テクスチャを表示する方法です。

それは十分ではありません。への呼び出しがglMemoryBarrier表示されないため、コードが実際に機能するという保証はありません。

注意: Image Load/Storeによるイメージへの書き込みは、メモリ コヒーレントではありません。それらが表示される前に、明示的なユーザー同期が必要です。後でテクスチャとして保存したイメージを使用する場合は、イメージに書き込むレンダリング コマンドの後で、イメージからテクスチャとしてサンプリングするレンダリング コマンドの前に、明示的な呼び出しが必要です。glMemoryBarrier

なぜそれが問題なのか、私にはわかりません

デスクトップの OpenGL はOpenGL ESではないためです。

最後の 3 つのパラメーターは、OpenGL に与えるピクセル データの配置のみを記述します。OpenGL がデータを保存する方法については何も変わりません。ES ではそうしますが、それは単に ES がフォーマット変換を行わないからです。

デスクトップ OpenGL では、浮動小数点データを正規化された整数テクスチャにアップロードすることは完全に合法です。OpenGL は、可能な限りデータを変換することが期待されています。ES は変換を行わないため、データに一致するように内部形式(3 番目のパラメーター) を変更する必要があります。

デスクトップ GL にはありません。特定の画像形式が必要な場合は、それを要求します。Desktop GL は、ユーザーが求めるものだけを提供します。

常にサイズ設定された内部フォーマットを使用してください。

于 2013-01-12T17:16:12.410 に答える
4

GL_RGBA はサイズ指定された内部形式ではないため、実際にどれがどれであるかを知ることはできません。ほとんどの場合、OpenGL によって GL_RGBA8 に変換されます。

あなたの場合、設定した GL_FLOAT パラメータは、テクスチャにアップロードできるピクセル データのみを記述します。

ここの表 2 を読んで、内部テクスチャ フォーマットとして設定できるものを確認してください。

于 2013-01-12T15:27:17.807 に答える
3

さて、私は解決策を見つけました。問題はここにあります:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);

この行は、内部形式 (GL_RGBA) のサイズを指定していません。GL_RGBA32F を指定すると、機能し始めました。なぜそれが問題なのか、私にはわかりません(誰かが説明できることを願っています)。

于 2013-01-12T12:28:11.663 に答える