Pixel Sorting

2.png
PImage img;

void setup() {
  size(915, 548);
  img = loadImage("Little_Chief_Mountain_GNP1.jpg");
  img.resize(915, 548);
}

void draw() {
  img.loadPixels();
  for (int x = 0; x < img.width; x+= img.width /300) {
    for (int y = 0; y < img.height; y+= img.height / 300) {
      int c = getPixel(img, x, y);
      if (getPixel(img, x-1, y) > c) {
        setPixel(img, x-1, y, c);
        c = getPixel(img, x-1, y);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x-1, y-1) > c){
        setPixel(img, x-1, y-1, c);
        c = getPixel(img, x-1, y-1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x, y-1) > c){
        setPixel(img, x, y-1, c);
        c = getPixel(img, x, y-1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x+1, y) > c){
        setPixel(img, x+1, y, c);
        c = getPixel(img, x+1, y);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x+1, y+1) > c){
        setPixel(img, x+1, y+1, c);
        c = getPixel(img, x+1, y+1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x, y+1) > c){
        setPixel(img, x, y+1, c);
        c = getPixel(img, x, y+1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x-1, y+1) > c){
        setPixel(img, x-1, y+1, c);
        c = getPixel(img, x-1, y+1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x+1, y-1) > c){
        setPixel(img, x+1, y-1, c);
        c = getPixel(img, x+1, y-1);
        setPixel(img, x, y, c);
      }
    }
  }
  img.updatePixels();
  image(img, 0,0);
  noLoop();
}


public int getPixel(PImage img, int x, int y) {
   x = x < 0 ? 0 : x >= img.width ? img.width - 1 : x;
   y = y < 0 ? 0 : y >= img.height ? img.height - 1 : y;
  return img.pixels[x + y * img.width];
}

public void setPixel(PImage img, int x, int y, int c) {
   x = x < 0 ? 0 : x >= img.width ? img.width - 1 : x;
   y = y < 0 ? 0 : y >= img.height ? img.height - 1 : y;
  img.pixels[x + y * img.width] = c;
}

Superformula

1.png
float n1 = 0;
float n2 = 0;
float n3 = 0;
float m = 0;

float rotY = 0;
float rotX = 0;

void setup() {
  size(1280, 720, P3D); 
  n1 = random(1,100);
  n2 = random(1,100);
  n3 = random(1,100);
  m = (int)random(2,10);
}

void draw() {
  background(255);
  translate(width/2, height/2);
  rotateY(rotY);
  rotateX(rotX);
  noStroke();
  lights();
  int total = 75;
  PVector[][] globe = new PVector[total+1][total+1];
  float r = 300;
  for (int i = 0; i < total+1; i++) {
    float lat = map(i, 0, total, -HALF_PI, HALF_PI);
    float r2 = superFormulaR(m, n1, n2, n3, lat);//superShape3D(lat, m, 0.2, 1.7, 1.7);
    //float r2 = supershape(lat, 2, 10, 10, 10);
    for (int j = 0; j < total+1; j++) {
      float lon = map(j, 0, total, -PI, PI);
      float r1 = superFormulaR(m, n1, n2, n3, lon);//supershape(lon, m, 0.2, 1.7, 1.7);
      //float r1 = supershape(lon, 8, 60, 100, 30);
      float x = r * r1 * cos(lon) * r2 * cos(lat);
      float y = r * r1 * sin(lon) * r2 * cos(lat);
      float z = r * r2 * sin(lat);
      globe[i][j] = new PVector(x, y, z);
    }
  }

  //stroke(255);
  //fill(255);
  //noFill();
  //offset += 5;
  pushMatrix();
  colorMode(HSB);
  for (int i = 0; i < total; i++) {
    float hu = map(i, 0, total, 0, 255*6);
    fill((hu + 0) % 255 , (hu *10) % 255, (hu /2) % 255);
    beginShape(TRIANGLE_STRIP);
    for (int j = 0; j < total+1; j++) {
      PVector v1 = globe[i][j];
      vertex(v1.x, v1.y, v1.z);
      PVector v2 = globe[i+1][j];
      vertex(v2.x, v2.y, v2.z);
    }
    endShape();
  }
  popMatrix();
    rotY += PConstants.TWO_PI / 1000;
    rotX += PConstants.TWO_PI / 1000;
    if (frameCount % 350 == 0) {
      n1 = random(1,100);
      n2 = random(1,100);
      n3 = random(1,100);
      m = (int)random(2,20);  
    }
}

public PVector superFormula3D(float m, float n1, float n2, float n3, float phi, float theta)
{
   float r1 = superFormulaR(m, n1, n2, n3, theta);
   float r2 = superFormulaR(m, n1, n2, n3, phi);
   return new PVector(r1 * cos(theta) * r2 * cos(phi), r1 * sin(theta) * r2 * cos(phi), r2 * sin(phi));
}

