3

I'm working on a project in the Three.JS Online Editor. I'm trying to make a Day / Night Cycle. It should loop through colors, setting the scene background colors, like this:

  1. Day
  2. Sunrise/Sunset
  3. Night
  4. Sunrise/Sunset
  5. Day ... Etc., etc.,

And it should loop through these, forever.

I've gotten it to loop through two colors, but I can't seem to get it to loop through all three.

Is there a way to do this? Here's my code so far:

//var day = new THREE.Color(0xB8F4FF);
//var duskdawn = new THREE.Color(0xFF571F);
//var night = new THREE.Color(0x17012D);

//scene.background = new THREE.Color(0xB8F4FF);

let t = 0;
let tn = 0;
let cyc = 0;

//const day = new THREE.Color(0xB8F4FF);
var day = new THREE.Color(0xB8F4FF);
const duskdawn = new THREE.Color(0xFF571F);
const night = new THREE.Color(0x17012D);

animate();

function animate() {

  requestAnimationFrame(animate);
  t += 0.01;
  tn += 0.01;
  cyc = 0.9;
  cyc += 0.1;
  if(cyc % 2 == 1){
      //day = new THREE.Color(0x17012D);
      day = new THREE.Color(0xB8F4FF);
      //scene.background.copy(day).lerp(duskdawn, 0.5 * (Math.sin(t) + 1));
      scene.background.copy(day).lerp(duskdawn, 0.5 * (Math.sin(t) + 1));
      day = new THREE.Color(0x17012D);
      cyc += 0.1;
      if(cyc != 1){
          day = new THREE.Color(0x17012D);
      }
  /**/
  }
  if(cyc % 2 != 0){
      //scene.background.copy(night).lerp(duskdawn, 0.5 * (Math.sin(tn) + 1));
      //day = new THREE.Color(0xB8F4FF);
      day = new THREE.Color(0x17012D);
      scene.background.copy(day).lerp(duskdawn, 0.5 * (Math.sin(tn) + 1));
      //day = new THREE.Color(0xB8F4FF);
      cyc += 0.1;
      //cyc = 0;
  }
  /**/
  cyc = 0.9;
  cyc += 0.1;
  //cyc += 1;
}

Any help would be appreciated.

If anyone needs any more information, please, let me know!

Thanks!

Damjan Pavlica
  • 31,277
  • 10
  • 71
  • 76
Fox GAMING_NTF
  • 153
  • 2
  • 14

1 Answers1

4

Try it like so:

let camera, scene, renderer, clock;

const colors = [
  new THREE.Color(0xff0000),
  new THREE.Color(0xffff00),
  new THREE.Color(0x00ff00),
  new THREE.Color(0x0000ff)
];

const duration = 4; // 4s

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 1;

  scene = new THREE.Scene();
  scene.background = new THREE.Color();

  clock = new THREE.Clock();

  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);

  const time = clock.getElapsedTime();

  animateBackground(time)

  renderer.render(scene, camera);

}

function animateBackground(t) {

  const f = Math.floor(duration / colors.length);
  const i1 = Math.floor((t / f) % colors.length);
  let i2 = i1 + 1;

  if (i2 === colors.length) i2 = 0;

  const color1 = colors[i1];
  const color2 = colors[i2];
  const a = (t / f) % colors.length % 1;

  scene.background.copy(color1);
  scene.background.lerp(color2, a);


}
body {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.124/build/three.js"></script>
Mugen87
  • 28,829
  • 4
  • 27
  • 50
  • 1
    Clever and simple solution! – M - Jan 07 '21 at 20:55
  • Unfortunately, I don't know why, it doesn't seem like it wants to work in the ThreeJS Editor. It just displays a black rectangle in the top left corner when I try to run it. Do you have any idea what I can do to fix this? EDIT: An Update, I got it to work, thanks!. – Fox GAMING_NTF Jan 08 '21 at 13:07
  • I've selected `COLOR` as the background type and added parts of the above code as a new script for the `Scene` node. The script looks like so: https://jsfiddle.net/rnuL051z/ – Mugen87 Jan 08 '21 at 13:17
  • Ok, thanks. I also actually have another question, I tried making the duration constant longer, it appears as if it only seems to make the first color longer duration, not any of the others. – Fox GAMING_NTF Jan 08 '21 at 13:39
  • And what I'm trying to do is make it so that it lengthens all of the color's durations, not just the first one. – Fox GAMING_NTF Jan 08 '21 at 13:50
  • It still does the same thing, it only lengthens the first color. – Fox GAMING_NTF Jan 08 '21 at 13:58
  • If you have troubles with adapting the code it's probably better if you animate the colors with keyframes like in this example: https://threejs.org/examples/misc_animation_keys – Mugen87 Jan 08 '21 at 14:10
  • Should it be working? All I've done is changed the duration constant. I've tried using that but I can't seem to adapt it to get it to work for this. The code you provided has worked much better, I just need to slow it down. – Fox GAMING_NTF Jan 08 '21 at 15:35