Glitch Art and Shaders

posted by on 2017.02.11, under Processing
11:

It’s been a while since the last post. I have been busy with (finally!) starting to set up a website to collect some of my works, and I’ve been more or less finishing a couple of interactive installations. For this reason, interactivity and real-time processing have captured my attention recently. It turns out that when you want to interact with a piece of code which produces graphics, and as soon as what you are doing involves more than just a couple of pairs of colored circles, you run quickly into performance issues. So, unless you are one of those digital artists drawing a blinking white circle in the middle of the screen and call it art (it’s fine, don’t worry, go on with it), you need to find your way around these types of issues. In practice, this amounts to get comfortable with words like Vertex Buffer Object, C++, and shaders, to which this post is dedicated.
The story goes like this: modern graphic cards (GPU) have a language they use, called GLSL . For instance, when in Processing you draw a line or a circle, what is actually happening behind the curtains is a communication between the CPU and the graphic card: Processing informs the GPU about the vertices of the line, the fact that it has to be line, the color of the vertices, etc. There are several stages from when the vertices are comunicated to the final result that you see on your screen. Some of these stages are user programmable, and the little programs that take care of each of these stages are called “shaders”. Shaders are notoriously difficult to work with: you have to program them in C, basically, and they are quite unforgiving with respect to errors in the code. On the other hand, they are really really fast. If you want to know why it is so, and how a (fragment) shader operates, give a look here.
So, why the hell would you want to learn such a tool? Well, if you, like me, are fond of glitch art, you must have realized that interactive real-time glitch art is almost impossible if you try to work pixel by pixel: even at a resolution of 800×600, the amount of computations for the CPU to get a framerate of 30fps is impractical. Enter fragment shaders! If you delegate the work to the GPU, it becomes more than doable.
I can’t go into the detail of the code I present in the following, but there are very good tutorials on the web that slowly teach you how to tame shaders. In particular, give a look here. Rest assured: you really need to be programming friendly, and have a lot of patience to work with shaders!

PImage img;
PShader glitch;


void setup(){
  size(800, 600, P2D);
  background(0);
  img = loadImage(insert_link_to_image);
  img.resize(800, 600);
 
 
  glitch = loadShader("glitchFrag.glsl");
  glitch.set("iResolution", new PVector(800., 600., 0.0) );
 
}

 
}

void draw(){
 
  glitch.set("iGlobalTime", random(0, 60.0));
 
   if (random(0.0, 1.0) < 0.4){
  shader(glitch);
   }
 
  image(img, 0, 0);
 
  resetShader();
 
}

---------------

// glitchFrag.glsl

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif


#define PROCESSING_TEXTURE_SHADER

varying vec4 vertTexCoord;
uniform sampler2D texture;
uniform vec3      iResolution;          
uniform float     iGlobalTime;          



