组合多个 opengl 片段着色器

发布于 2024-10-24 11:30:38 字数 338 浏览 3 评论 0原文

我想将一些图像处理工作移植到 OpenGL,以使用 OpenGL ES 提高性能。我已经有了一个非常简单的阈值算法,但我想将其他过滤器组合到图像中(例如对比度)。

我的第一个想法是通过使用多个片段着色器来完成此任务。然而,我想很快地做到这一点,那么这会导致很多状态变化吗?我读过的唯一方法是通过处理纹理然后多次调用“使用程序”来实现此目的。

有没有更有效的方法来做到这一点?理想情况下,我希望执行对比度拉伸和直方图平衡作为步骤的一部分。

除非我可以将其合并到单个着色器中,否则 FBO 是否适合我?

我对 OpenGL 有点陌生(以防万一你看不出来)。

谢谢!

西蒙

I'm wanting to port some image processing work to OpenGL for performance using OpenGL ES. I've got a very simple thresholding algorithm in place but I'd like to combine additional filters to the image (such as contrast).

My first thought would be to complete this by using multiple fragment shaders. However, I'd like to do this pretty quickly so would this cause a lot of state change? The only method I've read about is to do this by working on a texture and then calling 'use program' multiple times.

Is there a more efficient way to do this? Ideally, I'd like to perform a contrast stretch and a histogram balance as part of the steps.

Unless I can combine this into a single shader would an FBO work for me here?

I'm a bit new to OpenGL (in case you couldn't tell).

Thanks!

Simon

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

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

发布评论

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

评论(2

橙幽之幻 2024-10-31 11:30:38

除非手动执行,否则无法“合并”片段着色器,因此唯一明智的选择是使用 FBO 进行“乒乓”渲染。您有 2 个 FBO,绘制到一个并从另一个读取,然后切换 FBO 并重复,在渲染之间切换片段着色器。

You can't "merge" fragment shader unless you do it manually, so the only sane choice is to do "ping-pong" rendering using FBOs. You have 2 FBOs, draw to one and read from another, then switch FBOs and repeat, switching fragment shaders between rendering.

呆头 2024-10-31 11:30:38

实际上,乒乓球渲染非常适合此目的!这是在 LibGDX 中工作的代码示例,其中有一个实际上绘制到屏幕的“批处理”对象,我们可以使用 FrameBuffers 捕获输入:

FrameBuffer ping = fbo; // the framebuffer containing your rendered texture
for (ShaderProgram shader : shaders) {
    pong.clear();
    pong.begin();
    batch.begin();
    batch.setShader(shader);
    batch.draw(ping.getColorBufferTexture(), 0, 0, width, height);
    batch.end();
    pong.end();
    ping = pong;
}
batch.begin();
batch.draw(pong.getColorBufferTexture(), 0, 0, width, height);
batch.end();

对 pong 的明确调用(在我的例子中,创建一个新的帧缓冲区)是昂贵,因此预分配可能会带来一些加速。这更多的是马蒂亚斯答案的后续,而不是答案本身,但不适合评论。

Ping pong rendering is quite nice for this purpose, actually! Here's a code sample that works within LibGDX, where there is a 'batch' object that actually draws to the screen, the input to which we can capture with FrameBuffers:

FrameBuffer ping = fbo; // the framebuffer containing your rendered texture
for (ShaderProgram shader : shaders) {
    pong.clear();
    pong.begin();
    batch.begin();
    batch.setShader(shader);
    batch.draw(ping.getColorBufferTexture(), 0, 0, width, height);
    batch.end();
    pong.end();
    ping = pong;
}
batch.begin();
batch.draw(pong.getColorBufferTexture(), 0, 0, width, height);
batch.end();

The clear call to pong (in my case, making a new framebuffer) is expensive, so preallocating might offer some speedups. This is more of a followup to Matias' answer than an answer in itself, but wouldn't fit in a comment.

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