Digital Reality

Published by Tim on Sunday April 10, 2022

Last modified on January 25th, 2024 at 14:07

A few months ago I did a livestream marathon on Youtube over a period of 5 days. The theme I chose was “Digital Reality” and I wanted to see to what extent I could build a 3D world with first-person control in a limited amount of time using Processing. I had a lot of fun, also because many of you were there live and gave me feedback via the chat. Thanks again for that.

YouTube

By loading the video, you agree to YouTube’s privacy policy.
Learn more

Load video

YouTube

By loading the video, you agree to YouTube’s privacy policy.
Learn more

Load video

YouTube

By loading the video, you agree to YouTube’s privacy policy.
Learn more

Load video

YouTube

By loading the video, you agree to YouTube’s privacy policy.
Learn more

Load video

YouTube

By loading the video, you agree to YouTube’s privacy policy.
Learn more

Load video

sketch.pde

float MAGNITUDE = 12000;
PImage tex, floor;

PGraphics scene;

PImage texture;

PShader shade;

ArrayList<Videowall> walls;

float speed = 50;

float tileW;
float tileH;

float cameraZ = -5000;
PShape globe;

color BG = 0;
color FG = #F1F1F1;

float mx, my;

float TILES_X = 100;
float TILES_Y = 100;

void setup() {
  size(1920, 1080, P3D);
  tex = loadImage("16.jpg");
  floor = loadImage("25.jpg");
  tex.filter(GRAY);
  floor.filter(GRAY);

  globe = createShape(SPHERE, 10000);
  globe.textureMode(NORMAL);
  globe.setTexture(tex);
  globe.setStroke(false);

  scene = createGraphics(width, height, P3D);
  texture = createGraphics(width, height, P3D);

  walls = new ArrayList<Videowall>();

  for (int i = 0; i < 20; i++) {
    walls.add(new Videowall(i));
  }

  imageMode(CENTER);

  tileW = MAGNITUDE/TILES_X;
  tileH = MAGNITUDE/TILES_Y;

  shade = loadShader("halftone.glsl");
}

void draw() {
  shade.set("pixelsPerRow", 8000);

  mx = map(mouseX, 0, width, -90, 90);
  my = map(mouseY, 0, height, 200, -10000);

  float eyeX = width/2.0;
  float eyeY = height/2.0 + my;
  float eyeZ =(height/2.0) / tan(PI*30.0 / 180.0);
  float centerX = width/2.0;
  float centerY = height/2.0;
  float centerZ = 0;
  float upX = 0;
  float upY = 1;
  float upZ = 0;

  scene.beginDraw();
  scene.background(BG);
  scene.camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);

  // scene.directionalLight(255, 255, 255, 0, 0.5, -1);
  scene.perspective(PI/3.0, (float)width/height, 1, 100000);
  drawScene();
  interactionKeyboard();

  scene.endDraw();

  image(scene, width/2, height/2);
  filter(shade);

  texture = g.get();

  rec(30,1000);
}

ui.pde

void interactionKeyboard() {
  if (keyPressed) {
    if (key == 'w') {
      cameraZ += speed;
    } else if (key == 's') {
      cameraZ -= speed;
    } else if(key == 'p'){
     saveFrame("out/" + nf(int(random(1000000)),7) + ".png"); 
    }
  }
}

scene.pde

