arthur.sw
arthur.sw

Reputation: 11639

OpenGL HSV additive blending

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

Answers (2)

user3507393
user3507393

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

ericsoco
ericsoco

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

Related Questions