How to make a parallax effect using Three.js

Viewed 1823

I want to make a parallax effect on mouse move using three.js. Basically I want to generate bunch of clouds to canvas and want them to move on x axis when mouse is moved.

So I have already tried to add clouds to the scene as images. How could I link mouse move even to these clouds? Or should I add clouds to the scene differently?

How I added clouds:

    var imgCloud = new THREE.MeshBasicMaterial({ 
        map:THREE.ImageUtils.loadTexture('img/cloud.jpg')
    });
    imgCloud.map.needsUpdate = true;

    // Cloud
    var cloud = new THREE.Mesh(new THREE.PlaneGeometry(200, 200), imgCloud);
    cloud.overdraw = true;
    scene.add(cloud);

2 Answers

You need to add an event listener to the window to get the mouse position. Then you can use that to modify the position of all clouds individually or just the position of the scene.

window.addEventListener('mousemove', onMouseMove, false);

function onMouseMove(event) {
    scene.position.x = (event.clientX - window.innerWidth / 2);
}

You can simply catch the mouse position and then move the camera along an axis relative to the new mouse position.

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

camera.position.z = 150;

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

// Add cloud
for (let i = 0; i <= 200; i++) {
  const geometry = new THREE.SphereGeometry(5, 32, 32);
  const material = new THREE.MeshBasicMaterial({ color: 0x3399ff, transparent: true, opacity: 0.8});
  const sphere = new THREE.Mesh(geometry, material);
  sphere.position.x += Math.round(Math.random() * 500) - 250;
  sphere.position.y += Math.round(Math.random() * 500) - 250;
  sphere.position.z += Math.round(Math.random() * 200);
  scene.add(sphere);
}

// Control
var mouseTolerance = 0.1;

document.onmousemove = function (e) {
  var centerX = window.innerWidth * 0.5;
  var centerY = window.innerHeight * 0.5;

  camera.position.x = (e.clientX - centerX) * mouseTolerance;
  camera.position.y = (e.clientY - centerY) * mouseTolerance;
};

//Render loop
function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
render();
body{
  margin: 0;
  overflow: hidden;
  height: 400px;
  width: 600px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>

The mouse position can be obtained withdocument.onmousemove as usual. Camera can be repositioned with camera.position.[axis]. You can play with different axes and see how it looks. Note that some objects must be closer to the camera than others otherwise it will not look like Parallax

Related