float rand(vec2 co){
    return fract(cos(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}


void main(){
   vec3 uv = vec3(0.0);
   vec2 uv2 = vec2(0.0);
   vec2 nuv = gl_FragCoord.xy / iResolution.xy;
   vec3 texColor = vec3(0.0);

   if (rand(vec2(iGlobalTime)) < 0.7){
    texColor = texture2D(texture, vertTexCoord.st).rgb;
}
 else{
   texColor = texture2D(texture, nuv * vec2(rand(vec2(iGlobalTime)), rand(vec2(iGlobalTime * 0.99)))).rgb;
}
       
    float r = rand(vec2(iGlobalTime * 0.001));
    float r2 = rand(vec2(iGlobalTime * 0.1));
    if (nuv.y > rand(vec2(r2)) && nuv.y < r2 + rand(vec2(0.05 * iGlobalTime))){
    if (r < rand(vec2(iGlobalTime * 0.01))){
       
   if ((texColor.b + texColor.g + texColor.b)/3.0 < r * rand(vec2(0.4, 0.5)) * 2.0){
       
        uv.r -= sin(nuv.x * r * 0.1 * iGlobalTime ) * r * 7000.;
        uv.g += sin(vertTexCoord.y * vertTexCoord.x/2 * 0.006 * iGlobalTime) * r * 10 *rand(vec2(iGlobalTime * 0.1)) ;
        uv.b -= sin(nuv.y * nuv.x * 0.5 * iGlobalTime) * sin(nuv.y * nuv.x * 0.1) * r *  20. ;
        uv2 += vec2(sin(nuv.x * r * 0.1 * iGlobalTime ) * r );
   
}
       
    }
}

  texColor = texture2D(texture, vertTexCoord.st + uv2).rgb;
  texColor += uv;
   gl_FragColor = vec4(texColor, 1.0);  
   
}

In the following, you can see the result applied to a famous painting by Caravaggio (yes, I love Caravaggio): it matches real time framerate.
If you want to apply the shader to the webcam, you just need to set up a Capture object, called, say, cam, and substitute img with cam in the Processing code. Enjoy some glitching! :)

Glitch Shader from kimri on Vimeo.

n-grams, Markov chains and text generators

posted by on 2016.11.03, under Processing, Supercollider
03:

An n-gram is a contiguous sequence of n elements of a text, where each element can be a phoneme, a syllable, a character, a word, etc. Given a text, the collection of its n-grams allows to infer some statistical correlation, and moreover to assemble the n-grams collected into a Markov chain . Right, what’s a Markov chain, then? A Markov chain describes a process in which the next step depends probabilistically only on the current step. For instance, a random walk is an example of a Markovian process. One way to assign a Markov chain to a text is to collect all its n-grams, and for each n-gram we keep track of the next n-gram. We then go through the collection of all the n-grams, and for each of them we choose randomly among the list of the subsequent n-grams. We form then the new n-gram, and proceed. Confusing? Let’s see an example. Suppose we have the text “this is a book and this is my pen”, and suppose we are interested in 2-grams, where a single gram is a word. We have then then the pair (This, is), the pair (is, a), etc. Then, we keep track of all the 1-grams which follow a single 2-gram: for instance, after (this, is) we can have (a) or (my), and we assign to each of them an equal probability. Suppose we start from (This, is): if we happen to choose (a), we form the pair (is, a), to which it must follow (a, book), and so on, until we reach the end of the text. In this way, we can generate a text which has similar statistical distribution of n-grams, in this case pairs of words. The greater n, the closer your generated text will be to the original one.
Inspired by this, I have written a code in p5.js, a set of libraries for Javascript, that generates text starting from n-grams in words. Here “word” only means “groups of characters separated by a whitespace”. Punctuation is not considered from the grammatical point of view, nor the role of articles, nouns, etc. are analysed; neverthless, the results are still quite interesting. The choice of Javascript is dictated by the fact that Processing/Java is not very friendly with dictionaries, and in this case they are really useful.
Here’s the code

var words;
var ngrams = {}
var order = 2;
var txt = "";
var a = 0.1;
var target = 255;

function setup() {
  createCanvas(600, 600);

  words = source.split(" ");

  for (var i = 0; i < words.length - order; i++){
    gram_temp = [];
    for (var j = 0; j < order; j++){
    gram_temp.push(words[i + j]);
      }
      gram = join(gram_temp," ");
      if (!ngrams[gram]){
     ngrams[gram] = [];
    }
      if (i < words.length - order){
     ngrams[gram].push(words[i + order])   
  }
}
  markovIt(ngrams);
  txt = spText(txt);
}

function draw() {
    background(255);
    a += (target - a) * 0.1;
    textSize(12);
        fill(0, a);
    textDisplay(txt);
    if (a  < 0.099 ){
     restart();
     }
}

function restart(){
    markovIt(ngrams);
    txt = spText(txt);
    a = 0;
    target = 255;
}


function textDisplay(ttext){
    textAlign(CENTER);
    text(ttext, 100, 60, width - 100, height - 60);
}

function spText(txt){
    return txt.split(".");
}

function mousePressed(){
   target = 0;
}

function markovIt(ngrams) {
    var index = int(random(0, words.length - order + 1));
    curr_temp = [];
    for (var j = 0; j < order; j++){
     curr_temp.push(words[index + j]);
      }
      current = join(curr_temp, " ");
      result = current;
      if (!ngrams[current]){
        return null;
    }
      var range = int(random(30, 500));
      for (var i = 0; i < range; i++){
        if (!ngrams[current]){
        break;
          }
        possibilities = ngrams[current];
        if (possibilities.length == 0){
          break;
        }
        next = possibilities[int(random(0, possibilities.length))];
        result = result + " " + next;
        tokens = result.split(" ");
        curr_temp = [];
        for (var j = order; j > 0; j--){
        curr_temp.push(tokens[tokens.length - j]);
    }
         current = join(curr_temp, " ");
         }
    txt = result;
   
}

Notice that you need to declare a variable source, which should contain the input text.
As a little homage to Noam Chomsky, a pioneer of grammar studies (and much more), here you can find a working version of the code above using 2-grams in words, and based on this. Click on the canvas to generate some new text.

OSC messaging, Processing and SuperCollider

posted by on 2016.10.15, under Supercollider
15:

OSC stands for Open Sound Control, and consists in a protocol for networking between computers, synths and various multimedia devices. For instance, it allows a software, like Ableton Live, say, to communicate with a hardware synth, whenever the latter supports OSC. You might think that you already now how to do this via MIDI, and you’d be partially right. The differences between OSC and MIDI are many: accuracy, robustness, etc. One of the most important, or rather most useful difference, though, is that OSC allows to send *any* type of messages at high resolution to any address. Differently, the MIDI protocol has its own specific messages, like note On, not Off, pitch, etc., with low resolution (0-127). This means that if you use MIDI to communicate between devices, you’ll be required to translate your original message, say for instance the position of a particle or the color of a pixel at mouse point, via the standard MIDI messages. And this is often not enough. An example is usually better than many principled objections, so here comes a little Processing sketch communicating to SuperCollider. The idea is quite simple: in the Processing sketch, systems of particles are spawned randomly, with the particles having a color, a halflife, and also a tag. The user can click on the screen and generate a circle. If a particle traverses one of the circles, it will tell SuperCollider to generate a synth, and it will pass by various information, like its position, velocity, color, etc. This data will affect the synth created in SuperCollider. Here’s the Processing code, which uses the library oscP5

//// Setup for OscP5;

import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress Supercollider;

//// Setting up the particle systems and the main counter;


ArrayList<Parsys> systems;
ArrayList<Part> circles;
int count = 0;

void setup(){
  size(800, 800);
  background(255);
  oscP5 = new OscP5(this,12000);
  Supercollider = new NetAddress("127.0.0.1", 57120);
 
  systems = new ArrayList<Parsys>();
  circles = new ArrayList<Part>();
 
}

void draw(){
  background(255);
  for (int i = systems.size() - 1; i>=0; i--){
    Parsys sys = systems.get(i);
    sys.update();
    sys.show();
    if (sys.isDead()){
      systems.remove(i);
    }
    for (int j = 0; j < circles.size(); j++){
      Part circ = circles.get(j);
      sys.interact(circ);
    }
  }
 
  for (int i = 0; i < circles.size(); i++){
    Part circ = circles.get(i);
    circ.show();
  }
  if (random(0, 1) < 0.04){
    Parsys p = new Parsys(random(0, width), random(0, height));
    systems.add(p);
  }
}

void mousePressed(){
  Part circ = new Part(mouseX, mouseY, 0, 0, 0, 30);
  circ.stuck = true;
  circ.halflife = 80;
  circles.add(circ);
}

/////Define the class Parsys

class Parsys {
  ArrayList<Part> particles;
 
  Parsys(float x, float y){
    particles = new ArrayList<Part>();
   
    int n = int(random(20, 80));
    for (int i = 0; i < n; i++){
      float theta = random(0, 2 * PI);
      float r = random(0.1, 1.2);
      Part p = new Part(x, y, r * cos(theta), r * sin(theta), int(random(0, 3)));
      p.tag = count;
      count++;
      particles.add(p);
    }
  }
 
  void update(){
    for (int i =  particles.size() - 1; i>=0; i--){
      Part p = particles.get(i);
      p.move();
      if (p.isDead()){
        particles.remove(i);
      }
    }
  }
 
  void show(){
    for (int i =  particles.size() - 1; i>=0; i--){
      Part p = particles.get(i);
      p.show();
    }
  }
 
  boolean isDead(){
    if (particles.size() <=0){
      return true;
    }
    else return false;
  }
 
  void interact(Part other){
    for (int i = 0; i < particles.size(); i++){
      Part p = particles.get(i);
      if (p.interacting(other)){
        float dist = (p.pos.x - other.pos.x)* (p.pos.x - other.pos.x) + (p.pos.y - other.pos.y)*(p.pos.y - other.pos.y);
        if (!p.active){
          float start = other.pos.x/width;
        p.makeSynth(start, dist/(other.rad * other.rad));
        p.active = true;
        }
        else {
          p.sendMessage(dist/(other.rad * other.rad));
        }
      }
      else
      {
        p.active = false;
      }
    }
  }
}

/////Define the class Part

class Part {
  PVector pos;
  PVector vel;
  int halflife = 200;
  int col;
  float rad = 2;
  boolean stuck = false;
  boolean active = false;
  int tag;

  Part(float x, float y, int _col) {
    pos = new PVector(x, y);
    col = _col;
  }

  Part(float x, float y, float vx, float vy, int _col) {
    pos = new PVector(x, y);
    vel = new PVector(vx, vy);
    col = _col;
  }

  Part(float x, float y, float vx, float vy, int _col, float _rad) {
    pos = new PVector(x, y);
    vel = new PVector(vx, vy);
    rad = _rad;
  }

  void move() {
    if (!stuck) {
      pos.add(vel);
      halflife--;
    }
  }

  void show() {
    noStroke();
    fill(255 / 2 * col, 255, 100, halflife);
    ellipse(pos.x, pos.y, rad * 2, rad * 2);
  }

  boolean isDead() {
    if (halflife < 0) {
      active = false;
      return true;
    } else return false;
  }

  boolean interacting(Part other) {
    if (dist(pos.x, pos.y, other.pos.x, other.pos.y) < rad + other.rad) {
      return true;
    } else return false;
  }

  void makeSynth(float start, float dist) {
      OscMessage message = new OscMessage("/makesynth");
      message.add(col);
      message.add(vel.x);
      message.add(vel.y);
      message.add(start);
      message.add(dist);
      message.add(tag);
      oscP5.send(message, Supercollider);
    }
   
    void sendMessage(float dist){
    OscMessage control = new OscMessage("/control");
    control.add(tag);
    control.add(dist);
    oscP5.send(control, Supercollider);
  }
}

Notice that the messaging happens in the functions makeSynth() and sendMessage() in the class Part. The OSC message is formed in the following way: first there is its symbolic name, like “/makesynth”, and then we add the various information we want to send. These can be integers, floats, strings, etc. The symbolic name allows the “listening” media device, in this case SuperCollider, to perform an action whenever the message with the specific symbolic name arrives. You need to specify an address where to send the message: in my case, I used the default incoming SuperCollider address. Here is the code on the SuperCollider side

s.boot;

(

fork{
SynthDef(\buff, {|freq = 10, dur = 10, gate = 1, buff, rate = 1, pos = 0, pan = 0, out = 0, spr|
    var trig = Impulse.ar(freq);
    var spread = TRand.ar((-1) * spr * 0.5, spr * 0.5, trig);
    var sig = GrainBuf.ar(2, trig, dur, buff, rate, pos + spread + spr, 0, pan);
        var env = EnvGen.kr(Env([0.0, 1, 1, 0], [Rand(0.05, 0.8), Rand(0.1, 0.4), Rand(0.01, 0.5)]), doneAction: 2);
    Out.ar(out, sig * env * 0.02 );
}).add;

SynthDef(\rev, {|out, in|
    var sig = In.ar(in, 2);
    sig = FreeVerb.ar(Limiter.ar(sig), 0.1, 0.5, 0.1);
    Out.ar(0, sig);
    }
).add;

~rev = Bus.audio(s, 2);
s.sync;
Synth(\rev, [\in: ~rev]);

~synths = Dictionary.new;


~buffers =  "pathFolder/*".pathMatch.collect({|file| Buffer.readChannel(s, file, channels:0)});

~total = 0;

OSCdef(\makesynth, {|msg|
    //msg.postln;
    if(~total < 60, {
        x = Synth(\buff, [\freq: rrand(0.1, 40), \dur: rrand(0.01, 0.5), \buff: ~buffers[msg[1]], \rate: msg[3] * rrand(-3, 3), \pan: msg[2], \pos: msg[4], \spr: msg[5], \out: ~rev]);
        ~synths.put(msg[6], x);
        x.onFree({~total = ~total - 1; ~synths.removeAt(msg[6]);});
        ~total = ~total + 1;
        //~total.postln;
    }, {});
}, "/makesynth");

 OSCdef(\control, {|msg|
    ~synths[msg[1]].set(\freq2, msg[2]);
 }, "/control");

}
)

The listening is performed by OSCdef(name, {function}, symbolic name), which passes as argument to the function the message we have sent via Processing. Notice that the first entry of the array msg will always be the symbolic name of the message. Pretty simple, uh? Neverthless, the SuperCollider code has some nuances that should be explained. First, the synth you create should better be erased when it finishes its job, otherwise you’ll have an accumulation of them which will eventually freeze your computer. Also, I’ve put a cap on the total number of synth which I allow at a given time, to avoid performances issues. We also want to be able to control various parameters of a given synth while the particle that generated it is still inside one of the circles. To do this, we have to keep track of the various synths which are active at a given moment. I’ve done this by “tagging” each new created particle with an integer, and by using the Dictionary variable ~synths. Recall that a Dictionary is a collection of data of the form [key, value, key, value,…]: you can retrieve the given value, in this case a synth node, via the associated key, in this case the particle tag. When the given synth node is freed, via the method onFree() we decrease the total number of active synths, and remove the key corresponding to the particle tag.
I hope the example above shows how powerful OSC communication is, and how nuanced one can be in the resulting actions performed.
Here it is an audio snippet.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Non-Real Time Analysis and Rendering

posted by on 2016.08.01, under Processing
01:

This is a “utility” post dealing with Non-Real Time analysis, which I hope can help someone who has struggled with this issues before.
Here’s the setting. You have a nice sketch in Processing which reacts to an external input, say music or mouse position, and want to render it to show the world how fun and joyful the time spent while coding might be. You then realize that using the function saveFrame() creates problems: each single frame takes too long to save to disk, and everything goes horribly out of sync. In this case it is convenient to have a sketch that retrieves the data needed frame by frame, say the frequency spectrum of a piece of audio. One can later load this data, and render it via saveFrame(), knowing that when the frames are reassembled at the prescribed framerate, everything will be in sync.
The following code does exactly that. It uses a class called Saver, which in this case keeps track of the frequency spectrum. Under the more than reasonable assumption that the Fast Fourier Transform done by the Minim library is computed in less than 1/30 of seconds, the data you’ll retrieve for each frame will be in sync with the audio. Then you can go to your sketch which visualizes this data, load the value saved in the .txt file, and use it anywhere you would use the array of frequencies, say. It should be immediate to adapt the piece of code to your need. To save to disk you have to press any key

import ddf.minim.*;
import ddf.minim.analysis.*;

Minim minim;
AudioPlayer song;
FFT fft;

String songPath = "InsertPathToSongHere";

Saver mySaver;

boolean saved = false;
boolean pressed = false;

void setup() {
  size(200, 200);
  background(0);

  minim = new Minim(this);
  song = minim.loadFile(songPath, 1024);

  frameRate(30);

  song.play();

  fft = new FFT(song.bufferSize(), song.sampleRate());
  mySaver = new Saver(fft.specSize(), "data/analysis.txt");
 
}

void draw() {
  background(0);

  fft.forward(song.mix);

  for (int i = 0; i < fft.specSize(); i++) {
   float a = fft.getBand(i);
   mySaver.setElement(a);
  }

  mySaver.update();

  if (pressed & !saved) {
    mySaver.write();
    saved = true;
  }
}

void keyPressed() {
  pressed = true;
}

//Define the Saver class

class Saver {

  int buffSize;
  String pathTosave;
  ArrayList data;
  int arraylength;

  Saver(int _buffSize, String _pathTosave) {

    buffSize = _buffSize;
    pathTosave = _pathTosave;
    arraylength = 0;  
    data = new ArrayList();
 
  }

  void setElement(float a) {
    data.add(a);
  }

  void update() {
    arraylength++;
  }

  void write() {
    String[] dataString = new String[arraylength];
    int index;
   
    for (int i = 0; i < dataString.length; i++) {
      String temp = "";
      for (int j = 0; j < buffSize; j++) {
        index = i * buffSize + j;
        if ( j == buffSize - 1){
          temp += (float) data.get(index);
        } else {
          temp += (float) data.get(index) + " ";
        }
      }

      dataString[i] = temp;
   
    }

    saveStrings(pathTosave, dataString);
    println("Data saved!");
  }
}

This technique was inspired by something I’ve read somewhere, I will try to retrieve it and point to it here. 😉

Abstract expressionism: a generative approach

posted by on 2016.06.28, under Processing
28:

I have always been fascinated by abstract expressionism, and in particular the work of Jackson Pollock. The way paint, gravity and artistic vision play together was always for me very representative of that tension between chaos and structural patterns one often finds in art.
So, here it is a little homage to the drip-painting style of Pollock. The Processing code is not clean enough to be useful, and I don’t think I understand what it exactly does yet (yes, it happens more than often that what I code is a surprise to me!). Let me say that it incorporates many of the topics discussed in this blog: object oriented programming, noise fields, etc. I’ll update the post when I’ll get it (hopefully) cleaned up.
Meanwhile, enjoy. 😉

Textural Terrain Generation

posted by on 2016.06.22, under Processing
22:

This post is inspired by some of the stuff Daniel Shiffman has on his YouTube channel.
The idea is based on the use of meshes and textures. So, what’s a mesh and what’s a texture?
A mesh is a collection of vertices, edges and faces that are used in 3D computer graphics to model surfaces or solid objects. If you are familiar with the mathematical notion of a triangulation, you are more or less in business. Even though the faces are not necessarily triangles in general, the analogy works quite well. In Processing there is a nice and quick way to generate a triangular mesh, and it’s via beginShape()/endShape(), which is what I have used in the code below. One starts with a grid (check out some earlier posts for rants about grids), and from the collection of points of the grid Processing will then build a triangular mesh*. This is achieved via the TRIANGLE_STRIP mode: we only need to specify the vertices (though in a precise order), and they will be connected via triangular shapes. Very cool. Ok, we have a tons of little triangles which assemble in a huge square: what do we do with this? Here comes the notion of a texture map. The idea is very simple: we have an image, and we want to “glue” it to a face of the mesh. Once it is glued to such a face, the image will follow the face: for instance, if we rotate such a face, the image which is stuck to that face rotates as well! Now, you should know that mapping textures on a complicated surface is kind of an art, but in our case it is pretty easy, since the surface is just a flat square. To achieve this gluing, we have to define some anchor points in the image. In other words, we have to give information about how points in the original image are associated to vertices in the mesh. The double loop in the code below does exactly this: the last two parameters in the vertex() function specify indeed the gluing.
If we had halted our imagination here, we would end up with something very static: an image attached to a square. Meh. Here comes the simple, but interesting idea. Since we are in 3D geometry, we can modify the z-coordinate of the vertex at point (x,y) with a function of the plane. In this case, the function used is Perlin noise. If we rotate our system of coordinates with respect to the x-axis, you start seeing little mountains appear. Nice! Still, though, there is no movement in place. To achieve such a movement effect, we can increment the y coordinate slightly at each frame, so that the new z-coordinate at point (x, y) will be the value of the z-coordinate at a previous point in the grid, achieving the moving effect. In the code, I’ve furthermore decided to control the offset of the z-coordinate with a variable r whose minimum value is 0, and gets triggered randomly. Notice that I’ve also allowed some “release” time for r, so to achieve some smoothness. In this way you obtain a nice beating feeling. Instead of doing it randomly, what happens if you trigger r via a beat detector listening to some music (using the Sound or Minim library, say)? Yep, you get a nice music visualizer. :)
Last couple of things I added is to “move along the image”, and using tint() instead of clearing the screen. The first one is achieved via the variable speed: basically, at each new frame, we don’t glue the image to the mesh in the exact same way, but we translate it a bit in the y-direction.
Oh, I’ve also used more than one image, to get a change in the color palette.
Here’s the code

