自定义 glBlendFunc 比原生慢很多

Posted

技术标签:

【中文标题】自定义 glBlendFunc 比原生慢很多【英文标题】:Custom glBlendFunc a lot slower than native 【发布时间】:2011-08-14 02:06:04 【问题描述】:

我正在尝试通过片段着色器执行我自己的自定义 glBlendFunc,但是,我的解决方案比本机 glBlendFunc 慢很多,即使它们执行精确的混合功能也是如此。

我想知道是否有人对如何以更有效的方式执行此操作有任何建议。

我的解决方案是这样的:

void draw(fbo fbos[2], render_item item)

   // fbos[0] is the render target
   // fbos[1] is the previous render target used to read "background" to blend against in shader
   // Both fbos have exactly the same content, however they need to be different since we can't both read and write to the same texture. The texture we render to needs to have the entire content since we might not draw geometry everywhere.

   fbos[0]->attach(); // Attach fbo
   fbos[1]->bind(1); // Bind as texture 1

   render(item);

   glCopyTexSubImage2D(...); // copy from fbos[0] to fbos[1], fbos[1] == fbos[0]
 

片段.glsl

vec4 blend_color(vec4 fore) 
   
    vec4 back = texture2D(background, gl_TexCoord[1].st); // background is read from texture "1"
    return vec4(mix(back.rgb, fore.rgb, fore.a), back.a + fore.a);  

【问题讨论】:

【参考方案1】:

提高基于 FBO 的混合性能的最佳选择是 NV_texture_barrier。尽管有这个名字,AMD 也实现了它,所以如果你坚持使用 Radeon HD 级显卡,它应该可供你使用。

基本上,它允许您在没有重量级操作(如 FBO 绑定或纹理附加操作)的情况下进行乒乓球比赛。规范的底部有一个部分显示了一般算法。

另一种选择是EXT_shader_image_load_store。这将需要 DX11/GL 4.x 类硬件。 OpenGL 4.2 最近通过ARB_shader_image_load_store 将其提升为核心。

即使这样,正如达西所说,你永远无法击败常规混合。它使用着色器无法访问的特殊硬件结构(因为它们发生在着色器运行之后)。仅当存在您绝对无法以任何其他方式完成的效果时,您才应该进行程序化混合。

【讨论】:

NV_texture_barrier 使我能够同时渲染和读取同一个纹理,对吗? @ronag:有点。最好阅读扩展规范,但它的一般要点是,只要您不在同一个地方这样做,您就可以读取和写入相同的纹理。并且你适当地使用了屏障。【参考方案2】:

它的效率要高得多,因为混合操作直接内置于 GPU 硬件中,因此您可能无法在速度上击败它。话虽如此,请确保您已关闭深度测试、背面剔除、硬件混合和任何其他不需要的操作。我不能说它会产生巨大的影响,但它可能会产生一些影响。

【讨论】:

以上是关于自定义 glBlendFunc 比原生慢很多的主要内容,如果未能解决你的问题,请参考以下文章

前端性能优化:jquery的each为什么比原生的for循环慢很多?

Android BLE为啥首次连接蓝牙设备比较慢

对于自定义 UITableViewCell 中的大图像,为啥 drawRect 滚动比 UIImageView 慢

RenderScript 自定义 ScriptC 比 Intrinsics 慢

物联网BLE应用程序开发 -- 实现一个自定义串口透传Profile文件

VBA宏运行速度为啥比Excel自带函数慢