public float superFormulaR(float m, float n1, float n2, float n3, float phi)
{
   float t1,t2;
   float a=1,b=1;

   t1 = cos(m * phi / 4) / a;
   t1 = abs(t1);
   t1 = pow(t1,n2);

   t2 = sin(m * phi / 4) / b;
   t2 = abs(t2);
   t2 = pow(t2,n3);

   return 1/pow(t1+t2,-1/n1);
}



public PVector superFormula(float m, float n1, float n2, float n3, float phi)
{
   float r;
   float t1,t2;
   float a=1,b=1;

   t1 = cos(m * phi / 4) / a;
   t1 = abs(t1);
   t1 = pow(t1,n2);

   t2 = sin(m * phi / 4) / b;
   t2 = abs(t2);
   t2 = pow(t2,n3);

   r = pow(t1+t2,1/n1);
   if (abs(r) == 0) {
      return new PVector(0,0);
   } else {
      r = 1 / r;
      return new PVector(r * cos(phi),r * sin(phi));
   }
}

Wiki: here

Max Headroom

Processing script based off the TV show Max Headroom. 

float rotx = PI/4;
float roty = PI/4;

float boxSize = 800;
float lineNum = 30;
void setup()
{
  size(1020, 720, P3D);
  textureMode(NORMAL);
  shapeMode (CENTER);
}
 
void draw()
{
   
  background(0);
  translate(width/2.0, height/2.0, boxSize/2);
  rotateX(rotx);
  rotateY(roty);
  stroke(255);
  noFill();
  float z = boxSize/2;
  pushMatrix();
  int side = 0;
  for (float rotY = HALF_PI; rotY <= TWO_PI; rotY+= HALF_PI) {
    switch (side) {
      case(0):
      stroke(255,0,0);
      break;
      case(1):
      stroke(255,255,0);
      break;
      case(2):
      stroke(255,255,0);
      break;
      case(3):
      stroke(255,0,0);
      break;
    }
    side++;
    for (int i = 0; i <= lineNum; i++) {
      if (rotY == HALF_PI || rotY == TWO_PI) {
        drawLineFromX(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
      } else{
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
      }
    }
    rotateY(rotY);
  }
  popMatrix();
  pushMatrix();
  rotateX(HALF_PI);
  stroke(0,0,255);
  for (int i = 0; i <= lineNum; i++) {
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
  }
  popMatrix();
  pushMatrix();
  rotateX(-HALF_PI);
  stroke(0,255,0);
  for (int i = 0; i <= lineNum; i++) {
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
  }
  popMatrix();
  lineNum = 20 + 10 * sin(frameCount / 100.0);
  boxSize = 700 + 100 * sin(frameCount / 100.0 + PI);
  if(!mousePressed){
    roty+=0.01;
    rotx+=0.02;
  }
}

float lineZOffset(int i, float z) {
  float size = 25 + 25 *sin(frameCount / 50.0 + PI /3);
  return z - size+ size * noise(frameCount / 100.0 + (float)i * 10000);
}

void drawLineFromX(float xStart, float xEnd, float y, float z, float points) {
  beginShape();
  float next = abs(xEnd - xStart) / points;
  curveVertex(xStart - next, y, z);
  curveVertex(xStart, y, z);
  int i = 1;
  for (float x = xStart + next; x < xEnd; x+= next) {
    curveVertex(x,  y, lineZOffset(2 + i, z));
    i++;
  }
  curveVertex(xEnd, y,  z);
  curveVertex(xEnd - next, y,  z);
  endShape();
}

void drawLineFromY(float yStart, float yEnd, float x, float z, float points) {
  beginShape();
  float next = abs(yEnd - yStart) / points;
  curveVertex(x,  yStart - next,z);
  curveVertex(x,  yStart, z);
  int i = 1;
  for (float y = yStart + next; y < yEnd; y+= next) {
  curveVertex(x,  y, lineZOffset(2 + i, z));
    i++;
  }
  curveVertex(x,  yEnd, z);
  curveVertex(x,  yEnd + next, z);
  endShape();
}
 

A Dark and Stormy Night, Programming with Poems

The above image was made using ADASN (A Dark and Stormy Night), a simple stack based programming language. I designed the code of the programming language to be written as normal English.  Every word of a sentence that has over 3 characters represents a number, 1 if it starts with a, 2 if it starts with b and etc. All the words in the sentence are then added up and if the resulting number corresponds to a command then the command is executed otherwise it is pushed onto the stack. Numbers 55 through to 86 represent commands. When the code is executed it generates a video where the code runs separately for each pixel every frame of the video.

The code tends to work best when written as a poem as it allows for more flexible sentence structure. The trick is to write code that not only describes how to make an image but what that image means.

Currently I have written a transpiler using JavaCC that converts the code into java and glsl, using processing to interface with opengl. This creates java source code that can then be compiled into a runnable jar file.

Commands

  • 55     time - pushes the current running time to the stack
  • 56    dup - duplicates the top of the stack
  • 57    push - pushes the number number to the stack even if its a command
  • 58    decimal - pops then pushes 1 / that numbers  
  • 59    <= - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 60    >= - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 61    < - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 62    > - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 63    = - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 64    != - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 65    + - pops the top 2 from the stack then pushes one plus the other
  • 66    - - pops the top 2 from the stack then pushes one minus the other
  • 67    * - pops the top 2 from the stack then pushes one times the other
  • 68    / - pops the top 2 from the stack then pushes one divided by the other
  • 69    % - pops the top 2 from the stack then pushes one modulus the other
  • 70    x - pushes the x position of the current pixel
  • 71    y - pushes the y position of the current pixel
  • 72    r - pushed the red color value of the current pixel
  • 73    g - pushed the green color value of the current pixel
  • 74    b - pushed the blue color value of the current pixel
  • 75    sR - pops then sets the current red color value to that number
  • 76    sG - pops then sets the current green color value to that number
  • 77    sB - pops then sets the current blue color value to that number
  • 78    sin - pops then pushes the sin of that number
  • 79    cos - pops then pushes the cos of that number
  • 80    tan - pops then pushes the tan of that number
  • 81    rand - pushes a random number
  • 82    width - pushes the width of the video
  • 83    height - pushes the height of the video
  • 84     pop - pops the stack
  • 85    length - pops the top 2 on the stack and pushes the length of them
  • 86    atan - pops the top 2 on the stack and pushes the atan of them

Example

Bolbus.

Terrifically gigantic,
floating a buv, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Rising at morn,
falling at night,
soaring a buv.

Watching from far above,
shining down sun,
moving the fun.

Beautiful.

Terrifically gigantic,
floating above, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Rising at morn,
falling at night,
soaring above.

Watching from far above,
shining down sun,
moving the fun.

Terrifically gigantic,
floating around all up a bove, 
up in the heavens,
floating with love.

Around, all bashly above.

Terrifically gigantic,
floating a buv, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Watching from far above,
shining sun,
moving the fun.

Rising at morn,
falling at night,
xhuming the sun.

(As you can see i did cheat a bit by changing the spelling of some words, xhuming instead of exhuming and a buv/a bove instead of above)

Parsing

This is what it gets parsed down to:

  1. 2 82 68 70 66 2 83 68 71 66 85 4 82 68 62 75
  2. 2 width / x - 2 height / y - length  4 width / > setR
  3. R = length y - (height /2), x - (width /2)) >  width / 4

 

 

