OpenGL Framebuffer ColorAttachment to Compute Shader
OpenGL Framebuffer ColorAttachment to Compute Shader
我想将自定义帧缓冲的颜色附件放入计算着色器中进行简单的图像处理,但我只得到黑屏。 这是我的示例代码
创建颜色附件
glGenFramebuffers(1, &this->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
glGenTextures(1, &this->textureColorBuffer);
glBindTexture(GL_TEXTURE_2D, this->textureColorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, this->width(), this->height(), 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
this->textureColorBuffer, 0);
编译和链接着色器
cshader = glCreateShader(GL_COMPUTE_SHADER);
const char *csSrc[] = {
"#version 440n",
"layout (binding = 0, rgba32f) uniform image2D destTex;
layout (binding = 1, rgba32f) uniform image2D sourceTex;
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main() {
vec4 texel;
ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);
texel = imageLoad(sourceTex, storePos);
texel = vec4(1.0) - texel;
imageStore(destTex, storePos, texel);
}"
};
glShaderSource(cshader, 2, csSrc, NULL);
glCompileShader(cshader);
cshaderprogram = glCreateProgram();
glAttachShader(cshaderprogram, cshader);
glLinkProgram(cshaderprogram);
调用着色器并将纹理绘制为四边形。着色器是一个简单的颜色切换着色器,用于测试目的。
glUseProgram(cshaderprogram);
glUniform1i(0, 0);
glActiveTexture(GL_TEXTURE0);
glBindImageTexture(0, outputTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY,
GL_RGBA32F);
glActiveTexture(GL_TEXTURE1);
glBindImageTexture(0, textureColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY,
GL_RGBA32F);
glUniform1i(1, 1);
glDispatchCompute(width() / 16, height() / 16, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
screenProgram.bind();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindVertexArray(screenVao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, outputTexture);
glDrawArrays(GL_TRIANGLES, 0, 6);
我能够正确地将 textureColorBuffer 渲染到四边形,并且可以写入纹理。我认为我不知道如何从帧缓冲区读取的问题。
我希望你能帮助我。如果还有一些问题,请问。
sourceTex
的绑定点是 1 而不是 0:
layout (binding = 1, rgba32f) uniform image2D sourceTex;
所以你必须将纹理绑定到图像单元 1
glBindImageTexture( 1, // <------- 1 instead of 0
textureColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
请注意,图像单位和纹理单位是不同的东西。
当然,您也可以在coumpute着色器中使用纹理采样器制服。如果destTex
和sourceTex
的大小相同,则可以将texelFetch
与gl_GlobalInvocationID
一起使用,以查找sourceTex
:
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout (binding = 0, rgba32f) uniform image2D destTex;
layout (binding = 0) uniform sampler2D sourceTex;
void main()
{
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
vec4 texel = texelFetch(sourceTex, pos, 0);
texel = vec4(1.0) - texel;
imageStore(destTex, pos, texel);
}
在上面的代码片段中,图像单元 0 用于destTex
,纹理单元 0 用于sourceTex
。
顺便问一下,你确定要做吗
texel = vec4(1.0) - texel;
请注意,如果texel
的 alpha 通道为 1.0,它将变得完全透明。
相关文章:
- OpenGL VBO Indexing ( How to compute Index Array)
- Generate boost::uuids::uuid from boost::compute::detail::sha
- OpenGL Framebuffer ColorAttachment to Compute Shader
- 在 OpenCV 中使用 hog.compute(..) 进行访问冲突
- 在 boost::compute 中分配大向量
- 通过引用将自定义结构的向量传递给 boost::compute 闭包或函数
- OPENCL:可以将模板对象作为内核参数,并使用boost :: Compute
- Using cv::rgbd::Odometry::compute
- 数学背后的"compute n! under modulo p"?
- 在特征库compute()中执行AnalyzePattern()和分解()的成本
- boost::compute,将指针传递给闭包
- vulkan - compute queuefamily - vkGetDeviceQueue - access vio
- 在 OpenGL 计划链路状态检查期间"No definition of main in vertex shader"
- Shader类中存在语法错误
- 将 DirectX11 ID3D11Texture2D 从 Shader 转换为 OpenCV IplImage
- OpenCV: HOGDescriptor.compute
- OpenGL HeightMap with vertex shader and QGLShaderProgram
- OpenGL Shader vs CUDA
- 如何在Visual Studio 11中使用Shader Model 5.0编译的着色器
- OpenGL Shader 在 AMD 机器中无法正常工作