int w = 1900;
int h = 800;
int cols;
int rows;
int scl = 30;

PImage[] img = new PImage[3];
PImage buff;

float speed = 0.01;
int speed2 = 0;
float r = 0;


void setup() {
  size(1200, 720, P3D);
  background(0);

  //Load the images we are using as textures;
  img[0] = loadImage("path_to_image1");
  img[1] = loadImage("path_to_image2");
  img[2] = loadImage("path_to_image3");

  for (int i = 0; i < img.length; i++) {
    img[i].resize(1900, 2000);
    img[i].filter(BLUR, 0.6);
  }
  buff =img[0];

  noStroke();

  cols = w / scl;
  rows = h / scl;
}


void draw() {

//Triggers a "beat";
  if ( (random(0.0, 1.0) < 0.05) & (r < 0.1) ) {
    r = 8.0;
  }

  //This allows for some release time;

  if (r > 0.01) {
    r *= 0.95;
  }


//From time to time, choose another texture image;
    if (random(0.0, 1.0) < 0.008) {
    int i = int(random(0, 3));
    buff = img[i];
  }


  float yoff = speed;
  speed -= 0.03;
  if (frameCount%2 == 0) {
    speed2 += 1;
  }
  speed2 = speed2 % 60;

  translate(width/2, height/8);
  rotateX(PI/3);
  translate(-w/2 + sin(frameCount * 0.003)* 20, -h/2, -450); //The sin function allows for some left/right shift

  //Building the mesh

  for (int y = 0; y < rows; y++) {
    beginShape(TRIANGLE_STRIP);
    tint(255, 14);
    texture(buff); //Using the chosen image as a texture;
    float xoff = 0;
    for (int x = 0; x < cols + 1; x++) {
      vertex(x * scl, y * scl, map(noise(xoff, yoff), 0, 1.0, -60, 60) * (r + 2.9), x * scl, (y + speed2) % 2000 * scl);
      vertex(x * scl, (y + 1) * scl, map(noise(xoff, yoff + 0.1), 0, 1.0, -60, 60) * (r + 2.9), x * scl, ((y + 1 + speed2) % 2000) * scl);
      xoff += 0.1;
    }
    endShape();
    yoff += 0.1;
  }
}

