Compute Shader无法获取结果图像问题排查求助
问题排查:Compute Shader输出1D纹理无法读取数据
我正在用Compute Shader筛选符合条件的颜色列,想把结果输出到1D图像imgOutput做后续处理,但没法通过get_img获取任何数据。下面是我的代码实现,麻烦帮忙排查问题(注:第一个代码块里的texture已经提前生成):
C++ 代码实现
Shader spriteRowProgram, spriteColumnProgram; unsigned int resultTexture = 0; const std::string path = found::utils::Environment::GetRunPath(); const std::string sprite_row_path = path + "shaders/glfw_sprite_row.comp"; spriteRowProgram = Shader(sprite_row_path); std::vector<GLfloat> get_img(qMax(TEX_WIDTH, TEX_HEIGHT) * 4); glGenTextures(1, &resultTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_1D, resultTexture); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, qMax(TEX_WIDTH, TEX_HEIGHT), 0, GL_RGBA, GL_FLOAT, get_img.data()); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, texture); spriteRowProgram.use(); glUniform1i(1, 1); glBindImageTexture(1, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); glUniform1i(0, 0); glBindImageTexture(0, resultTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); glClear(GL_COLOR_BUFFER_BIT); spriteRowProgram.setInt("input_width", TEX_WIDTH); spriteRowProgram.setInt("input_height", TEX_HEIGHT); glDispatchCompute(TEX_WIDTH, 1, 1); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Compute Shader 代码实现
#version 430 core layout (local_size_x = 1, local_size_y = 1) in; layout(rgba32f, location = 0, binding = 0) uniform writeonly image1D imgOutput; // texture samplers layout(rgba32f, location = 1, binding = 1) uniform readonly image2D inputImage; uniform int input_width; uniform int input_height; void main() { vec4 baseColor = imageLoad(inputImage, ivec2(0, 0)); bool alpha = baseColor.w == 1; bool success = true; for (int i = 0; i <= input_height; ++i) { vec4 current = imageLoad(inputImage, ivec2(gl_GlobalInvocationID.x, i)); if (alpha) { if (current.w > 0.99) continue; else { success = false; break; } } else { vec4 difference = baseColor - current; success = abs(difference.x) < 0.01 && abs(difference.y) < 0.01 && abs(difference.z) < 0.01; if (success) continue; else { break; } } } if (success) baseColor = ivec4(0.1, 0.1, 0.1, 0.1); else baseColor = ivec4(1.0, 1.0, 1.0, 1.0); imageStore(imgOutput, int(gl_GlobalInvocationID.x), baseColor); }
问题排查与修复方案
- 缺少GPU到CPU的数据读取步骤:你仅用
get_img初始化了纹理,但Compute Shader执行后,没有将GPU上的resultTexture数据读回CPU。在glMemoryBarrier后添加以下代码:glBindTexture(GL_TEXTURE_1D, resultTexture); glGetTexImage(GL_TEXTURE_1D, 0, GL_RGBA, GL_FLOAT, get_img.data()); - 1D纹理参数设置错误:1D纹理只有S轴,
GL_TEXTURE_WRAP_T参数无效,删除该行:// glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - Shader中纹理访问越界:循环条件
i <= input_height会访问超出图像范围的像素(图像y坐标范围是0到input_height-1),修改为:for (int i = 0; i < input_height; ++i) - 类型转换错误:将
ivec4赋值给vec4会导致浮点数值被截断,改用vec4直接赋值:if (success) baseColor = vec4(0.1, 0.1, 0.1, 0.1); else baseColor = vec4(1.0, 1.0, 1.0, 1.0); - 冗余的Uniform设置:
image类型的资源通过binding布局直接绑定,不需要用glUniform1i设置纹理单元,删除以下两行:// glUniform1i(1, 1); // glUniform1i(0, 0); - 内存屏障类型不匹配:写入图像纹理后,应使用
GL_TEXTURE_FETCH_BARRIER_BIT确保数据可见性,修改内存屏障:glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
内容的提问来源于stack exchange,提问作者0ices
相关产品推荐
相关产品推荐

