PDA

View Full Version : How do best blending using GLSL



cmarty
10-11-2007, 12:33 AM
Helo.
I need to blend several layers (each layer with different type of blend function).
I think the best way is replace (extend) fixed OpenGL blending with some code using GLSL. What is the best way how to do it?
Is it possible to use render to texture (FBO) extension -
1. In first layer render to FBO texture0.
2. For second layers switch FBO texture0 to FBO texture 1 and previous FBO texture0 use in GLSL shader for blending.
3. For third layers switch FBO texture 1 to FBO texture 0 and previos FBO texture 0 use in GLSL shader for blending.
and so on for more layers.
For switching texture use glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
texTarget, tex_fb[0], 0);

Is these step the most effective way how to do user defined blending ?

Thanks for any info.

V-man
10-11-2007, 03:32 AM
That seems adequate. Right now you have single FBO, multiple texture. You will be doing your rendering and blending in stages.

Hampel
10-11-2007, 03:47 AM
Perhaps "multiple render targets" (MRT) could help to combine several blendings into one?

yalmar
10-11-2007, 09:36 AM
you need combine your multiple textures in a depth order, for that i believe is need to use some technique such as depht peeling. I have a simple GLSL example, but without MRT. You can send me a e-mail directly to me if you are interested.

cmarty
10-11-2007, 10:32 AM
I'm little bit afraid about speed of switching glFramebufferTexture2DEXT. Do you think that the speed of rendering will be similar like with fixed opengl blending ?

To Hampel: Can you give me a hint how can MRT help me ?

To yalmar: depth order seems no problem to me, becase before rendering each layer I clear depth buffer => layers are depth independent.

Korval
10-11-2007, 01:25 PM
Do you think that the speed of rendering will be similar like with fixed opengl blending ?Absolutely not. Nor should you expect it to.

You're basically running the entire rasterization pipeline multiple times. Fixed-function blending just takes two colors and combines them.

That's why you should only do this if you absolutely need to, and if you can spare the performance.

cmarty
10-11-2007, 10:12 PM
I thought that count of rasterization piple is the same.

This is pseudocode of rendering with fixed blendig

glEnable(GL_BLEND);
for (i=0; i != MAX_LAYER; i++) {

switch (layers[i].copy_mode) {
case COPY_MODE:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
break;
case ADDITION_MODE:
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
break;
case SUBTRACTION_MODE:
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
glBlendEquationSeparate(GL_FUNC_SUBTRACT, GL_FUNC_SUBTRACT);
break;
}
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,layers[i].texObj->texture);
.....
and pass a next layer data
glDrawElements(GL_TRIANGLES, pmesh->faces*3, GL_UNSIGNED_INT,layers[i].object3d.mMesh[k].facesL);
...
}


and the new code will be similar:
glDisable(GL_BLEND);
for (i=0; i != MAX_LAYER; i++) {

// switching appropriat texture to FBO with glFramebufferTexture2DEXT(...)
glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fbo_texture0);
layers[i].shader->setTextureUnit(1, fbo_texture0);

switch (layers[i].copy_mode) {
case COPY_MODE:
activate_shader_for_copy_blending;
break;
case ADDITION_MODE:
activate_shader_for_add_blending;
break;
case SUBTRACTION_MODE:
activate_shader_for_subtract_blending;
break;
}
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,layers[i].texObj->texture);
.....
and pass a next layer data
glDrawElements(GL_TRIANGLES, pmesh->faces*3, GL_UNSIGNED_INT,layers[i].object3d.mMesh[k].facesL);
...
}

Please can you give me info if I'm wrong ?

def
10-12-2007, 03:19 AM
If your "layers" are imageplanes that fit together, why not use as many textures in one shaderpass as possible (max 32) and gain performance by not rendering multiple passes?