ページ

2015年6月13日土曜日

新しい技術を学んでみる 5 - Three.js -

今回はWebGLをサポートする「Three.js」を学習

概要
  WebGLをサポートした3D描画ライブラリでJavaScriptで記述
  公式ページ
  http://threejs.org

WebGLが使えるブラウザ
  色々使用状況を調べれるサイト
  http://caniuse.com


公式ページから早速ダウンロード



以下が実際に使うもの


・build/three.js
・build/three.min.js
・exsamples/js/controls/OrbitControls.js

雛形ファイルの作成

・index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Three.jsの練習</title>
   </head>
  <body>
    <div id="stage"></div>
    <script src="three.min.js"></script>
    <script>
      (function() {

      })();
    </script>
  </body>
</html>

Three.jsの構成要素

Scene
- Mesh(部品)
--Geometry(形状)
--Material(材質)
-Light
-Camera

簡単なBoxを描画してみる
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Three.jsの練習</title>
  </head>
  <body>
    <div id="stage"></div>
    <script src="three.min.js"></script>
    <script>
      (function() {
        var width = 500;
        var height = 300;
        // scene
        var scene = new THREE.Scene();

        // mesh
        var geometry = new THREE.BoxGeometry(50, 50, 50);
        var material = new THREE.MeshBasicMaterial({ color: "red"});
        var cube = new THREE.Mesh(geometry, material);
        cube.position.set(0, 0, 0);
        scene.add(cube);

        // light

        // camera
        var camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
        camera.position.set(200, 200, 500);
        camera.lookAt(cube.position);

        // rendering
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.setClearColor(0xeeeeee, 1);
        document.getElementById('stage').appendChild(renderer.domElement);
        renderer.render(scene, camera);

       })();
    </script>
  </body>
</html>


↓描画結果



・ライトをいい感じで当ててみる
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Three.jsの練習</title>
  </head>
  <body>
    <div id="stage"></div>
    <script src="three.min.js"></script>
    <script>
      (function() {
        var width = 500;
        var height = 300;
        // scene
        var scene = new THREE.Scene();

        // mesh
        var geometry = new THREE.BoxGeometry(50, 50, 50);
        //var material = new THREE.MeshBasicMaterial({ color: "red"});
        var material = new THREE.MeshLambertMaterial({ color: "red"});
        var cube = new THREE.Mesh(geometry, material);
        cube.position.set(0, 0, 0);
        scene.add(cube);

        // light
        var light = new THREE.DirectionalLight(0xffffff, 1);
        light.position.set(0, 100, 30);
        scene.add(light);
        var ambient = new THREE.AmbientLight(0x550000);
        scene.add(ambient);

        // camera
        var camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
        camera.position.set(200, 200, 500);
        camera.lookAt(cube.position);

        // rendering
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.setClearColor(0xeeeeee, 1);
        document.getElementById('stage').appendChild(renderer.domElement);
        renderer.render(scene, camera);

      })();
    </script>
  </body>
</html>


↓実行結果



・AxisHelperの追加
X軸、Y軸を視覚的に表示するヘルパーを追加
        // helper
        var axis = new THREE.AxisHelper(1000);
        axis.position.set(0, 0, 0);
        scene.add(axis);

↓実行結果



・床を追加しそこに影を描画 + アニメーションしてみる
<!DOCTYPE html>
<html lang="ja">
   <head>
    <meta charset="utf-8">
    <title>Three.jsの練習</title>
   </head>
   <body>
    <div id="stage"></div>
    <script src="three.min.js"></script>
    <script>
      (function() {
        var width = 500;
        var height = 300;
        // scene
        var scene = new THREE.Scene();

        // mesh
        var geometry = new THREE.BoxGeometry(50, 50, 50);
        //var material = new THREE.MeshBasicMaterial({ color: "red"});
        var material = new THREE.MeshLambertMaterial({ color: "red"});
        var cube = new THREE.Mesh(geometry, material);
        cube.castShadow = true;
        cube.position.set(0, 50, 0);
        scene.add(cube);

        var sGeometry = new THREE.SphereGeometry(30);
        var sMaterial = new THREE.MeshLambertMaterial({ color: "blue"});
        var sphere = new THREE.Mesh(sGeometry, sMaterial);
        sphere.castShadow = true;
        sphere.position.set(50, 50, 50);
        scene.add(sphere);

        // Plane
        var pGeometry = new THREE.PlaneGeometry(300, 300);
        var pMaterial = new THREE.MeshLambertMaterial(
          { color: 0x0096d6, side: THREE.DoubleSide });
        var plane = new THREE.Mesh(pGeometry, pMaterial);
        plane.receiveShadow = true;
        plane.position.set(0, 0, 0);
        plane.rotation.x = 90 * Math.PI / 180;
        scene.add(plane);

        // light
        var light = new THREE.DirectionalLight(0xffffff, 1);
        light.position.set(0, 100, 30);
        light.castShadow = true;
        scene.add(light);
        var ambient = new THREE.AmbientLight(0x550000);
        scene.add(ambient);

        // camera
        var camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
        camera.position.set(200, 300, 500);
        camera.lookAt(cube.position);

        // helper
        var axis = new THREE.AxisHelper(1000);
        axis.position.set(0, 0, 0);
        scene.add(axis);

        // rendering
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.setClearColor(0xeeeeee, 1);
        renderer.shadowMapEnabled = true;
        document.getElementById('stage').appendChild(renderer.domElement);

        function render() {
          requestAnimationFrame(render);
          cube.rotation.x += 1 * Math.PI / 180;
          cube.rotation.y += 1 * Math.PI / 180;
          cube.rotation.z += 1 * Math.PI / 180;
          sphere.position.x = Math.sin(new Date().getTime() / 200) * 100;
          sphere.position.z = Math.cos(new Date().getTime() / 200) * 100;
          renderer.render(scene, camera);
        }
        render();

      })();
    </script>
  </body>
</html>

 ↓実行結果





2 件のコメント:

  1. 参考にさせて頂きました〜!
    私がプログラム初心者なので理解できてない部分も多いですが、分からない部分は調べて学習の軸として活用させて頂きます。

    返信削除
    返信
    1. コメントありがとうございます^^。
      気の向くままに書いていたりするので、分かりづらいかと思いますが、参考になれば幸いです。

      削除