Search code examples
three.jshtml5-canvasperlin-noise

Multiple three.js canvas


I'm working on two modified versions of this Three.js animation: https://codepen.io/farisk/pen/vrbzwL

var renderer = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas1'), antialias:true, alpha: true});
// default bg canvas color //
renderer.setClearColor( 0xffffff, 0);

//  use device aspect ratio //
renderer.setPixelRatio(window.devicePixelRatio);
// set size of canvas within window //
renderer.setSize(900, 900);


var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 35, 900/900, 0.1, 100 );
camera.position.z = 4;

var texture = new THREE.TextureLoader().load( 'http://nomadicschoolofthesenses.com/wp-content/themes/nomadic/images/pink6.png' );


var sphere_geometry = new THREE.SphereGeometry(200, 200, 200);

var material = new THREE.MeshBasicMaterial( { map: texture } );


var sphere = new THREE.Mesh(sphere_geometry, material);
scene.add(sphere);

var update = function() {

  // change '0.003' for more aggressive animation
  var time = performance.now() * 0.0005;
  //console.log(time)

  //go through vertices here and reposition them

  // change 'k' value for more spikes
  var k = 1;
  for (var i = 0; i < sphere.geometry.vertices.length; i++) {
      var p = sphere.geometry.vertices[i];
      p.normalize().multiplyScalar(1 + 0.1 * noise.perlin3(p.x * k + time, p.y * k, p.z * k));
  }
  sphere.geometry.computeVertexNormals();
  sphere.geometry.normalsNeedUpdate = true;
sphere.geometry.verticesNeedUpdate = true;


}

function animate() {
  sphere.rotation.y += 0.001;
  //sphere.rotation.y += 0.01;

  update();
  /* render scene and camera */
  renderer.render(scene,camera);
  requestAnimationFrame(animate);
}


window.addEventListener( 'resize', onWindowResize, false );

function onWindowResize(){

    camera.aspect = 900 / 900;
    camera.updateProjectionMatrix();

    renderer.setSize( 900, 900 );

}

requestAnimationFrame(animate);

I need to add two different canvases (#canvas1 & #canvas2" placed in different parts of the page with different values. I duplicated the code and changed the name of variables like renderer2, etc.

var renderer2 = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas2'), antialias:true, alpha: true});
// default bg canvas color //
renderer2.setClearColor( 0xffffff, 0);

//  use device aspect ratio //
renderer2.setPixelRatio(window.devicePixelRatio);
// set size of canvas within window //
renderer2.setSize(900, 900);

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 35, 900/900, 0.1, 100 );
camera.position.z = 3.5;

var texture = new THREE.TextureLoader().load( 'images/blue2.png' );

var sphere_geometry = new THREE.SphereGeometry(200, 200, 200);

var material = new THREE.MeshBasicMaterial( { map: texture } );

var sphere = new THREE.Mesh(sphere_geometry, material);
scene.add(sphere);

var update = function() {

  // change '0.003' for more aggressive animation
  var time = performance.now() * 0.0005;
  //console.log(time)

  //go through vertices here and reposition them

  // change 'k' value for more spikes
  var k = 1;
  for (var i = 0; i < sphere.geometry.vertices.length; i++) {
      var p = sphere.geometry.vertices[i];
      p.normalize().multiplyScalar(1 + 0.1 * noise.perlin3(p.x * k + time, p.y * k, p.z * k));
  }
  sphere.geometry.computeVertexNormals();
  sphere.geometry.normalsNeedUpdate = true;
sphere.geometry.verticesNeedUpdate = true;

}

function animate() {
  sphere.rotation.y += 0.001;
  //sphere.rotation.y += 0.01;

  update();
  /* render scene and camera */
  renderer2.render(scene,camera);
  requestAnimationFrame(animate);
}

window.addEventListener( 'resize', onWindowResize, false );

function onWindowResize(){

    camera.aspect = 900 / 900;
    camera.updateProjectionMatrix();

    renderer2.setSize( 900, 900 );

}

requestAnimationFrame(animate);

Both scripts work fine separately but if I call both of them it only renders the last one.


Solution

  • Thanks to what @gaitat pointed out. the solution was to merge / use the same script for all canvases and only duplicate variables as renderer, sphere, material, etc

    var renderer = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas1'), antialias:true, alpha: true});
    // default bg canvas color //
    renderer.setClearColor( 0xffffff, 0)
    
    var renderer2 = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas2'), antialias:true, alpha: true});
    // default bg canvas color //
    renderer2.setClearColor( 0xffffff, 0);
    
    //  use device aspect ratio //
    renderer.setPixelRatio(window.devicePixelRatio);
    // set size of canvas within window //
    renderer.setSize(900, 900);
    
    //  use device aspect ratio //
    renderer2.setPixelRatio(window.devicePixelRatio);
    // set size of canvas within window //
    renderer2.setSize(900, 900);
    
    var scene = new THREE.Scene();
    var scene2 = new THREE.Scene();
    var camera2 = new THREE.PerspectiveCamera( 35, 900/900, 0.1, 100 );
    camera2.position.z = 3.5;
    
    var camera = new THREE.PerspectiveCamera( 35, 900/900, 0.1, 100 );
    camera.position.z = 4;
    
    
    var texture2 = new THREE.TextureLoader().load( 'images/blue2.png' );
    var texture = new THREE.TextureLoader().load( 'images/pink6.png' );
    
    var sphere_geometry = new THREE.SphereGeometry(200, 200, 200);
    
    var material2 = new THREE.MeshBasicMaterial( { map: texture2 } );
    var material = new THREE.MeshBasicMaterial( { map: texture } );
    
    var sphere = new THREE.Mesh(sphere_geometry, material);
    var sphere2 = new THREE.Mesh(sphere_geometry, material2);
    scene.add(sphere);
    scene2.add(sphere2);
    
    var update = function() {
    
      // change '0.003' for more aggressive animation
      var time = performance.now() * 0.0005;
      //console.log(time)
    
      //go through vertices here and reposition them
    
      // change 'k' value for more spikes
      var k = 1;
      for (var i = 0; i < sphere.geometry.vertices.length; i++) {
          var p = sphere.geometry.vertices[i];
          p.normalize().multiplyScalar(1 + 0.1 * noise.perlin3(p.x * k + time, p.y * k, p.z * k));
      }
      sphere.geometry.computeVertexNormals();
      sphere.geometry.normalsNeedUpdate = true;
    sphere.geometry.verticesNeedUpdate = true;
    
    }
    
    function animate() {
      sphere.rotation.y += 0.001;
      //sphere.rotation.y += 0.01;
    
      update();
      /* render scene and camera */
      renderer.render(scene,camera);
      renderer2.render(scene2,camera2);
      requestAnimationFrame(animate);
    }
    
    window.addEventListener( 'resize', onWindowResize, false );
    
    function onWindowResize(){
    
        camera.aspect = 900 / 900;
        camera.updateProjectionMatrix();
    
            camera2.aspect = 900 / 900;
        camera2.updateProjectionMatrix();
    
        renderer.setSize( 900, 900 );
    
        renderer2.setSize( 900, 900 );
    
    }
    
    requestAnimationFrame(animate);