After more and more experimentation, and adding additional spheres with their individual behavior, I tried to texture the spheres and create shadows with the use of lights (pointlight/ ambientmaterial). Additionally, I have added an additional function to implement a gradient background that fills the screen no matter the screen size.
Unfortunately, the outcome resulted in something funky. Is anybody able to help with texturing, lighting, and adding a gradient background to my artwork? Ideally it would look something like this:
Here is my current code:
function setup() {
//to make 3d you need WEBGL
createCanvas(windowWidth, windowHeight, WEBGL);
}
function draw() {
background(220);
// gradient background
var color1 = color(211, 211, 211);
var color2 = color(255, 255, 255);
setGradient(0, 0, windowWidth, windowHeight, color1, color2, "Y");
pointLight(255, 0, 0, 200, 0, 0);
//pointLight(0, 0, 255, -200, 0, 0);
noStroke();
//a handy method
// click and drag to move the camera
// mouse wheel to zoom
orbitControl();
// I'm storing big ball coordinates in a 3D p5Vector
const big_ball = createVector(150, -100, 0);
// 2D distance from mouse and the vector, just a quick an dirty example
const d = dist(mouseX, mouseY, big_ball.x, big_ball.y)/50;
//3d shapes are created at 0,0,0
//box(20);
//and we move them with tranformations
//this push() isolate transformations
push();
// again in a quick way, using dist from mouse to move the balls
translate(big_ball.x - d, big_ball.y + d/2, big_ball.z);
normalMaterial();
sphere(95);
//pop is counterpart of push(), close the "parenthesis"
pop();
// the other ball, let;s also move it a little :P
push();
translate(d/2, -120, 90);
ambientMaterial(255);
sphere(45);
pop()
// third ball
push();
translate(d*2, -20 + d , 100)
normalMaterial();
sphere(60);
pop()
// fourth ball
push();
translate(90 + d, -15 + d , 250)
normalMaterial();
sphere(20);
pop()
// fifth ball
push();
translate(90, 15 + d , 100)
normalMaterial();
sphere(20);
pop()
// sixth ball
push();
translate(90 - d, 30 + d/2 , 200)
normalMaterial();
sphere(5);
pop()
// seventh ball
push();
translate(240 + d*2, -200 - d, -150)
normalMaterial();
sphere(80);
pop()
//the axis so you can see :)
// line(0,-500,0, 0, 500, 0);
// line(-500, 0, 0,500,0, 0);
// line(0, 0, -500, 0, 0, 500);
}
function setGradient(x, y, w, h, c1, c2, axis) {
noFill();
if (axis == "Y") { // Top to bottom gradient
for (let i = y; i <= y+h; i++) {
var inter = map(i, y, y+h, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x+w, i);
}
}
else if (axis == "X") { // Left to right gradient
for (let j = x; j <= x+w; j++) {
var inter2 = map(j, x, x+w, 0, 1);
var d = lerpColor(c1, c2, inter2);
stroke(d);
line(j, y, j, y+h);
}
}
}