2016-07-21 28 views
1

我修改與imageStore紋理的紋理像素()和後後我讀一些其他着色器sampler2D有質感()的紋理元素,但我得到它被存放在該值imageStore()之前的紋理。使用imageLoad()它工作正常,但我需要使用過濾和紋理()的性能更好,那麼有沒有辦法使用紋理()獲取修改後的數據?閱讀紋元imageStore()

編輯:

第一個片段着色器(寫入):

#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)); 
} 

第二個片段着色器(讀):

#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); 
} 

那我怎麼運行的着色器:

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); 

我做了這個簡單的應用程序來測試,因爲真正的一個非常複雜的,我首先清除紋理紅色,但紋理像素不會出現藍色的(除了在第二FRAG使用imageLoad的。着色器)。

+0

您需要更準確地描述情況。你在哪裏寫作,你在哪裏閱讀?發佈一些代碼。 –

回答

1

哦,那很容易即可。 Image Load/Store's寫使用incoherent memory model,而不是大多數其餘OpenGL使用的同步模型。因此,僅僅因爲你用Image Load/Store寫了一些東西並不意味着它對任何人都是可見的。您必須明確地使其可讀取。

您需要寫入數據的渲染操作,並且讀取它的操作之間的glMemoryBarrier call。由於讀取操作是紋理提取,所以正確的屏障是GL_TEXTURE_FETCH_BARRIER_BIT

而且僅供參考:您的imageLoad由於純運氣只能讀取書面數據。沒有什麼能保證它能夠讀取寫入的數據。爲了確保這樣的讀取,你也需要一個內存屏障。雖然明顯不同:GL_SHADER_IMAGE_ACCESS_BARRIER_BIT


而且,texture取得歸一化的紋理座標。 imageStore取整數像素座標。除非該紋理是矩形的紋理(它不是,因爲你使用sampler2D),它是不可能通過完全一樣的座標都imageStoretexture

因此,無論是你的像素被寫入錯誤的位置,還是你的紋理正在被採樣錯誤的位置。無論哪種方式,都存在明顯的錯誤交流。假設vs_uv_out確實是非標準化的,那麼你應該使用texelFetch或者你應該規範化它。幸運的是,您使用的是OpenGL 4.5,因此應該相當簡單:

ivec2 size = textureSize(tex); 
vec2 texCoord = vs_uv_out/size; 
out_color = texture(tex, texCoord); 
+0

我已經嘗試過glMemoryBarrier(GL_ALL_BARRIER_BITS),並沒有工作,所以GL_TEXTURE_FETCH_BARRIER_BIT不工作太 – FamZ

+0

@FamZ:沒有,那是錯的。這不僅僅是唯一的錯誤。查看修改。 –