计算计算着色器内帧缓冲区的颜色直方图

2024-02-11

正如标题所示,我正在将场景渲染到帧缓冲区上,并尝试从计算着色器内的帧缓冲区中提取颜色直方图。我对使用计算着色器完全陌生,并且缺乏教程/示例/关键字让我不知所措。

特别是,我正在努力正确设置计算着色器的输入和输出图像。这是我所拥有的:

computeShaderProgram = loadComputeShader("test.computeshader");

int bin_size = 1;
int num_bins = 256 / bin_size;
tex_w = 1024;
tex_h = 768;

GLuint renderFBO, renderTexture;
GLuint tex_output;

//defining output image that will contain the histogram
glGenTextures(1, &tex_output);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_output);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, num_bins, 3, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
glBindImageTexture(0, tex_output, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R16UI);


//defining the framebuffer the scene will be rendered on
glGenFramebuffers(1, &renderFBO);

glGenTextures(1, &renderTexture);
glBindTexture(GL_TEXTURE_2D, renderTexture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W_WIDTH, W_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glBindFramebuffer(GL_FRAMEBUFFER, renderFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

在主循环中,我在帧缓冲区上绘制一个简单的正方形,并尝试将帧缓冲区作为输入图像传递给计算着色器:

glBindFramebuffer(GL_FRAMEBUFFER, renderFBO);
glDrawArrays(GL_TRIANGLES, 0, 6);

glUseProgram(computeShaderProgram);
//use as input the drawn framebuffer
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderFBO);
//use as output a pre-defined texture image
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex_output);
//run compute shader
glDispatchCompute((GLuint)tex_w, (GLuint)tex_h, 1);

GLuint *outBuffer = new GLuint[num_bins * 3];
glGetTexImage(GL_TEXTURE_2D, 0, GL_R16, GL_UNSIGNED_INT, outBuffer);

最后,在计算着色器内部我有:

#version 450
layout(local_size_x = 1, local_size_y = 1) in;
layout(rgba32f, binding = 0) uniform readonly image2D img_input;
layout(r16ui, binding = 1) uniform writeonly image2D img_output;

void main() {

    // grabbing pixel value from input image  
    vec4 pixel_color = imageLoad(img_input, ivec2(gl_GlobalInvocationID.xy));

    vec3 rgb = round(pixel_color.rgb * 255);

    ivec2 r = ivec2(rgb.r, 0);
    ivec2 g = ivec2(rgb.g, 1);
    ivec2 b = ivec2(rgb.b, 2);

    imageAtomicAdd(img_output, r, 1);
    imageAtomicAdd(img_output, g, 1);
    imageAtomicAdd(img_output, b, 1);
}

我将输出定义为大小为 2d 纹理图像N x 3 where N是 bin 的数量,3考虑各个颜色分量。在着色器内部,我从输入图像中获取一个像素值,将其缩放到0-255范围并增加直方图中的适当位置。

我无法验证这是否按预期工作,因为计算着色器会产生编译错误,即:

  • 无法将布局(r16ui)应用于图像类型"image2D"
  • 无法找到兼容的重载函数"imageAtomicAdd(struct image2D1x16_bindless, ivec2, int)"
  • 编辑:更改为后r32ui之前的错误现在变为:合格的实际参数#1无法转换为不合格的参数(“im”)

如何正确配置我的计算着色器? 我的过程是否正确(至少在理论上),如果不正确,为什么?


至于你的问题:

无法将布局(r16ui)应用于图像类型“image2D”

r16ui只能应用于无符号图像类型,因此您应该使用uimage2D.

无法找到兼容的重载函数...

规范明确指出原子操作只能应用于 32 位类型(r32i, r32ui, or r32f)。因此您必须使用 32 位纹理。


您的代码中还有其他问题。

glBindTexture(GL_TEXTURE_2D, renderFBO);

您无法将 FBO 绑定到纹理。您应该改为绑定支持 FBO 的纹理(renderTexture).

另外,您打算将纹理绑定到图像统一而不是采样器,因此您必须使用glBindImageTexture or glBindImageTextures而不是glBindTexture。使用后者,您可以在一次调用中绑定两个图像:

GLuint images[] = { renderTexture, tex_output };
glBindImageTextures(0, 2, images);

Your img_output制服被标记为writeonly。然而,原子图像函数期望有一个不合格的统一。所以删除writeonly.


您可以在 OpenGL 和 GLSL 规范中找到上述所有信息,可从以下位置免费访问OpenGL 注册表 https://www.khronos.org/registry/OpenGL/index_gl.php.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算计算着色器内帧缓冲区的颜色直方图 的相关文章