Here’s it how it looks like

Very floaty and cloud-like, no? 😉

Exercise 1: instead of loading images, use the frames of a video as textures.
Exercise 2: instead of controlling the z-coordinate of a point (x,y) via a Perlin noise function, use the brightness at (x,y) of the texture image obtained in Exercise 1.
Exercise 3: Enjoy. :)

*One should really think of a mesh as an object which stores information about vertices, edges, etc., while we are here concerned only with displaying a deformed grid.

Mondrian and recursion

posted by on 2016.05.03, under Processing
03:

As I mentioned more than once in this blog, one shouldn’t abuse object oriented programming. There is still a lot of beautiful art generated with a few lines of code. I hope the following Processing sketch, inspired by the geometric minimalism of Piet Mondrian, falls in this category

color[] cols;
int num = 5;

void setup() {
  size(600, 800);
  background(0);
  cols = new color[num];

  for (int i = 0; i < num; i++) {
    cols[i] = color(int(random(0, 255)), int(random(0, 255)), int(random(0, 255)));
  }

  strokeWeight(1.5);
  for (int i = 0; i < 10; i++) {
   // rotate(i * 0.1 * 2 * PI);
    Mondrian(0, width, height);
  }
}

void draw() {

}

void mousePressed() {
  fill(255, 255);
  rect(0, 0, width, height);

  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < num; j++) {
      cols[j] = color(int(random(0, 255)), int(random(0, 255)), int(random(0, 255)));
    }
   
