THREE.jsを使い始めた(再開し始めた?)理由
ズバリかっこいいから!TwitterでTHREE.js作成者のMr.doob氏やその周りのクリエイターがつくったものを見て、自分も作りたいと思った。それらがすべてWebGLを使ったものではないかもしれないけど、見て楽しめるものを作ってみたいと思い勉強し始めることにした。
・Mr.doob氏
https://twitter.com/mrdoob
・Web Audio&THREE.jsを用いたビジュアライザー 音楽の可視化
Loop Waveform Visualizer
・THREE.jsのピアノ演奏
http://www.rgba.org/r3d/3d-piano-player/
・ピクセルシェーダーの解説とそのデモ
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の読み込み
<script type="text/javascript" src="http://jsdo.it/lib/three.js-r60/js"></script>
このコードをhtmlファイルに記入する。THREE.jsはjsdo.itから読み込んでいる。
カメラの設置
//画角 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使うなよー - くろまほうさいきょうでんせつ