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: velvetkevorkian.wordpress.com
 */

import processing.opengl.*;
import javax.media.opengl.*; //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);
  background(0);
  cam= new PeasyCam(this, 250);
  img= loadImage("vg.jpg");
  results= new float[img.pixels.length][3];
  analyse();
}

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.glEnable(GL.GL_BLEND);
  gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); //additive blending
  pgl.endGL();

  if (rgb) {
    colorMode(RGB, 255);
  }
  else {
    colorMode(HSB, 255);
  }
  if (updateBackground) {
    background(0);
  }
  cam.rotateY(radians(1));
  pushMatrix();
  translate(-128, -128, -128);


  /*
  //draw a bounding box
   pushMatrix();
   translate(128, 128, 128);
   stroke(200, 100);
   noFill();
   box(256);
   popMatrix();
   */

  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]);
  }
  popMatrix();
  if (record) {
    saveFrame(frameCount+".png");
  }
}

void analyse() {
  img.loadPixels();
  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][1]=b;
    results[i][2]= c;
  }
}

void keyPressed() {
  if (key=='c') { //toggle between RGB and HSB analysis
    rgb=!rgb;
    analyse();
  }
  else if (key=='b') { //toggle background clearing
    updateBackground= !updateBackground;
    background(0);
  }
  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!

Advertisements
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:

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s