//    rotate(i * 0.1 * 2 * PI);
    Mondrian(0, width, height);
   
  }
}


void Mondrian(float x, float len1, float len2) {
  if (len1 > 20 & len2 > 20) {
    pushMatrix();
    translate(x, 0);
    color c1 = cols[int(random(0, cols.length))];

    if (random(0.0, 1.0) < 0.5) {
      float x_new = random(0, len1 * 0.5);
      fill(c1, 255);
      rect(0, 0, x_new, len2);
      Mondrian(x_new, len1 - x_new, len2);
    } else {
      float len_new = random(0, len2);
      fill(c1, 255);
      rect(0, 0, len1, len_new);
      Mondrian(0, len1, len_new);
    }
    popMatrix();
  }
}

It is essentially based on recursion, and exploits again the idea of a grid, even if in a conceptually different way from the latest post.
If you run the code, you should get something like this

1

I suggest you uncomment the line which contains the rotate call. :)
Also, here’s an exercise: modify the function Mondrian() in such a way that the same color is never chosen in successive iteration.
Remark: In his neoplastic paintings, Mondrian used mostly primary colors and white, with white being usually predominant. Moreover, he used thicker lines. Try to modify the code above to achieve the same effect.

Grids: an object oriented approach

posted by on 2016.04.07, under Processing
07:

