読者です 読者をやめる 読者になる 読者になる

みかづきブログ その3

3ヶ月つづけてみました。

はじめてのthree.js その2

kimizuka.hatenablog.com

以前、はじめてのthree.jsを書いてから、全然three.jsを触る機会がなかったのですが、このままでは昨今の3Dブームに置いて行かれてしまうと思い、再び触り始めました。

今回は、前回までの知識をフル活用して、自分のアイコンをつくってみましたので、その過程をメモしておこうと思います。

今回つくるもの

f:id:kimizuka:20160606114751p:plain

このアイコンを3Dにしようと思います。


まずはDOMでつくってみる

このアイコンは 9 × 9 の 81個のブロックでつくられています。
なのでまずはJavaScriptをつかってDOMでつくってみました。

((win, doc) => {
 
 "use strict";
 
 const 
 top = 100,
 left = 100,
 width = 20,
 height = 20,
 margin = width / 5;
 
 var colors = [
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 
 "#637952",
 "#637952",
 "#000000",
 "#637952",
 "#637952",
 "#637952",
 "#000000",
 "#637952",
 "#637952",
 
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 
 "#637952",
 "#000000",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#000000",
 "#637952",
 
 "#637952",
 "#637952",
 "#000000",
 "#000000",
 "#000000",
 "#000000",
 "#000000",
 "#637952",
 "#637952",
 
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952",
 "#637952"
 ];
 
 for (let i = 0, length = colors.length; i < length; ++i) {
    let p = doc.createElement("p");
    
    p.style.cssText = [
        "position: absolute",
        "top:" + (top + (i / 9 | 0) * (height + margin)) + "px",
        "left:" + (left + (i % 9) * (width + margin)) + "px",
        "width:" + width + "px",
        "height:" + height + "px",
        "background:" + colors[i]
    ].join(";");
    
    doc.body.appendChild(p);
}

})(window, document);

左上から順番に色を配列に入れていって、それをfor文でまわして作成しました。
もっと効率よくかけますが、モックなので開発スピード重視で書いてます。


DEMO


three.js で書いてみる

81個のブロックをfor文で書くことに成功したので、そのままthree.jsに移植してみます。
座標系が逆なので、DOMバージョンとは配列が逆になっています。

((win, doc) => {

  "use strict";

  const renderer = new THREE.WebGLRenderer(),
        scene = new THREE.Scene(),
        camera = new THREE.PerspectiveCamera(
            60,
            win.innerWidth / win.innerHeight,
            1,
            10
        ),
        light = new THREE.PointLight(0xffffff, 2.5),
        top = -1.5,
        left = -1.5,
        size = .2,
        margin = size  * .8,
        colors = [
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,

          0x637952,
          0x637952,
          0x000000,
          0x000000,
          0x000000,
          0x000000,
          0x000000,
          0x637952,
          0x637952,

          0x637952,
          0x000000,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x000000,
          0x637952,

          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,

          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,

          0x637952,
          0x637952,
          0x000000,
          0x637952,
          0x637952,
          0x637952,
          0x000000,
          0x637952,
          0x637952,

          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,

          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,

          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952,
          0x637952
        ];
  
  var boxes = [];

  scene.add(light);
  
  camera.position.set(1, 1, 5);
  camera.lookAt(new THREE.Vector3(0, 0, 0));
  
  light.position.set(1, 1, 1);
  
  renderer.setSize(win.innerWidth, win.innerHeight);
  doc.body.appendChild(renderer.domElement);
  
  for (let i = 0, length = colors.length; i < length; ++i) {
    var geometry = new THREE.BoxGeometry(size, size, size),
        material = new THREE.MeshLambertMaterial({
          color: colors[i]
        });
    
    boxes[i] = new THREE.Mesh(geometry, material);
    boxes[i].position.set(
      left + (i % 9) * (size + margin),
      top + (i / 9 | 0) * (size + margin),
      0
    );
    
    scene.add(boxes[i]);
  }

  (function render() {
    for (let i = 0, length = boxes.length; i < length; ++i) {
      boxes[i].rotation.x += 0.01;
      boxes[i].rotation.y += 0.01;
      boxes[i].rotation.z += 0.01;
    }
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  })();

})(window, document);

DEMO

ポジションは適当にあわせました。
2Dのときより怖いですね。