随机推荐

  • 如何检查进程是否具有管理权限

    如何正确检查进程是否以管理权限运行 我检查了IsUserAnAdimMSDN 中的函数 https msdn microsoft com en us library windows desktop bb776463 aspx 但不建议这样做
  • Angular 7:从订阅内部调用时,ChangeDetectorRef detectorChanges() 会导致无限循环

    在阅读了与变更检测和类似帖子相关的所有材料并未能解决我的问题后 我在这里发帖 变化检测器参考detectChanges 从订阅内部调用时会导致无限循环 如果我不打电话detectChanges I get ExpressionChanged
  • Python Pandas read_csv 跳过前 x 和后 y 行

    我想我可能在这里遗漏了一些明显的东西 但我对 python 和 pandas 很陌生 我正在读取一个大文本文件 只想使用范围 61 75496 中的行 我可以跳过前 60 行 keywords pd read csv keywords li
  • 如何在 Spring Boot Maven 多模块项目中包含另一个模块的资源

    我有一个 Spring Boot Maven 多模块项目 如果spring boot模块依赖模块A并在src main resources模块文件夹A我想在最终的 Spring Boot 应用程序中捆绑一个属性文件或其他一些资源 我该如何实
  • nil:NilClass 的未定义方法“map”

    当用户尝试更新其个人资料时 我的应用程序似乎随机抛出 nil NilClass 的未定义方法 map 错误 但奇怪的是 它说更新时发生错误 但错误行实际上在视图中 完整错误 users update ActionView TemplateE
  • Dynamic_cast 没有按预期抛出异常

    基于这个答案 在 C 中查找对象的类型 https stackoverflow com questions 351845 finding the type of an object in c 我写了这段代码 static TVALUE ge
  • 当我对符号矩阵进行行归约时,为什么 SymPy 给出了错误的答案?

    如果我要求 SymPy 对奇异矩阵进行行归约 nu Symbol nu lamb Symbol lambda A3 Matrix 3 nu 1 0 0 3 nu 2 nu 1 2 0 0 2 nu 1 nu lamb 2 3 0 0 nu
  • Safari 中的 Vue.js 渲染问题

    我有一个使用 Vue 和 Laravel 编写的作品集网站 它使用 v for 呈现项目缩略图 除了 Safari 之外 这在每个浏览器上都工作得很好 但有一个奇怪的问题 除非用户调整浏览器窗口的大小 否则图像根本不会显示 相关代码如下 d
  • 如何在使用 Python 运行 wkhtmltopdf.exe 时停止弹出窗口

    我正在使用 wkhtmltopdf exe 使用 python 将 html 转换为 pdf wkhtmltopdf exe 的弹出窗口使我在运行它时很难处理任何其他事情 我必须转换大约 200K 个文件 并且必须同时处理其他事情 但它确实
  • 是否可以将摘要式身份验证与 XMLHTTPRequest 一起使用?

    我有一个简单的问题 是否可以将摘要式身份验证与 XMLHTTPRequest 一起使用 如果答案是否定的 那么技术原因是什么 或者如果可能的话 我该怎么做 非常感谢 谷歌到目前为止还没有好的答案 EDIT 感谢您的回答 在收到随机数后修改标
  • 设置 WPF ScrollViewer 中何时滚动

    我有一个滚动查看器 其中包含一个网格 其中有一堆表单控件 文本框 复选框 组合框等 当我通过选项卡浏览控件时 滚动查看器将滚动 但仅在必要时滚动 我的意思是我通过选项卡浏览滚动查看器中的所有内容 并且仅当控件不可见时滚动查看器才会滚动 我想
  • 为什么这些线程不按顺序运行?

    当我运行这段代码时 include
  • 在 Laravel 中同步一对多关系

    如果我有一个多对多的关系 那么用它的关系更新关系是非常容易的sync method 但是我用什么来同步一对多关系呢 table posts id name table links id name post id 在这里 每一个Post可以有
  • Google OAuth:如何使用刷新令牌?

    我可以将 Android 设备上的一次性使用令牌换成访问令牌 and a 刷新令牌 我正在尝试弄清楚如何使用刷新令牌 I found this https developers google com accounts docs OAuth2
  • 在 R 中导入和分析非矩形 .csv 文件

    我将从 Mathematica 迁移到 R 在导入过程中我不需要预测数据结构 特别是我不需要在导入之前预测数据的矩形性 我有很多文件 csv文件格式如下 tasty chicken cinnamon not tasty butter pep
  • 如何在 android 中显示简单的通知? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如何在 Android 的通知栏中显
  • 寻找一种优雅且非侵入性的方式来访问类的私有方法

    免责声明 这绝不意味着在生产代码中使用 这是对 C 边缘的探索 我的问题是一个后续问题 基于与 Johannes Schaub 的讨论 在c 中调用私有方法 https stackoverflow com questions 6873138
  • 强制 enum 为 unsigned long 类型

    是否可以强制枚举的基础类型为 unsigned long 类型 谢谢 在 C 11 及更高版本中 您可以明确提及您想要的类型 enum MyEnumeration unsigned long values go here 这将允许您显式控制
  • 如何从 AWS Codebuild 构建规范文件中排除文件夹?

    所以我需要从我的工件中排除一个文件夹 但谷歌搜索找不到任何信息 version 0 2 phases install runtime versions nodejs 10 build commands echo Build started
  • 计算计算着色器内帧缓冲区的颜色直方图

    正如标题所示 我正在将场景渲染到帧缓冲区上 并尝试从计算着色器内的帧缓冲区中提取颜色直方图 我对使用计算着色器完全陌生 并且缺乏教程 示例 关键字让我不知所措 特别是 我正在努力正确设置计算着色器的输入和输出图像 这是我所拥有的 compu