I have been working recently on a small audio-visual installation based essentially on grid manipulations, inspired by the art of the amazing Casey Reas.
Grids are some of the first interesting repetitive structures one learns to build. For instance, a one parameter function which displays a regular grid of rectangles maximising the surface of the screen used might look like this

void grid(int n){
float stepx = width/n;
float stepy = height/n;

for (int x = 0; x < width; x+=stepx){
   for (int y = 0; y < height; y+=stepy){
    rectMode(CENTER);
    noStroke();
    fill(255);
    rect(x + stepx/2.0, y + stepy/2.0, 20, 20);
    }
  }
}

It will produce a grid of equally spaced white rectangles (so, better set the background to black before in your code). This is all fun and cosy for a couple of milliseconds, but if you are like me, you will look immediately for possibilities of explorations, and honestly the bit of code above doesn’t offer much. Let’s be precise: it *can* offer a lot of ways of tweaking, but they become cumbersome very very quickly. Also, I like to write codes which are conceptually structural and modular, and which allow to separate more clearly the “data holding” part from its representation. I find that this helps a lot the sense of surprise I get from playing with my newly created tool/toy. For instance, all that white is boring: how about we assign a different color to each rectangle? Not randomly though, which would be very cheap. Let’s use an image as a palette, and have each rectangle carry the color of the image pixel at the center of the rectangle. This can be attained by introducing the following line

fill(img.pixels[x + y * width]);

where img is the PImage variable holding your image (which I assume you have resized to the screen width and height, unless you have a fetish for ArrayOutOfBound messages :) ). Nice. But I guess you still can’t see my point, of course. Okay, let’s do the same but with a video. Now the image is changing at each frame, so the function grid() must be called in the animation loop, i.e. inside draw(). Here you can see my point: by proceding in this way, you are doing a certain amount of redundant computations. Indeed, the only thing that you would like to modify in this case is how each node of the grid is represented, and *not* the grid structure itself. So, it helps then to think of a grid as a data holder for the positions of its nodes, which, once we require some extra properties, are directly determined by a single integer n, the number of nodes per row and column. What we draw on the screen is then a representation of this bunch of information. Anytime you have something that behaves like a collection of data, object oriented programming (OOP) is not far from sight. Building objects (or rather classes) is kind of an art: extracting the relevant properties we want in our objects so that further manipulation becomes reactive and enjoyable is not an easy task. This to say that the are some basic rules in object oriented programming, but for artistic reason we can (and should) ignore many standard design patterns, and look at each case separately. Since I like thinking in terms of objects when programming, I feel the following warning is due: do *not* overuse OOP! There are fantastic pieces of algorithmic/generative art which do not use objects at all. The point is that you might run the risk to decompose the problem in its atomic parts, which has a certain intellectual appeal, no doubt, but then get lost when it comes to exploration and tweaking. So, case by case, see what works best, and, most importantly, what puts you in that spot where you can still get surprised. This said, let’s move on.
So, we can model a grid with the following Grid class

class Grid {
  int n;
  float[] posx;
  float[] posy;
  float offsetx;
  float offsety;
  Shape[] shapes = {};
 
  Grid(int _n){
    n = _n;
    int stepx = width/n;
    int stepy = height/n;
    offsetx = stepx/2.0;
    offsety = stepy/2.0;
    posx = new float[n];
    posy = new float[n];
   
    for (int i = 0; i < n; i++){
      posx[i] = i * stepx;
      posy[i] = i * stepy;
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
        shapes = (Shape[]) append(shapes,new Shape(posx[i], posy[j]));
        }
      }

    }
   
    Grid(int _n, float _offsetx, float _offsety){
    n = _n;
    int stepx = width/n;
    int stepy = height/n;
    offsetx = _offsetx;
    offsety = _offsety;
    posx = new float[n];
    posy = new float[n];
   
    for (int i = 0; i < n; i++){
      posx[i] = i * stepx;
      posy[i] = i * stepy;
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
        shapes = (Shape[]) append(shapes,new Shape(posx[i], posy[j]));
        }
      }

    }
   
    Grid(int _n, float len, float _offsetx, float _offsety){
    n = _n;
    int stepx = int(len/n);
    int stepy = int(len/n);
    offsetx = _offsetx;
    offsety = stepy;
    posx = new float[n];
    posy = new float[n];
   
    for (int i = 0; i < n; i++){
      posx[i] = i * stepx;
      posy[i] = i * stepy;
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
        shapes = (Shape[]) append(shapes,new Shape(posx[i], posy[j]));
        }
      }

    }  
   
    void display(){
      pushMatrix();
      translate(offsetx, offsety);

      for (int i = 0; i < shapes.length; i++){
        shapes[i].display(20);
      }

      popMatrix();
    }
   
    void display(PImage _img){
      _img.loadPixels();
      pushMatrix();
      translate(offsetx, offsety);

      for (int i = 0; i < shapes.length; i++){
        shapes[i].setColor(_img.pixels[int(shapes[i].x) + int(shapes[i].y) * _img.width]);
        shapes[i].display(20);
      }

      popMatrix();
    }
   
  }

