Background: I’m using blending (GL_BLEND) to combine several signed luminance textures into a blended sum. Doesn’t sound like a big deal, except for the trick that they are signed (some texels of the texture add, while some subtract).
I have not found any good way to do this. My present attempt is to split each texture into two textures: one for positive texels and one for negative texels, and then I use glBlendEquation(GL_FUNC_ADD) and glBlendEquation(GL_FUNC_REVERSE_SUBTRACT), respectively.
The bad thing about this is that I use hundreds of textured quads (sort of like a particle system), which requires a huge number of state changes => slooooow (even on my GeForce 4).
Now, I suspect I can solve this with fragment programs or similar, but before I do that I would like to know if there is a “vanilla” way of doing it (portability is the key here).
Can’t you draw both textures at the same time bound to different texture units?
No, I can’t since I need to blend with all the previously rendered/blended textures (the sign must be applied in the blending stage - the texturing stage is too early).
Think of it as a normal billboarding/particle system, but I want to be able to both ADD to and SUBTRACT from the destination color buffer, not only add.
I don’t think this is directly possible, but you might get an almost similar result by storing the negative values in alpha and positive in intensity and then use the blending function GL_ONE, GL_SRC_ALPHA. That way the alpha channel would darken the destination color and the intensity would get added to it. But granted it’s not the equation you were looking for. For some situations, like detail textures, you might be able to use it anyways.
Thanks. I worked around it a bit by first drawing all the positive textures, then the negative ones. That way I only need two state changes per frame, which is much faster. The only problem is that I may need to decrease the dynamic range since alot of positive values get added together, potentialy being clamped, before the negative values are added.
I wonder why there is no GL_ADD_SIGNED, as with multi texturing (A + B - 0.5), which would have been ideal in this case.