【问题标题】:Reading texels after imageStore()在 imageStore() 之后读取纹素
【发布时间】:2016-07-21 19:07:26
【问题描述】:

我正在使用 imageStore() 修改纹理的纹素,然后我在其他着色器中读取这些纹素作为带有 texture() 的 sampler2D 但我得到了在 imageStore() 之前存储在纹理中的值.使用 imageLoad() 可以正常工作,但我需要使用过滤,并且 texture() 的性能更好,那么有没有办法使用 texture() 获取修改后的数据?

编辑:

第一个片段着色器(用于书写):

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

我做了这个简单的应用程序来测试,因为真实的非常复杂,我首先用红色清除纹理,但纹素不会出现蓝色(除了在第二个片段着色器中使用 imageLoad)。

【问题讨论】:

  • 您需要更准确地描述情况。你在哪里写作,你在哪里阅读?贴一些代码。

标签: c++ opengl glsl


【解决方案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);

【讨论】:

  • 我已经试过 glMemoryBarrier(GL_ALL_BARRIER_BITS) 没用,所以 GL_TEXTURE_FETCH_BARRIER_BIT 也没有用
  • @FamZ:不,那是错误的。这不是唯一的错误。查看修改。
猜你喜欢
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多