So, you can see that I have heavily used that you can overload constructors and methods, so to give some default behaviours when we don’t want to bother passing a lot of parameters. An instance of Grid will also carry an array of Shape objects: this is the “representational” informations of our grid. Here’s how the Shape class looks like:

class Shape {
  float x, y;
  color c;
 
  Shape(float _x, float _y){
    x = _x;
    y = _y;
    c = color(255, 255, 255);
  }
 
  Shape(float _x, float _y, color _c){
    x = _x;
    y = _y;
    c = _c;
  }
 
  void display(float w){
    rectMode(CENTER);
    noStroke();
    fill(c, 255);
    rect(x, y, w , w);
    rectMode(CORNER);
  }
 
  void setColor(color _c){
    c = _c;
  }
 
}

If you don’t specify any color, the rectangle will be white.
So, now the previous function grid() is subsumed in the following lines of code

Grid grid = new Grid(20);
grid.display(img);

Apart from the elegance of it, that as I mentioned before should not be the only criterion of judgement, the code now is amenable to vast explorations. For instance, by modifying the display() method of the Shape class we can completely change the appearance of our grid, even so much that it doesn’t look like a grid anymore! Moreover, we don’t have all those redundant computations to be made.
One thing that comes to mind when you have a class is that you can produce many objects from that class with slightly different properties. In this case I have decided to use this expedient in order to explore “fractalization”, which is another (made up?) word for “apply recursion carefully”. Add the following function to your code

void fractalize(int n){
  if (n > 1){
  grid = new Grid(n, x, y);
  grid.display();
  x+= grid.offsetx;
  y+= grid.offsety;
  fractalize(n - 1);
  }
}

To make the most of it, you might want to lower the alpha of the filling for the rectangles. Actually, as I mentioned before, we can start exploring the code and the questions it naturally suggests, like: “why restrict ourselves to rectangles?” Or “why even filling them?” “Can I add some stochastic noise here and there to make everything not so hearthless and rigid?” “What is the meaning of life?”
When you start raising these questions, a vast playground (or/and a deep existential pit) opens up.
Believe it or not, after very few adjustments to the Shape class here’s what I got

1

1

which I find having an interesting balance between structure and randomness. A nice surprise! :)

Noise, flows and generative art

posted by on 2016.03.26, under Processing
26:

What is and what isn’t generative art is a long standing debate, in which I do not want to enter here. Just to put things in context, though, I’ll share some words about it. For some people, a piece of art is generative if it is the product of some sort of system which, once set in motion, is left to itself, with no further interaction. These systems are also called autonomous. Though generative art is usually associated to algorithmic art, i.e. art generated by some computer algorithm, autonomous systems can be found in biology, chemistry, mechanics, etc. Personally, I find the constraint on the autonomy of the system a bit too tight. While I do think that autonomous systems produce fascinating pieces of art, hence showing the beauty of complexity and emergency, I’m also very much interested in the dichotomy creator/tool, which in this case manifests itself as a shadow of the interaction between human and machine. I’m thinking about art which is computer assisted, more specifically which arises from the interaction of some sort of (algorithmic) system with the creator/spectator. This interaction poses interesting questions. We can indeed consider the total generative system as the combination autonomous system + spectator. This would be an autonomous system itself, if not for one little detail: the spectator is aware (whatever that means) that he’s a tool of a machine which is producing a piece of art. A more concrete example would be the following. Consider a live art installation in which the movements of spectators are used to control some given parameters of a system, which is then used to draw on a big screen, or produce sounds. There is going to be a huge conceptual difference if the spectators are aware of the tracking of their movements or not. In the second case, we are in the presence of something which looks like an autonomous system, while in the first case the spectators could use their awareness to drive the artistic outcome. The topic is incredibly fascinating and worth thinking about: these few words were only meant as a support to the fact that I would consider as generative art* the piece that you are going to see in the following.
Since discussions surrounding art are not notoriously controversial enough, I’ll move to noise and randomness (yeeeih!). Let’s start with saying: you can’t generate random numbers with a computer. Behind any random number produced with a programming language, there is an algorithm: in general it is a very complicated one and takes as parameter physical parameters of your machine (say, the speed of the CPU at the moment you request a random number), but it is still an algorithm. It is just so complex that we (as humans) can’t see any logical pattern behind it. I already feel the objection coming: “Well, what is randomness anyway? Is there anything truly random?”. I’m going to skip this objection quickly, pointing here instead. Enjoy! 😉
Processing offers two functions to treat randomness and noise: one is random(), and the other is noise(). Actually, noise() is a function that reproduces Perlin noise, a type of gradient noise which is extremely useful to reproduce organic textures.
Though Perlin noise is great, no doubt about that, and since randomness for a machine is just a function which looks unpredictable, why not make one’s own noise? After all, one of the point of generative art is that it allows to build tools which can be played with and explored. The function customNoise() in the code below does exactly that: it is a function from -1 to 1 which behaves in an erratic enough way to be a good substitute for noise(). You have now got your very own noise function, well done! The question is: what are we going to do with that? That’s where the second noun in the title of this post enters the stage. Every time you have a nice function in two variables, you can build out of it a vector field. “What’s that?”, you might say. You can think of it as an assignment of a little arrow to each point of the screen, with the angle (in this case) respect to the x-axis determined by our noise function. Once we have such a little arrow, we can use it to tell a particle which is at a given position on the screen where to go next. You can imagine the vector field as being associated to a fluid which at each point moves exactly with velocity given by the value of the vector field. If you then drop tiny particles in the fluid, they will start moving along curves, which are called the flow curves of the vector field. Moreover, they will start accumulate along specific flow curves: I leave you to investigate why it is that. 😉
So, the following Processing code brings home all these ideas, plus a last one, which has to do with the beginning of this post. You will notice that the function customNoise() has a mouseX inside, and there’s a mouseY controlling the variable depth. This means that the function interacts with the mouse movement, and hence the output of the code can be driven by the user. In particular, the piece you get stays comfortably in that gray area between generative and nongenerative art, one of those interesting arguments you can entertain your friends with at the next vernissage or pub quiz you go. 😉
Here’s the code:

