我正试着通过片段着色器做我自己的自定义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]
} fragment.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);
}发布于 2011-08-14 11:00:04
要提高基于FBO的混合的性能,最好的选择是NV_texture_barrier。尽管名字是AMD,但AMD也实现了它,所以如果你坚持使用Radeon HD级卡,它应该是可用的。
基本上,它允许您在没有重量级操作的情况下进行乒乓操作,如FBO绑定或纹理附加操作。该规范有一个接近底部的部分,显示了通用算法。
另一种选择是EXT_shader_image_load_store。这将需要DX11/GL 4.x类硬件。OpenGL 4.2最近通过ARB_shader_image_load_store将其提升到了核心。
即使这样,正如达西所说,你也永远不会击败常规的混合。它使用着色器无法访问的特殊硬件结构(因为它们发生在着色器运行之后)。只有在某些效果是你绝对不能用其他任何方式实现的情况下,你才应该进行程序化混合。
发布于 2011-08-14 10:44:21
它的效率要高得多,因为混合操作是直接内置到GPU硬件中的,所以你可能无法在速度上击败它。话虽如此,请确保您关闭了深度测试、背面剔除、硬件混合和任何其他不必要的操作。我不能说这会有很大的不同,但它可能会产生一些影响。
https://stackoverflow.com/questions/7054538
复制相似问题