2016-07-21 17 views
1

Ich modifiziere Texel einer Textur mit imageStore() und danach lese ich diese Texel in einem anderen Shader als sampler2D mit Textur(), aber ich bekomme die Werte, die im Textur vor dem imageStore(). Mit imageLoad() funktioniert es gut, aber ich muss filtern und die Leistung von texture() ist besser, also gibt es eine Möglichkeit, die modifizierten Daten mit texture() zu bekommen?Lesen von Texeln nach imageStore()

Edit:

erste Fragment-Shader (zum Schreiben):

#version 450 core 

layout (binding = 0, rgba32f) uniform image2D img; 

in vec2 vs_uv_out; 

void main() 
{ 
    imageStore(img, ivec2(vs_uv_out), vec4(0.0f, 0.0f, 1.0f, 1.0f)); 
} 

zweite Fragment-Shader (zum Lesen):

#version 450 core 

layout (binding = 0) uniform sampler2D tex; 

in vec2 vs_uv_out; 

out vec4 out_color; 

void main() 
{ 
    out_color = texture(tex, vs_uv_out); 
} 

Das ist, wie ich laufe die Shadern:

glUseProgram(shader_programs[0]); 
glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, 
        GL_RGBA32F); 

glDrawArrays(GL_TRIANGLES, 0, 6); 

glUseProgram(shader_programs[1]); 
glBindTextureUnit(0, texture); 

glDrawArrays(GL_TRIANGLES, 0, 6); 

Ich habe diese einfache Anwendung gemacht, um zu testen, dass, weil die echte sehr komplex ist, ich zuerst die Textur mit rot lösche, aber die Texel nicht blau erscheinen (außer imageLoad im zweiten frag. Shader).

+0

Sie müssen die Situation genauer beschreiben. Wo machst du das Schreiben und wo machst du das Lesen? Veröffentlichen Sie einen Code. –

Antwort

1

Oh, das ist dann einfach. Image Load/Store's schreibt verwendet incoherent memory model, nicht das synchrone Modell die meisten der Rest von OpenGL verwendet. Nur weil Sie etwas mit Image Load/Store schreiben, bedeutet dies nicht, dass es für andere sichtbar ist. Sie müssen es explizit zum Lesen sichtbar machen.

Sie benötigen eine glMemoryBarrier call zwischen dem Rendervorgang, der die Daten schreibt und der Operation, die es liest. Und da der Lesevorgang ein Textur-Abruf ist, ist die korrekte zu verwendende Barriere GL_TEXTURE_FETCH_BARRIER_BIT.

Und zu Ihrer Information: Ihre imageLoad konnte die geschriebenen Daten nur aufgrund reines Glück lesen. Nichts garantiert, dass es in der Lage wäre, die geschriebenen Daten zu lesen. Um solche Lesevorgänge sicherzustellen, benötigen Sie ebenfalls eine Speicherbarriere. Obwohl offensichtlich ein anderer: GL_SHADER_IMAGE_ACCESS_BARRIER_BIT.


Auch nimmt texture normalisiert Texturkoordinaten. imageStore nimmt ganzzahlige Pixelkoordinaten an. Wenn diese Textur keine Rechtecktextur ist (und nicht, weil Sie sampler2D verwendet haben), ist es unmöglich, die exakt gleiche Koordinate sowohl an imageStore als auch an texture zu übergeben.

Daher werden entweder Ihre Pixel an die falsche Stelle geschrieben oder Ihre Textur wird von an der falschen Stelle abgetastet. So oder so, es gibt ein klares Missverständnis. Unter der Annahme, dass vs_uv_out wirklich nicht normalisiert ist, sollten Sie entweder texelFetch verwenden oder Sie sollten es normalisieren. Glücklicherweise verwenden Sie OpenGL 4.5, das sollte ziemlich einfach sein:

+0

Ich habe bereits versucht glMemoryBarrier (GL_ALL_BARRIER_BITS) und es hat nicht funktioniert, so GL_TEXTURE_FETCH_BARRIER_BIT funktioniert nicht – FamZ

+0

@FamZ: Nein, das war falsch. Es war einfach nicht das * einzige * Ding falsch. Siehe Änderungen. –