[英]How to blend many textures/buffers into one texture/buffer in OpenGL?
我有一个包含MNIST数据集的大缓冲区(对象):许多(数万)小(28x28)灰度图像,按行顺序逐一存储为表示像素强度的float
。 我想有效地(即有点交互地)将这些许多图像混合成一个“平均”图像,其中混合图像中的每个像素都是同一位置的所有像素的平均值。 这可能吗?
我考虑的选项是:
直接在缓冲区对象上使用计算着色器。 我会生成imgWidth * imgHeight
计算着色器调用/线程,每个调用循环遍历所有图像。 这似乎不是很有效,因为每次调用都必须遍历所有图像,但是以另一种方式(即产生numImages
调用并遍历像素)仍然有调用彼此等待。
使用图形管道将纹理一个接一个地绘制到帧缓冲区,将它们相互混合。 这仍然会导致线性时间,因为每个图像都必须依次渲染到帧缓冲区。 不过,我对帧缓冲区不是很熟悉。
在 CPU 中线性地完成这一切,这似乎比在 GPU 上更容易,而且速度也不慢。 我只会错过像素的并行处理。
我错过了他们的其他可能性。 有没有最优的方法? 如果不是,您认为最简单的方法是什么?
我就是这样做的。
将所有纹理渲染到 framebuffer ,它也可以是默认的帧缓冲区。
一旦渲染完成。
从帧缓冲区读取数据。
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[w_writeIndex]);
// copy from framebuffer to PBO asynchronously. it will be ready in the NEXT frame
glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
// now read other PBO which should be already in CPU memory
glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[w_readIndex]);
unsigned char* Data = (unsigned char*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
大多数时候,我们希望在像素级别进行并行化,因为有很多。
但是,在您的情况下,像素(28x28)并不多。
您拥有的最大数量似乎是图像的数量(数千张图像)。 所以我们想利用这一点。
使用计算着色器,您可以成对混合图像,而不是遍历所有图像。 每次通过后,您将图像数量减半。 一旦图像的数量变得非常少,您可能想要更改策略,但您需要进行试验以查看最有效的方法。
你知道计算着色器可以有 3 个维度。 您可以让X
和Y
索引图像的像素。 Z
可用于将这对图像嵌入纹理数组中。 因此,对于索引Z
,您将混合纹理2*Z
和2*Z+1
。
您需要考虑的一些实现细节:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.