Reputation: 11639
I'd like to have this kind of effect with OpenGL: http://www.escapemotions.com/experiments/flame/#top
There is an additive blending which seem to add brightness values: addition of red color gives white color.
(255,0,0) + (200,0,0) -> (255,100,100)
I could implement this using GLSL (converting the two colors into HSV space, adding the values, and ceverting back), but I'm wondering if there is a better way.
The flame painter is made with Processing (which I don't know well since I use openframeworks), how the effect is computed in Processing ?
Upvotes: 1
Views: 956
Reputation: 36
Peter, the Flame Painter programmer here.
The lighten mode in Flame Painter is similar to Photoshop ADD blending mode, I am adding a small amount of color into all RGB channels.
Example (pseudocode):
color: C = (50, 20, 10) // RGB channels = 50, 20, 10
lighter color: C = C + C // RGB channels = 100, 40, 20
lighter color: C = C + C // RGB channels = 150, 60, 30
...
add the colors till it the color C became white. (255, 255, 255)
This method does not work if the color is pure red, blue, green, purple, yellow or magenta. Example for red color:
color: C = (50, 0, 0) // RGB channels = 50, 0, 0
lighter color: C = C + C // RGB channels = 100, 0, 0
lighter color: C = C + C // RGB channels = 150, 0, 0
...
the brightest color will be red. (255, 0, 0)
that's why I add a small amount (1 pigment) to channels where the default color is 0. Example:
color: C = (50, 1, 1) // RGB channels = 50, 1, 1
lighter color: C = C + C // RGB channels = 100, 2, 2
lighter color: C = C + C // RGB channels = 150, 3, 3
...
and the brightest color will be white again. (255, 255, 255)
Upvotes: 2
Reputation: 26303
Blend modes are implemented as part of the Processing API: http://processing.org/reference/blendMode_.html
Internally, this uses GL if the renderer is a GL renderer (glBlendFunc(GL_SRC_ALPHA, GL_ONE)
), otherwise it uses the same math GL uses:
private static int blend_add_pin(int a, int b) {
int f = (b & ALPHA_MASK) >>> 24;
return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 |
low(((a & RED_MASK) + ((b & RED_MASK) >> 8) * f), RED_MASK) & RED_MASK |
low(((a & GREEN_MASK) + ((b & GREEN_MASK) >> 8) * f), GREEN_MASK) & GREEN_MASK |
low((a & BLUE_MASK) + (((b & BLUE_MASK) * f) >> 8), BLUE_MASK));
}
(from PImage.java)
As to "if there is a better way", the nice thing about using GL is that it happens on the GPU rather than the CPU. So, doing the math yourself as demonstrated above will be slower than letting the GL blend mode supported by your graphics card do its magic.
Upvotes: 1