Digital Reality
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.
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
Lena: This 10-minute visualiser for A. G. Cooks album teaser featuring my python archive generator, is one of my favourite […]
One of the first exercises I assign to my students in my seminars is called “Random Compositions”. Basically, it’s quite […]
For my students at Elisava, I have created a new version of my mockup-tool. You need two different files for […]
2023-12-01 Today I want to share with you a first prototype that will be the basis for a new course […]
One of the most exciting and maybe even unsettling discoveries in the learning process of Creative Coding in Graphic Design […]
2023-08-03 In this episode I have been looking at String Methods in p5.js, or rather in Javascript. Originally I wanted […]
2023-07-20 Today I share the edit of the third episode of my trustTheProcess() livestreams with you. In it I rebuilt […]
In this livestream from June 22, 2023, I used Processing to develop an interactive, three-dimensional timeline of exemplary historical data […]