float[] x;
float[] y;
color[] col;
float s = 0.001;
float depth = 0.5;
PImage img;

void setup() {
  size(1000, 1000);
  background(0);
  int n = 1000;
  x = new float[n];
  y = new float[n];
  col = new color[n];
  img = loadImage(pathtoimage/image);
  img.resize(width, height);
  img.loadPixels();
  for (int i = 0; i < x.length; i++) {
    x[i]= random(0, width);
    y[i]= random(0, height);
    int loc = int(x[i]) + int(y[i])*width;
    col[i] = img.pixels[loc];
  }
}

void draw() {
  noStroke();
  depth = map(mouseY, 0, height, 0.5, 1.5);
  //fill(255, 4); //Uncomment if you don't want to use an image;
  for (int i = 0; i < x.length; i++) {
    float alpha = customNoise(x[i] * s, y[i] * s)*2*PI;
    x[i]+= depth * cos(alpha); // + random(-0.4, 0.4);
    y[i]+= depth * sin(alpha); // + random(-0.4, 0.4);
    if (y[i] > height) {
      y[i] = 0;
      x[i] = random(0, width);
    }
    x[i]= x[i]%width;
    fill(col[i], 4); //Comment if you don't want to use an image;
    ellipse(x[i], y[i], 2, 2);
  }
}


float customNoise(float x, float y) {
  return pow(sin(0.9*x + noise(x, y)*map(mouseX, 0, width, 0, 5)*y), 3);
}

You will get something like this

noise2

noise1

Notice that the first piece is obtained by commenting/uncommenting some few lines.
Finally, there is one last question you might ask, and it is the following:”How did you come up with those peculiar numbers for the parameters in the code?”. Well, the answer is: by a certain amount of trial and error. As I mentioned more than once, making art with code allows for a great degree of exploration: tweaking a parameter here and changing a line there can give you very different and unexpected results. That what you get at the end is artistically appealing or not, well, nobody else can tell but you. These highly subjective decisions are what transforms a bunch of programming lines into something meaningful and beautiful. So, go on tweaking and looking for something you find interesting and worth sharing, then! :)

*If you are post-modernly thinking “Who cares if it’s called generative or not?”, you definitely have all my sympathy.

Digital poetry and text glitching

posted by on 2016.03.21, under Processing
21:

Digital poetry is that part of literature which is concerned with poetic forms of expression which are mainly computer aided. I am using the term in a strong sense here, i.e. I am thinking about generative poetry, hypertext poetry, and for this occasion in particular digital visual poetry. In general, the relation between the (graphical) sign used to represent a word and its actual meaning in a poetic text is a very interesting (and crucial) one. Indeed, the way words are represented can be an integral part of the aesthetic value of a piece of literary text, poetry in this case. Just think about the beautiful art of Chinese calligraphy, for example. It is then not surprising that poetry, as many forms of digital art, can be glitched* too. I have written about glitch art already, and we can use a couple of ideas and methodology from there. One way to glitch a piece of poetry would be to introduce orthographic anomalies/errors in the text to get for instance something like**

“SnOww i% my s!hoooe
AbanNdo;^^ed
Sparr#w^s nset”

At this stage we are working mainly with the signifier, but in a way which doesn’t take into account the actual spatial representation of the text itself. (Yes, the text is actually represented already, I’m being a bit sloppy here.)
More in the direction of digital visual poetry, we can work with properties of the visualized text: the position of the actual characters involved, for instance. The graphical atoms will be then the characters forming the words in the text, in this case, and we introduce perturbations to their positions in space, and some other visual artifacts. To achieve this, we can regard the various lines of text, which are of type String, as array of characters, and display them. We have then to take care of the length in pixels of each character with the function textWidth(), in order to be able to display the various lines of text.
Here’s how a simple Processing code inspired by these ideas would look like:

PFont font;
String[] text = {"Oh you can't help that,",  "said the Cat.", "We're all mad here.",  "I'm mad. You're mad." };
int size = 48;
int index = 0;

void setup(){
  size(800, 800);
  background(0);
  textAlign(CENTER);
  font = loadFont("TlwgTypewriter-48.vlw"); //You can create fonts with Tools/Create Font in Processing
  textFont(font, size);
  for (int i = 0; i < text.length; i++){
    float posx = 200;
    float posy =  200 + i * 50;
    for (int j = 0; j < text[i].length(); j++){
    textSize(size);
    text(text[i].charAt(j), posx, posy);
    posx = posx + textWidth(text[i].charAt(j)) +random(-10, 10);
    if (random(0.0, 1.0) < 0.3){
       size = size + int(random(-10, 10));
       glitch(posx, posy);
      }
    }
  }
}

void draw(){
}

void glitch(float x, float y){
  char c = char(int(random(130, 255)));
  text(c, x + random(-10, 10), y + random(-10, 10));
}

You would get something like this

1

I have been lazy, and introduced the array of strings directly in the code: an easy (but instructive) variation would be to load a piece of text from a .txt file, and parse it to obtain the individual lines.
Finally, we could work at a third layer of graphic “deepness”: we could consider the whole text as an image, and use the ideas in the previous post to glitch it. This is left to you as an interesting exercise.
Most importantly: never contradict the Cheshire Cat, mind you. 😉

*I avoid using the term “hacked”, since nowadays it is practically and culturally meaningless. Someone suggested “hijacked”, which I prefer.
** Thanks to Kerouac for the raw material to esperiment with.

pagetop