gpt4 book ai didi

c++ - 在 imageStore() 之后读取纹素

转载 作者:行者123 更新时间:2023-11-30 05:24:58 26 4
gpt4 key购买 nike

我正在使用 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);

我制作了这个简单的应用程序来测试,因为真实的应用程序非常复杂,所以我首先用红色清除纹理,但纹素不会显示为蓝色(除了在第二个 frag.shader 中使用 imageLoad)。

最佳答案

哦,那就简单了。 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);

关于c++ - 在 imageStore() 之后读取纹素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38512490/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com