Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

【Three.js】SpotLightで影をつくる

See the Pen [2017/03/19][Three.js]shadow by cubes by aadebdeb (@aadebdeb) on CodePen.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>[2017/03/19] shadow by cubes</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.3/dat.gui.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
  <script>

    window.onload = function() {
      init();
      render();
    };
    window.onresize = onResize;

    var camera, scene, renderer;
    var stats;
    var controller;
    var time;

    var ambientLight, spotLight, spotLightHelper;

    function init() {

      time = 0;

      initGui();
      initStats();

      initScene();
      initCamera();
      initRenderer();

    }

    function initStats() {
      stats = new Stats();
      stats.setMode(0);
      stats.domElement.style.position = 'absolute';
      stats.domElement.style.left = '0px';
      stats.domElement.style.top = '0px';
      document.body.appendChild(stats.domElement);
    }

    function initGui() {
      controller = new function() {
        this.ambientIntensity = 1;
        this.ambientColor = '#eeeeee';
        this.spotIntensity = 1;
        this.spotAngle = Math.PI / 3;
        this.spotColor = '#ffffff';
      };

      gui = new dat.GUI();
      gui.add(controller, 'ambientIntensity', 0, 10).onChange(function(e) {
        ambientLight.intensity = e;
      });
      gui.addColor(controller, 'ambientColor').onChange(function(e) {
        ambientLight.color = new THREE.Color(e);
      });
      gui.add(controller, 'spotIntensity', 0, 10).onChange(function(e) {
        spotLight.intensity = e;
      });
      gui.add(controller, 'spotAngle', 0, Math.PI / 2).onChange(function(e) {
        spotLight.angle = e;
      });
      gui.addColor(controller, 'spotColor').onChange(function(e) {
        spotLight.color = new THREE.Color(e);
      });
    }

    function initRenderer() {
      renderer = new THREE.WebGLRenderer();
      renderer.setClearColor(new THREE.Color(0xeeeeee));
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.shadowMap.enabled = true;
      document.body.appendChild(renderer.domElement);
    }

    function initCamera() {
      camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
      camera.position.set(50, 50, 100);
      camera.lookAt(new THREE.Vector3(0, 0, 0));
    }

    function initScene() {
      scene = new THREE.Scene();

      var axes = new THREE.AxisHelper(50);
      scene.add(axes);

      var ground = new THREE.Mesh(
        new THREE.PlaneGeometry(100, 100),
        new THREE.MeshLambertMaterial({color: 0xcccccc})
      );
      ground.position.set(0, 0, 0);
      ground.rotation.x = -Math.PI / 2;
      ground.receiveShadow = true;
      scene.add(ground);

      for (var i = 0; i < 20; i++) {
        var cube = new THREE.Mesh(
          new THREE.BoxGeometry(5, 5, 5),
          new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff})
        );
        cube.position.set(
          getRandom(-50, 50),
          getRandom(2.5, 30),
          getRandom(-50, 50)
        );
        cube.castShadow = true;
        scene.add(cube);
      }

      ambientLight = new THREE.AmbientLight(controller.ambientColor);
      ambientLight.intensity = controller.ambientIntensity;
      scene.add(ambientLight);

      spotLight = new THREE.SpotLight(controller.spotColor);
      console.log(spotLight.position);
      var p = getSpotLightPosition();

      spotLight.position.set(p.x, p.y, p.z);
      spotLight.castShadow = true;
      spotLight.angle = controller.spotAngle;
      spotLight.intensity = controller.spotIntensity;
      spotLight.target = ground;
      scene.add(spotLight);
      spotLightHelper = new THREE.SpotLightHelper(spotLight);
      scene.add(spotLightHelper);
    }

    function getRandom(min, max) {
      return Math.random() * (max - min) + min;
    }

    function getSpotLightPosition() {
      return new THREE.Vector3(50 * Math.sin(time), 30, 50 * Math.cos(time));
    }

    function render() {
      time += 0.01;
      var p = getSpotLightPosition();
      spotLight.position.set(p.x, p.y, p.z);
      spotLightHelper.update();
      stats.update();
      renderer.render(scene, camera);
      requestAnimationFrame(render);
    }

    function onResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }

  </script>
</head>
<body>
</body>
</html>
f:id:aa_debdeb:20170319100917p:plain

[2017/03/19] shadow by cubes