3D rain drops [The rate at which the drops fall gradually increases]

This a simple code in which multiple spheres are created at different X and Y coordinates and are given the speed at which they will fall.The speed seems to gradually increase as the number of spheres increase as a result , the first sphere translates at the desired speed but the second sphere moves two times faster, the third moved 3 times faster and so on.

My guess is somehow the speed variable increments for each object(sphere) generated.

drop = [];

function setup() {
  width = 800;
  height = 800;

  createCanvas(width, height, WEBGL);
  for (i = 0; i < 10; i++) {
    drop[i] = new rainDrop();
  }
}

function draw() {
  background(220);
  speed = 1;
  for (i = 0; i < 10; i++) {
    drop[i].fall();
    drop[i].display();

  }
}

function rainDrop() { // Create a drop object


  this.y = random(-200 / 0.5, -200);
  this.x = random(-200 / 2, 200 / 2);
  this.z = 0;
  this.speed = 1;

  this.display = function() {

    translate(this.x, this.y, this.z);
    sphere(10);
  }

  this.fall = function() {


    this.y = this.y + this.speed;
    if (this.y > 800 / 2) {
      this.y = random(-200 / 0.5, -200);
      this.x = random(-200 / 2, 200 / 2);

    }


  }


}

Cool project! A quick fix is to wrap up your transformations with push() and pop() like so:

this.display = function() {
    push();
    translate(this.x, this.y, this.z);
    sphere(10);
    pop();
  }

This keeps the speed from accumulating.

1 Like

Thanks a lot for the fix, just tried it out and it works.

Try also changing z value/ depth

And using lights();

1 Like

Hey,
I took your advice and read up on lights and materials.I have reduced the number of spheres being generated to 5 and out of these 5 spheres only one sphere appears to be perfectly shaded, the others have a sharp distinction between the white and the colored portion.Any idea how i can get every sphere to be perfectly shaded.Just to make it easier to spot the perfectly shaded sphere , i have set the depth value as 0.

drop = [];

function setup() {
  width = 800;
  height = 800;

  createCanvas(width, height, WEBGL);
  for (i = 0; i < 5; i++) {
    drop[i] = new rainDrop();
  }
}

function draw() {
  background(255);
  //lights();

  for (i = 0; i < 5; i++) {
    drop[i].lights();
    drop[i].fall();
    drop[i].display();

  }
}

function rainDrop() { // Create a drop object


  this.y = random(-height / .5, -height);
  this.x = random(-width / 2, width / 2);
  this.z = 0;
  this.speed = 1;
  this.grav = 0.01;


  this.display = function() { // used to display the drop
    push();

    fill(255);
    translate(this.x, this.y, this.z); // location of each sphere
    //specularMaterial(200, 200, 255);
    ambientMaterial(255, 255, 255);
    sphere(10, 64);

    pop();
  }

  this.fall = function() { // to make the drop fall

    this.speed = this.speed + this.grav;
    this.y = this.y + this.speed;
    if (this.y > 800 / 2) {
      push();
      this.y = random(-height / 0.5, -height);
      this.x = random(-width / 2, width / 2);
      this.z = 0;
      this.speed = 1;
      pop();
    }


  }

  this.lights = function() { // lighting the objects


    Y = ((mouseY) - width / 2);
    X = ((mouseX) - height / 2);
    v = createVector(X, Y, 1);
    v.normalize();
    //dirX = mouseX;
    //dirY = mouseY;
    //directionalLight(250, 250, 250, -dirX, dirY, 0);


    //pointLight(255, 255/2, 255/2, X, -Y, 0);
    ambientLight(0, 0, 100);
    directionalLight(250, 250 / 2, 250 / 2, v);

  }


}

Try to add noStroke(); here?

Isn’t lights(); alone a proper command?

1 Like

I tried replacing fill() with noStroke() and it didn’t work.There is still one perfectly shaded sphere and others have a distinct line between the colored and the white portion.

I tried using lights(); but it threw me an error “Uncaught ReferenceError: lights is not defined”.
My guess is in lights() we have functions like ambientLight([Params]) and such.

I have uploaded a picture of the problem below

Still can not get all the spheres to be perfectly shaded, will keep trying and let you’ll know if I get it working perfectly.

The code used is:

drop = [];

function setup() {
  width = 800;
  height = 800;

  createCanvas(width, height, WEBGL);
  for (i = 0; i < 50; i++) {
    drop[i] = new rainDrop();
  }
}

function draw() {
  background(50);
  //lights();

  for (i = 0; i < 50; i++) {
    
    drop[i].lights();
    drop[i].fall();
    drop[i].display();
    

  }
}

function rainDrop() { // Create a drop object


  this.y = random(-height / .5, -height);
  this.x = random(-width / 2, width / 2);
  this.z = 0;
  this.speed = 1;
  this.grav = 0.01;


  this.display = function() { // used to display the drop
    push();

    noStroke();
    translate(this.x, this.y, this.z); // location of each sphere
    ambientMaterial(200, 200, 255);
    sphere(10, 64);

    pop();
  }

  this.fall = function() { // to make the drop fall

    this.speed = this.speed + this.grav;
    this.y = this.y + this.speed;
    if (this.y > 800 / 2) {
      push();
      this.y = random(-height / 0.5, -height);
      this.x = random(-width / 2, width / 2);
      this.z = 0;
      this.speed = 1;
      pop();
    }


  }

  this.lights = function() { // lighting the objects


    Y = ((mouseY) - width / 2);
    X = ((mouseX) - height / 2);
    v = createVector(X, Y, -300); // Constant 
    v.normalize();
    

    directionalLight(255, 255/2, 255/2, v);
    ambientLight(25, 25, 200);
   

  }


}