HTML5テクニカルノート
three.js入門 01: 3次元空間で立方体を回す
- ID: FN1704010
- Technique: HTML5 / JavaScript
- Library: three.js r84
three.jsは、WebGLを使って3次元の表現ができる無償のJavaScriptライブラリです。本稿では、短いコードで3次元空間に立方体をつくって、回してみます。使ったプロパティやメソッドには、できるだけ公式ドキュメントへのリンクを加えました。
01 theree.jsライブラリを使う
ライブラリはthree.jsサイトのリンク[download]で、ZIPファイルがローカルに保存できます(図001)。buildフォルダの中に、開発用のthree.jsと公開用のthree.min.jsが納められていますので、用途に応じていずれかをお使いください。
図001■three.jsサイトの[download]のリンク
CDNも公開されていますので、本稿ではこちらを使うことにします。
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script>
02 シーンとカメラを定める
3次元空間であるシーンは、コンストラクタTHREE.Scene()
でつくります。引数は要りません。シーンの中に3次元のオブジェクトや光源、それらを映しだすためのカメラが加えられます。カメラを定めるのはコンストラクタTHREE.PerspectiveCamera()
です。引数はつぎの4つを渡します(図002)。
new THREE.PerspectiveCamera(視野角, 縦横比, 撮影開始距離, 撮影終了距離)
図002■カメラの設定
視野角は画角とも呼ばれ、撮影する範囲の広がりのほか遠近法の強さにも影響します(「レンズと画角のちがいを知り、表現に活かす CG制作者のための画角講座」参照)。画面の縦横比は幅/高さです。そして、奥行きに対して撮影する範囲の始まりと終わりを与えます。シーンとカメラはつぎのように定め、カメラのz軸方向の位置はObject3D.position
プロパティで少し下げました(デフォルト値0)。なお、JavaScriptコードから<body>
要素を参照することになるので、<script>
要素は<body>
の中に置いてください。
var width = window.innerWidth; var height = window.innerHeight; var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(30, width / height, 1, 1000); camera.position.z = 100;
03 レンダラーで<canvas>要素をつくってページに加える
カメラの映したシーンを描くのがレンダラーです。コンストラクタTHREE.WebGLRenderer()
で<canvas>
要素をつくります。引数は省きましょう。幅と高さはWebGLRenderer.setSize()
メソッドで決めます(デフォルト値300×150ピクセル)。<canvas>
要素はページに加えなければなりません。WebGLRenderer.domElement
プロパティで参照できるので、<body>
要素に差し込みました。これらの処理は関数(createRenderer())として定め、戻り値のレンダラーは変数に納めます(renderer)。
var renderer = createRenderer(width, height); function createRenderer(width, height) { var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height); document.body.appendChild(renderer.domElement); return renderer; }
04 立方体をつくってシーンに加える
立体はMesh
クラスのオブジェクトとしてつくります。メッシュには、かたちの幾何学情報となるジオメトリーと素材のマテリアルを与えなければなりません。直方体のジオメトリーをつくるのは、THREE.BoxGeometry()
メソッドです。幅と高さと奥行きを引数に渡します。THREE.MeshNormalMaterial()
でつくる素材は少し変わっていて、面の向きによって色が決まるのです。でき上がったジオメトリー(geometry)とマテリアル(material)のオブジェクトは、コンストラクタTHREE.Mesh()
の引数にします。こうして関数(createCube())から返された立方体(cube)は、Object3D.add()
メソッドでシーンに加えてください。
var side = Math.min(width, height) / 50; var cube = createCube(side, side, side); scene.add(cube); function createCube(width, height, depth) { var geometry = new THREE.BoxGeometry(width, height, depth); var material = new THREE.MeshNormalMaterial(); var cube = new THREE.Mesh(geometry, material); return cube; }
カメラ(camera)で映したシーン(scene)の画像は、レンダラー(renderer)で<canvas>
要素に描きます。そのために呼び出すのは、WebGLRenderer.render()
メソッドです。引数にはシーンとカメラを渡します。これで、3次元空間に立方体が描かれます(図003)。ここまでのスクリプトは以下のコード001にまとめました。
renderer.render(scene, camera);
図003■3次元空間に立方体の正面が描かれた
コード001■3次元空間に立方体を描く
var width = window.innerWidth;
var height = window.innerHeight;
var side = Math.min(width, height) / 50;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(30, width / height, 1, 1000);
var renderer = createRenderer(width, height);
var cube = createCube(side, side, side);
camera.position.z = 100;
scene.add(cube);
function createRenderer(width, height) {
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
return renderer;
}
function createCube(width, height, depth) {
var geometry = new THREE.BoxGeometry(width, height, depth);
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh(geometry, material);
return cube;
}
renderer.render(scene, camera);
05 立方体をアニメーションで回す
3次元空間に立方体を描いたといっても、正面向きでは立体かどうかわかりません。オブジェクトはObject3D.rotation
プロパティで軸を決めて回すことができます(角度はラジアン)。どうせならアニメーションで回しましょう。アニメーションの関数(update())を定めてwindow.requestAnimationFrame()
メソッドに渡せば、画面が描き替わるたびに呼び出されてアニメーションとして動かせるのです(図004)。3次元空間を描きなおすWebGLRenderer.render()
メソッドの呼び出しを忘れないようにしてください。スクリプトは以下のコード002にまとめ、サンプル001はjsdo.itに公開しました。
// renderer.render(scene, camera); function update() { cube.rotation.x += 0.01; cube.rotation.y += 0.01; requestAnimationFrame(update); renderer.render(scene, camera); } update();
図004■3次元空間で立方体が回る
コード002■3次元空間につくった立方体をアニメーションで回す
var width = window.innerWidth;
var height = window.innerHeight;
var side = Math.min(width, height) / 50;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(30, width / height, 1, 1000);
var renderer = createRenderer(width, height);
var cube = createCube(side, side, side);
camera.position.z = 100;
scene.add(cube);
function createRenderer(width, height) {
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
return renderer;
}
function createCube(width, height, depth) {
var geometry = new THREE.BoxGeometry(width, height, depth);
var material = new THREE.MeshNormalMaterial();
var cube = new THREE.Mesh(geometry, material);
return cube;
}
function update() {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
requestAnimationFrame(update);
renderer.render(scene, camera);
}
update();
サンプル001■three.js r84: Rotating a cube
- three.js入門 02: フォンマテリアルとライトを使う
- three.js入門 03: ジオメトリーを使う
- three.js入門 04: マテリアルを使う three.js入門 05: アニメーションを加える
作成者: 野中文雄
作成日: 2017年4月19日
Copyright © 2001-2016 Fumio Nonaka. All rights reserved.