使用片段着色器计算纹素

发布于 2024-08-28 20:22:51 字数 162 浏览 4 评论 0原文

我有两个使用片段着色器生成的纹理。我希望能够计算每个纹理中高于一定颜色强度的纹素数量。

这怎么能做到呢?

我最初的想法是在生成纹理之前使用片段着色器对这些纹素进行计数。然而,这需要某种全局计数器。我无法使用遮挡查询,因为纹理是从其他纹理创建的。我正在使用 OpenGL 2.1。

I have two textures generated using a fragment shader. I want to be able to count the number of texels in each texture that are above some colour intensity.

How can this be done?

My initial thought is to count these texels using the fragment shader before generating the texture. However, this would require some sort of global counter. I can't use occlusion queries because the textures are created from other textures. I'm using OpenGL 2.1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愿得七秒忆 2024-09-04 20:22:51

感谢您的想法,
我找到了一个我认为最有效的简单方法。我最初认为遮挡查询只能与几何体一起使用,但它们也可以与纹理一起使用。

  1. 打开遮挡查询
  2. 使用片段着色器渲染图像并丢弃下面所需的纹素
    颜色强度
  3. 从查询中检索通过绘图测试的纹素数量

Thanks for the ideas,
I found a simple way I think is the most efficient. I initially thought occlusion queries could only be used with geometry but they can also be used with textures.

  1. Turn on occlusion queries
  2. Render the image using a fragment shader and discard texels below required
    color intensity
  3. Retrieve number of texels passing drawing test from query
℡寂寞咖啡 2024-09-04 20:22:51

您始终可以在帧缓冲区上运行像素着色器,将阈值以上的所有像素设置为白色,其余像素设置为黑色。然后抓取帧缓冲区的图片并计算白色像素的数量...

我假设您不需要每帧都执行此操作。如果是的话,您可能必须改变您的要求......

You could always run a pixel shader on the framebuffer that sets all pixels above the threshold to white and the rest to black. Then grab a picture of the framebuffer and count the number of white pixels...

I'm presuming that you are not going to need to do this every single frame. If you are, you probably going to have to change your requirements...

記憶穿過時間隧道 2024-09-04 20:22:51

我已经使用顶点和片段着色器完成了此操作。

我为纹理中的每个像素声明一个点顶点并渲染它们。

我声明了一个一维的离屏渲染纹理,长度是我想要的桶的数量。您可以制作这 1 个存储桶,但当每个片段等待写入同一像素时,它会减慢您的速度。我发现 32 通常对我来说效果很好。

将混合模式设置为加法。

在顶点着色器中,我通过桶的数量修改 gl_VertexID 并将该范围设置在 -1<->1 之间。

对每个顶点的纹理进行采样(实际上等于每个像素),并将有效像素的 gl_Color 设置为白色,将无效像素设置为黑色(基本上为 1 或 0)。

对 1D 纹理进行读回并对值求和。这将是像素数。

我过去完成的第二种方法是对与输入大小相同的屏幕外纹理进行第一次传递,并将输入分类为 1 或 0。接下来,渲染到宽度一半的纹理,高度和样本4次相加并写入。继续这样做,直到达到 1x1 并读回该值。

I've done this using a vertex and fragment shader.

I declare a point vertex for each pixel in the texture and render them.

I declare an offscreen render texture that is 1D and is the length of the number of buckets I want. You could make this 1 bucket but it will slow you down while each fragment is waiting to write to the same pixel. I've found 32 usually works pretty well for me.

Set the blend mode to additive.

In the vertex shader I mod gl_VertexID by the number of buckets and set that range between -1<->1.

Sample the texture for each vertex (which is really equal to each pixel) and set the gl_Color to white for valid pixel and black for not (basically 1 or 0).

Do a readback on the 1D texture and sum up the values. This will be the count of pixels.

A second way I've done it in the past is to do the first pass to an offscreen texture that is the same size as the input and classify the input as 1 or 0. Next, render to a texture that is half the width and height and sample 4 times add and write. Keep doing this until you get to a 1x1 and read the value back.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文