void drawScene() {

  // create the dome / sky
  scene.fill(#0000FF);
  scene.noStroke();
  scene.push();
  scene.translate(scene.width/2, scene.height/2);
  scene.rotateY(radians(frameCount * 1));
  // globe.setTexture(texture);
  scene.shape(globe);
  scene.pop();

  // Create the floor
  
  scene.fill(FG);
  scene.noStroke();
  scene.push();
  scene.translate(scene.width/2, scene.height/2 + 1200, cameraZ);
  scene.rotateY(radians(90 + mx));
  scene.rotateX(radians(90));
  scene.push();
  scene.fill(BG);
  scene.translate(0, 20);
  scene.textureMode(NORMAL); 
  scene.beginShape();
  scene.texture(floor);
  scene.vertex(-MAGNITUDE, -MAGNITUDE, 0, 0);
  scene.vertex(MAGNITUDE, -MAGNITUDE, 1, 0);
  scene.vertex(MAGNITUDE, MAGNITUDE, 1, 1);
  scene.vertex(-MAGNITUDE, MAGNITUDE, 0, 1);
  scene.endShape();
  scene.pop();
  
  scene.push();
  scene.translate(0,0,2100);
  // scene.rotateZ(radians(-frameCount));
  // Distribute the videowalls
  for (int i = 0; i < walls.size(); i++) {

    Videowall W = walls.get(i);

    scene.push();
    scene.translate(W.Z, W.X, W.Y);
    scene.rotateX(radians(W.ROTX));
    scene.rotateY(radians(W.ROTY));
    scene.rotateZ(radians(W.ROTZ));
    W.display();
    scene.image(texture, 0, 0,W.wallSize,W.wallSize);
    scene.pop();
  }
  
  scene.pop();


  scene.pop();
}

videowall.pde

class Videowall {

  PGraphics pg;

  float X;
  float Y;
  float Z;
  float ROTX, ROTY, ROTZ;
  
  int wallSize;

  color VIDEOWALL_FG = #000000;
  color VIDEOWALL_BG = #F1F1F1;

  int modulo;
  int s;

  Videowall(int _s) {

    modulo = int(random(5, 60));
    
    
    wallSize = int(random(200,3000));

    pg = createGraphics(wallSize, wallSize, P3D);

    noStroke();
    
    float mag = 500;
    
    X = random(-mag, mag);
    Y = random(-mag, mag);
    Z = random(-mag, mag);
    
   // X = 0;
   // Y = 0;
    // Z = 0;
    
    ROTX = random(-180, 180);
    ROTY = random(0,0);
    ROTZ = random(-180, 180);

  }

  void display() {

    float eyeX = pg.width/2.0 + mx * 3;
    float eyeY = pg.height/2.0;
    float eyeZ =(pg.height/2.0) / tan(PI*30.0 / 180.0);
    float centerX = pg.width/2.0;
    float centerY = pg.height/2.0;
    float centerZ = 0;
    float upX = 0;
    float upY = 1;
    float upZ = 0;

    pg.beginDraw();
    pg.background(VIDEOWALL_FG);
    pg.camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
    pg.fill(VIDEOWALL_BG);
    pg.directionalLight(255, 255, 255, -1, 0, 0);
    pg.noStroke();
    pg.translate(pg.width/2, pg.height/2);
    pg.sphere(160);
    pg.endDraw();
  }
}

Related

Hannah Gmeiner on Permacomputing in Graphic Design

In an age of increasing digital consumption, Hannah, a recent visual communication graduate, explored “Permacomputing”—a sustainable approach to technology inspired […]

Building Tools with p5.js (Playlist)

Click here to login or connect!To view this content, you must be a member of Tim's Patreon Unlock with PatreonAlready […]

DEMO 2025 – My Submissions

Limitations have always been playing a major role in my creative work; I was only able to develop my best […]

Tameem Sankari on Creative Coding for Large Media Corporations

In this interview, Copenhagen-based creative director Tameem Sankari shares his journey into Creative Coding, combining Processing, Blender, and Adobe CC. […]

Sam Griffith connects Creative Coding with Enviromentalism

In this post I’d like to introduce you to Sam Griffith, a talented graphic designer based in Detroit, to discuss […]

Throwback: My Talk at Demo Festival 2022

The next edition of the DEMO Festival is already approaching and I am currently developing a brand new talk for […]

Powers of Two – 128kb by Lena Weber

20 = 1 21 = 222 = 323 = 824 = 1625 = 3226 = 6427 = 128 … »In […]

Omid Nemalhabib explores the intersection of Creative Coding and Perso-Arabic Typography

In 2022, I spontaneously posted a story on Instagram: If anyone out there is also in Rotterdam, I’d love to […]