Shiny: Additive blending with OpenGL in Processing

This sketch was inspired by a combination of things: the particle systems chapter draft from Dan Shiffman’s forthcoming Nature Of Code book influenced the additive blending aesthetic, while I got the idea of a three dimensional “colour space” from this talk from Mario Klingemann.

All that’s really going on here is the RGB/HSB values of each pixel of an image are mapped to XYZ coordinates, while the camera rotates round the centre point. Changing the mode from RGB to HSB creates a different shape from the same collection of pixels, while the low opacity and OpenGL blending create a nice glowing effect. It’s interesting to see the connections between shades in an image- almost always a continuous spectrum without large gaps.

This runs a bit slowly, just because of the number of pixels having to be drawn each frame. I’d like to try it with a film and see whether the character of the movement on screen comes through…

In the spirit of sharing, here’s the code- pretty straightforward, mostly…

3d Picture Particles with additive blending
 Kyle Macquarrie:

import processing.opengl.*;
import*; //extra import needed for additive blending
import peasy.*;

PGraphicsOpenGL pgl;
GL gl;

PImage img;
PeasyCam cam;
float[][] results;
boolean rgb=true;
boolean updateBackground= true;
boolean record= false;

void setup() {
  size(1280, 720, OPENGL);
  cam= new PeasyCam(this, 250);
  img= loadImage("vg.jpg");
  results= new float[img.pixels.length][3];

void draw() {
  //set up the OpenGL blending
  PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;  // g may change
  GL gl = pgl.beginGL();  // always use the GL object returned by beginGL
  gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); //additive blending

  if (rgb) {
    colorMode(RGB, 255);
  else {
    colorMode(HSB, 255);
  if (updateBackground) {
  translate(-128, -128, -128);

  //draw a bounding box
   translate(128, 128, 128);
   stroke(200, 100);

  for (int i=0; i<img.pixels.length; i++) {
    if (updateBackground) { //higher alpha if canvas being cleared
      stroke(results[i][0], results[i][1], results[i][2], 175);
    else { //low alpha for a nice fuzzy blend
      stroke(results[i][0], results[i][1], results[i][2], 15);
    point(results[i][0], results[i][1], results[i][2]);
  if (record) {

void analyse() {
  for (int i=0; i<img.pixels.length; i++) {
    float a, b, c;
    if (rgb) {
      a= red(img.pixels[i]);
      b= green(img.pixels[i]);
      c= blue(img.pixels[i]);
    else {
      a= hue(img.pixels[i]);
      b= saturation(img.pixels[i]);
      c= brightness(img.pixels[i]);
    results[i][0]= a;
    results[i][2]= c;

void keyPressed() {
  if (key=='c') { //toggle between RGB and HSB analysis
  else if (key=='b') { //toggle background clearing
    updateBackground= !updateBackground;
  else if (key=='r') {
    record=!record; //record a sequence of frames
  else if (key=='s') {
    saveFrame(frameCount+".png"); //capture a single frame

That’s all for now, but I have some more adventures in additive blending particles systems to show soon.
Have fun!

This entry was posted in code, processing, Video and tagged , , . Bookmark the permalink.

One Response to Shiny: Additive blending with OpenGL in Processing

  1. Bob Kaze says:

    Hey Kyle,

    Really enjoyable and done very well. Carry on, you are really doing great!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s