I'm implementing a new version of my plugins using OpenGL for proxy display, and I've run up against a roadblock I'm having some trouble getting around...
My plugins add lighting effects, and I've coded them use "Screen" mixing in the final rendering. This is much like what happens in Photoshop proper using "Screen" layer mixing mode.
The key here is that light is only added, so a partially transparent effect over the top of the image only LIGHTENS the image, but no matter how bright the image or the effect, the result only approaches 1.0 (max white) and does not exceed it.
Basically the math for the desired "Screen" mixing is the following (where Alpha is Opacity of the effect being added):
ResultColor = ( (1 - Alpha ) * ExistingColor ) + ( Alpha * (1 - (1 - NewColor) * (1 - ExistingColor)) )
Visually, this is the desired effect:
.
My problem is, OpenGL doesn't seem to offer enough programmability in the mixing stage to allow me to emulate "Screen" mixing. The closest I seem to be able to get in OpenGL is one of these two functions:
This (similar to blend mode "Normal" in Photoshop), which shows dimming:
ResultColor = ( (1 - Alpha ) * ExistingColor ) + ( Alpha * NewColor )
or the following (similar to blend mode "Add" in Photoshop), which shows white-out:
ResultColor = ExistingColor + ( Alpha * NewColor )
Unfortunately, as you can see (if you look closely) the former dims the brightest part of the highlight if a color dimmer than the existing color is applied, and the latter, while only lightening the image, can generate a result as high as 2.0 (where white is 1.0). The visual result of this is white-out.
Do you know of any way to reprogram the alpha blending stage to accomplish the more complex desired "Screen" blending algorithm?
-Noel