【Three.js】簡単にシーンを切り替える方法【ソースコード付き】

スポンサーリンク
Three.js

複数のシーンを扱いたいけど、どうやって切り替えればいいの?

簡単な実装方法があるなら教えて

こういったお悩みを解決いたします。

シーンの読み込み・切り替えの方法は2つあると思います。

  • あらかじめすべてのシーンを読み込んでおき、レンダリング対象を切り替える
  • 逐一シーンを読み込み、読み込んだシーンをレンダリングする

当記事では、前者を採用しています。

あらかじめ読み込みを済ませておいた方が、切り替えがスムーズに行えます。

ただ、データ量が膨大だと最初の読み込む時間がかなりかかってしまいますので、状況に応じて使い分ける必要があるかと思います。

後半にはソースコードとデモを用意していますので、ぜひ参考にしてみてください。

当記事を読むと、

  • あらかじめシーンを読み込み、簡単に切り替えることができるようになる
スポンサーリンク

シーン切り替えの流れ

当記事のサンプルのシーンの切り替えは、ユーザーのボタンアクションを介して行います。

以下が概略です。

ScenesBox, Cylinder, Sphereの3つのシーンを管理しています。

それぞれに対応したボタンをユーザーがクリックすると、レンダリング対象シーンをそのシーンに切り替えます。

スポンサーリンク

シーン切り替えの実装!ソースコードはこちら

以下がソースコードになります。

<!DOCTYPE html>
<html>
  <head>
    <title>three.js Sample</title>
    <meta charset="utf-8">
    <script src="./three.js-master/build/three.min.js"></script><!--three.jsライブラリの読み込み-->
  </head>
  <body style="position: relative;">
    <button id="btn-boxscene" value="" style="position: absolute; left: 0%">Box</button>
    <button id="btn-cylinderscene" value="" style="position: absolute; left: 5%;">Cylinder</button>
    <button id="btn-spherescene" value="" style="position: absolute; left: 10%;">Sphere</button>
    <script>
      const scenes = new Object();
      const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000);  //カメラを作成
      const renderer = new THREE.WebGLRenderer(); //レンダラーを作成
      const boxGeometry = new THREE.BoxGeometry(100, 100, 100); //boxの形状データ
      const boxMaterial = new THREE.MeshNormalMaterial(); //boxの材質(マテリアル)情報
      const box = new THREE.Mesh(boxGeometry, boxMaterial); //形状と材質から実際の3Dオブジェクトを生成
      const cylinderGeometry = new THREE.CylinderGeometry(100, 100, 100, 32);
      const cylinderMaterial = new THREE.MeshNormalMaterial();
      const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);
      const sphereGeometry = new THREE.SphereGeometry(100, 100, 100);
      const sphereMaterial = new THREE.MeshNormalMaterial();
      const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
      const scenes_objects = {  //各シーンのオブジェクト
        box: box,
        cylinder: cylinder,
        sphere: sphere
      };
      let nowScene;
      init();
      animate();

      function init(){    //初期化用関数
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.BasicShadowMap;
        document.body.appendChild(renderer.domElement); //canvas要素をbodyタグに追加
        camera.position.set(0, 0, 500);
        Object.keys(scenes_objects).forEach(sceneName => {
          scenes[sceneName] = new THREE.Scene();
          scenes[sceneName].add(scenes_objects[sceneName]); //各シーンにオブジェクトを追加
        });
        nowScene = scenes['box']; //初期値をboxシーンにする
      }

      function animate(){
        renderer.render(nowScene, camera);
        requestAnimationFrame(animate); //毎フレーム呼び出すことで描画
      }

      //各ボタンがクリックされたときのイベントリスナを登録
      document.getElementById('btn-boxscene').addEventListener('click', function(){
        nowScene = scenes['box'];
      });
      document.getElementById('btn-cylinderscene').addEventListener('click', function(){
        nowScene = scenes['cylinder'];
      });      
      document.getElementById('btn-spherescene').addEventListener('click', function(){
        nowScene = scenes['sphere'];
      });
    </script>
  </body>
</html>

デモを見たい方はこちらをクリック(ページは遷移しません) ⇒

↑のデモで各シーンのボタンをクリックすると、映る物体が切り替わっているのが確認できるかと思います。

これでシーンの切り替えができました。

今回はオブジェクトがとても単純なものになりますが、複雑になってもこの手法で対応できるかとおもいます。

上記のソースコードは少し素朴な実装になりますが、ぜひ参考にして改良していただければと思います。

まとめ

いかがでしたでしょうか。

今回は複数のシーンを切り替える方法をご紹介しました。

動作しない、もっと良い実装法があるなどあれば、ぜひコメントをいただけると幸いです。

以上です。

コメント

タイトルとURLをコピーしました