クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Three.js】回る箱をいろいろ打ち替えてみる

ブラウザで3Dコンテンツを作るJSライブラリ「Three.js」。前回は回る箱を表示してコードを細かく見ました。今回は実際の動きとしてどこをどう打ち替えたらどう変わるのかを実体験していきたく思います。それでは、どうぞ!

※目次:

前回のおさらい

まずは前回のおさらいから。

※参考:Three.js入門サイトに私も入門する!! - クモのようにコツコツと

できたものはこんな感じです。

※注!3D表示が多いとスマホの読み込みに時間がかかるため「Run Pen」表示にしました。タッチして再生してください。

箱が回ってますね。そうです。ICS MEDIA のThree.js入門サイトに私も入門したのです!押忍!

※参考:Three.js入門サイト - ICS MEDIA

JSのコードはこんなです。

 // ページの読み込みを待つ
    window.addEventListener('load', init);

    function init() {

      // サイズを指定
      const width = 960;
      const height = 540;

      // レンダラーを作成
      const renderer = new THREE.WebGLRenderer({
        canvas: document.querySelector('#myCanvas')
      });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(width, height);

      // シーンを作成
      const scene = new THREE.Scene();

      // カメラを作成
      const camera = new THREE.PerspectiveCamera(45, width / height);
      camera.position.set(0, 0, +1000);

      // 箱を作成
      const geometry = new THREE.BoxGeometry(400, 400, 400);
      const material = new THREE.MeshNormalMaterial();
      const box = new THREE.Mesh(geometry, material);
      scene.add(box);

      tick();

      // 毎フレーム時に実行されるループイベントです
      function tick() {
        box.rotation.y += 0.01;
        renderer.render(scene, camera); // レンダリング

        requestAnimationFrame(tick);
      }
    }

チュートリアルのコードをペーストしたらすぐに回る箱が出現してくれたので、次はこのコードをいろいろ打ち替えて、どこが変わるのか見ていきたく思います。いざっ!

サイズを打ち替えてみる

