not good but great

プログラミング、アート、映画・本の感想について書きます。

THREE.jsをとりあえず触ってみたいと思ってから、直方体を回転させてみるまでの手順

THREE.jsを使い始めた(再開し始めた?)理由

ズバリかっこいいから!TwitterでTHREE.js作成者のMr.doob氏やその周りのクリエイターがつくったものを見て、自分も作りたいと思った。それらがすべてWebGLを使ったものではないかもしれないけど、見て楽しめるものを作ってみたいと思い勉強し始めることにした。

・Mr.doob氏
https://twitter.com/mrdoob
・Web Audio&THREE.jsを用いたビジュアライザー 音楽の可視化
Loop Waveform Visualizer
・THREE.jsのピアノ演奏
3D Piano Player (Three.js)
・ピクセルシェーダーの解説とそのデモ
Intro to Pixel Shaders in Three.js — Airtight Interactive


実は一度THREE.jsを使って簡単なデモを作成したことがある。

ネコの画像が写った立方体をドラッグで回せるというもの。

このサイトを見て、ほとんど写経してつくった覚えがある。自分なりコメントを書いて覚えていくいつものパターン。
JavaScript 3DレンダリングエンジンのThree.jsを試す | KRAY Inc

作成したことがあると言っても、半年以上昔のことなので、忘れていることもあり一から学習し直すことにした。

THREE.jsのおさらい


yomotsuさんのスライドを見て、WebGLとTHREE.jsってどういうやつだっけ??というのを思い出す。


THREE.js で WebGL | ヨモツネット
次にこの記事を読んで写経して実際に動かしてみることにした。

THREE.jsの読み込み

<script type="text/javascript" src="http://jsdo.it/lib/three.js-r60/js"></script>

このコードをhtmlファイルに記入する。THREE.jsはjsdo.itから読み込んでいる。

領域の確保

//領域の横幅
var width = 600;
//領域の縦幅
var height = 600;

WebGLを表示する領域を定義する。

カメラの設置

  //画角
    var fov = 80;
    //縦横比
    var aspect = width / height;
    //クリッピング手前
    var near = 1;
    //クリッピング奥
    var far = 1000;
    
    //カメラを生成
    var camera = new THREE.PerspectiveCamera(fov,aspect,near,far);
    //カメラの位置
    camera.position.z = 500;

yomotsuさんのスライド85枚目にカメラのイラストがあるので、それを見てもらえるとわかりやすい。

シーンの作成

    //シーンを生成
    var scene = new THREE.Scene();
    
    //ジオメトリーを生成
    var geometry = new THREE.CubeGeometry(50,200,200);
    //マテリアル(ランバート反射)を生成
    var material = new THREE.MeshPhongMaterial({color:0x660000});
    //メッシュを生成
    var cubeMesh = new THREE.Mesh(geometry,material);
    //メッシュをシーンに追加
    scene.add(cubeMesh);

シーンはWebGLを表示する場所?のようなものだと思う。舞台みたいなものをイメージしている。

・ジオメトリー
作成する物体の枠組み。マッチ棒で立体を作るイメージ。

・マテリアル
物体の表面の材質を決める。つるつる光を反射するもの、光を反射しないもの、いろいろある。

・メッシュ
マテリアルをジオメトリーで覆う作業。

光源の作成

    //平行光源を生成
    var directionalLight = new THREE.DirectionalLight(0xffffff,3);
    //光源の位置
    directionalLight.position.z = 3;
    //シーンに光源を追加
    scene.add(directionalLight);

光源をあてないと物体は見えない。光源の種類や光源の位置を決める。

レンダラーの作成

    //レンダラーを生成
    var renderer = new THREE.WebGLRenderer();
    //レンダラーのサイズを設定
    renderer.setSize(width,height);
    //レンダラーをDOMに追加
    document.body.appendChild(renderer.domElement);
    
    //レンダラーをレンダリングする
    renderer.render(scene,camera);

これまで定義してきた3Dを画面に描画する行程。

回転アニメーション

    //メッシュの角度
    var theta = 0;

    function anime(){
        var radian = theta * Math.PI / 180;
        //メッシュを回転
        cubeMesh.rotation.set(radian,radian,radian);
        theta++;
        if(theta > 360){
            theta = 0;
        }
        renderer.render(scene,camera);
        //繰り返し処理
        requestAnimationFrame(anime);
    }
    anime();

繰り返しには「requestAnimationFrame」を使用している。

ブラウザのタブの裏に回ると、動作しないので無駄な処理をしないで済むなどのメリットがある。
参考
requestAnimationFrame < よーしおまえらー、アニメーションにsetInterval使うなよー - くろまほうさいきょうでんせつ

デモ