Chroma and Image Distortion

Wrote this shader for processing a while back. It adds a sort of drunken vibe when applied to images. 

Fragment Shader

precision highp float;

uniform sampler2D texture;
uniform float noiseOffset;
uniform float noiseMultipler;
uniform float noiseAddMultipler;
uniform float colorOffset;
uniform float colorOffsetMod;
uniform float positionMixAlpha;

varying vec4 vertColor;
varying vec4 vertTexCoord;
varying vec4 pos;

//https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83
float rand(vec2 n) { 
    return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
}

float noise(vec2 p){
    vec2 ip = floor(p);
    vec2 u = fract(p);
    u = u*u*(3.0-2.0*u);

    float res = mix(
        mix(rand(ip),rand(ip+vec2(1.0,0.0)),u.x),
        mix(rand(ip+vec2(0.0,1.0)),rand(ip+vec2(1.0,1.0)),u.x),u.y);
    return res*res;
}

//  https://www.shadertoy.com/view/MdX3Rr
//  by inigo quilez
//
const mat2 m2 = mat2(0.8,-0.6,0.6,0.8);
float fbm( in vec2 p ){
    float f = 0.0;
    f += 0.5000*noise( p ); p = m2*p*2.02;
    f += 0.2500*noise( p ); p = m2*p*2.03;
    f += 0.1250*noise( p ); p = m2*p*2.01;
    f += 0.0625*noise( p );

    return f/0.9375;
}


void main() {
	vec2 p = vertTexCoord.xy;
    vec2 modNoiseP = (p*noiseMultipler + noiseOffset);//2
    float noiseF = (fbm(modNoiseP) + fbm(modNoiseP + noiseAddMultipler* fbm(modNoiseP)));
    float cMod = noiseF * colorOffsetMod;//3
    vec4 red = texture2D(texture,  mix(p, vec2(noiseF) - vec2(colorOffset * cMod,0.), positionMixAlpha));
    vec4 blue = texture2D(texture, mix(p, vec2(noiseF) + vec2(colorOffset * cMod,0.), positionMixAlpha));
    vec4 green = texture2D(texture, mix(p, vec2(noiseF), positionMixAlpha));
	gl_FragColor = vec4(red.r, green.g, blue.b, 1.);
}

Vertex Shader

#define PROCESSING_TEXTURE_SHADER

uniform mat4 transform;
uniform mat4 texMatrix;

attribute vec4 vertex;
attribute vec4 color;
attribute vec2 texCoord;

varying vec4 vertColor;
varying vec4 vertTexCoord;
varying vec4 pos;

void main() {
    gl_Position = transform * vertex;
    pos = transform * vertex;
    vertColor = color;
    vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);
}