上から順番に行きますね。まず冒頭部分。

 // ページの読み込みを待つ
    window.addEventListener('load', init);

    function init() {

うーむ…ここは打ち変えようがないわな。ウィンドウが読み終わってから関数init()*1を実行せよ、というイベントリスナです。次っ!

 // サイズを指定
//Before
      const width = 960;
      const height = 540;

//After
      const width = 540;
      const height = 960;

次の「サイズを指定」部分。これはcanvas要素のサイズのはずなので、数字を反対にするとcanvas要素が縦長になると思う。どうだ?

うむ。縦長になった。次!

      // レンダラーを作成
      const renderer = new THREE.WebGLRenderer({
        canvas: document.querySelector('#myCanvas')
      });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(width, height);

      // シーンを作成
      const scene = new THREE.Scene();

次の「レンダラーを作成」や「シーンを作成」はいじりようがないな。#myCanvasと紐づかないと困るし、シーンもないと困る。ちなみにさっきの「サイズ」の変数widthheightを打ち替えたらcanvasのサイズが変わったのはこれらの箇所のおかげですよ。次ぃ!

カメラをいじりってみる

その次の「カメラを作成」をいじってみましょう。

// カメラを作成(画角、縦横比)
//Before
      const camera = new THREE.PerspectiveCamera(45, width / height);

//After
      const camera = new THREE.PerspectiveCamera(75, width / height);

一行目のPerspectiveCamera()メソッド。第一引数は「画角」でした。45を75にしてみたら、グンっと四角が遠くなった。

// カメラを作成(画角、縦横比)
//Before
      const camera = new THREE.PerspectiveCamera(45, width / height);

//After
      const camera = new THREE.PerspectiveCamera(45, height / width);

第一引数は元に戻す。第二引数は「縦横比」。順番を逆にしてみようか。(960 / 540 → 540 / 960)

うおうぅ!なんだか平たい感じの箱になったよ。そうか、縦横比率が歪んだ感じになるんだな。

// カメラを作成(カメラの位置)
//Before
      camera.position.set(0, 0, +1000);

//After
     camera.position.set(500, 0, +1000);

2行目を変えてみる。まずは第一引数を0から500に。

お、左に移動したぞ。

// カメラを作成(カメラの位置)
//Before
      camera.position.set(0, 0, +1000);

//After
     camera.position.set(0, 500, +1000);

次は第二引数を0から500にしてみる。

こんどは下に移動した!

// カメラを作成(カメラの位置)
//Before
      camera.position.set(0, 0, +1000);

//After
     camera.position.set(0, 0, +500);

最後は第三引数だ。+1000を500に。

わわっ!ドアップ(汗)。どうやら第三引数は奥行き(Z軸)のようだ。

箱をいじる

次は「箱を作成」をいじる。まず一行目。

// 箱を作成(箱のサイズ)
//Before
      const geometry = new THREE.BoxGeometry(400, 400, 400);

//After
      const geometry = new THREE.BoxGeometry(100, 500, 800);

引数は3つで箱のサイズだったので、3つとも400だったのを100、500、800と打ち替えてみる。

板みたいになった!横の辺が一番長い800だろうから、引数は「幅」「高さ」「奥行き」の順番なんだな。

次は「ジオメトリ」の形自体を変えてみよう。

※参考:Three.jsのジオメトリの基本 - ICS MEDIA

ふむふむ。SphereGeometry()が「球体」か。それっ。

// 箱を作成(球に変形)
//Before
      const geometry = new THREE.BoxGeometry(400, 400, 400);

//After
      const geometry = new SphereGeometry( 400, 400, 400);

おお!球体になった!!回転してる感はなくなったが…

ついでに引数3つも打ち替えてみる。さっきと同じ200, 600, 800に。それい。

// 箱を作成(球に変形)
//Before
      const geometry = new THREE.BoxGeometry(400, 400, 400);

//After
      const geometry = new SphereGeometry( 200, 600, 800);

ありゃ?もっと歪んだ丸になることを期待したが、球のまま全体のサイズが変わった感じ?

次の行の「マテリアル」を変えてみよう。

※参考:Three.jsのさまざまなマテリアル - ICS MEDIA

MeshNormalMaterial()は「ノーマルのカラーをRGBで可視化するマテリアルです。ライティングを必要としないため、手軽に動作確認するときに役立つ」とのこと。 その次のMeshLambertMaterial()は「光沢感のないマットな質感を表現」とのこと。これにしてみよう。

// 箱を作成(マテリアル)
//Before
     const material = new THREE.MeshNormalMaterial();

//After
     const material = new THREE.MeshLambertMaterial({color: 0x6699FF});

ありゃりゃ?だめだ。真っ暗で何も表示されない。引数に#6699FFの色も入れてるんだけどなー。

ん?よく見ると「※このマテリアルをつかう時はライトを用意ください。」とかいてる。ライトの設定はしてなかったので暗闇にマットな箱が回っている状態か。残念。。

その次のコードはこれまたいじりようがないです。 変数boxにジオメトリとマテリアルを適用し、そのboxをシーンに入れている。

      const box = new THREE.Mesh(geometry, material);
      scene.add(box);

アニメーション設定の変更

では最後にアニメーションの設定を変更しましょう!関数tick()の中身を変えていきます。

//関数tick()を実行
      tick();

      // 毎フレーム時に実行されるループイベントです
//関数tick()を定義
      function tick() {
//(この中を変更)
}

まず、箱の回転単位

//箱が0.01回転する
//Before
        box.rotation.y += 0.01;
//After
        box.rotation.x += 0.01;

まずrotationxプロパティをyにしてみる。

おお!横回転していた箱が縦回転になったぞ!

//箱が0.01回転する
//Before
        box.rotation.y += 0.01;
//After
        box.rotation.y -= 0.01;

次に、+= 0.01を反対の-= 0.01;にするとどうなるか?

予想通り、反対回転になりました!

//箱が0.01回転する
//Before
        box.rotation.y += 0.01;
//After
        box.rotation.y += 0.1;

最後に0.01を10倍の0.1にしてみるとどうなるか?(ドキドキ…)

ブン!ブン!ブン!ブン!ブン! わおっ!乱暴!これが遊園地のコーヒーカップだったら酔っちゃうやつだ。。

最後の部分はまたいじりようがないですね。

        renderer.render(scene, camera); // レンダリング

        requestAnimationFrame(tick);
      }
    }

アニメーション設定をレンダリングしているのと、requestAnimationFrame()メソッドでtickをフレームアニメ化してる。

まとめ

ということで、様々な設定値をいじって動きを見てみました。設定内容がより実感できました。さいごのブンブン丸は景気よかったですねw MeshNormalMaterial()メソッドのマットな質感が確かめられなかったのは残念。ライティングの設定を加える必要があるようです。 ともあれ、引き続きThree.js入門を進めていきたいと思います。それではまた!

*1:このinitはIn it(その中)ではなく、イニシャル(initial)の略ね