【第1部】
three.jsの基本

  • 1. three.js の基本形
  • 2. 3次元オブジェクト
  • 3. 移動・回転・拡大
  • 4. アニメーション

Hello World

軸オブジェクト:HelloWorld.html

ソースコードをご覧ください。

HTML文書の構成

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HellowWorld</title>
<script src="javascript/three.js_r63/three.js"></script>	<!-- Three.js用ライブラリ -->
<style>
*{padding:0px; margin:0px}
div#canvas-frame{
width: 600px;	/* 横幅 */ 
height: 600px; /* 縦幅 */ /*<-------------------ここを変更!*/
}
</style>
<script>
(省略)
</script>
</head>
<body>
<!-- canvas要素を配置するdiv要素 -->
<div id="canvas-frame"></div>
</body>
</html>
  1. 額縁となるdiv要素(id="canvas-frame")を用意する。
  2. 額縁の縦横サイズをCSSで指定する。

イベントの管理

////////////////////////////////////////////////////////////////////
// windowイベントの定義
////////////////////////////////////////////////////////////////////
window.addEventListener("load", function () { //<--------------------------(※)
threeStart(); //Three.jsのスタート関数の実行
});
////////////////////////////////////////////////////////////////////
// Three.jsスタート関数の定義
////////////////////////////////////////////////////////////////////
function threeStart() {
initThree();	//Three.js初期化関数の実行
initObject(); //オブジェクト初期化関数の実行
initCamera(); //カメラ初期化関数の実行
draw();			 //描画関数の実行
}
  • 「window」はJavaScriptでウェブブラウザ上の全てのオブジェクトを管理するオブジェクト。
  • 「addEventListener」はイベントを設定するメソッド。
  • 「load」は「読み込み完了後」を指定するキーワード。
  • 「function () { 〜〜 }」は無名関数。

Three.js 初期化関数

//グローバル変数の宣言
var renderer,		//レンダラーオブジェクト
scene,			 //シーンオブジェクト
canvasFrame; //キャンバスフレームのDOM要素
function initThree() {
//キャンバスフレームDOM要素の取得
canvasFrame = document.getElementById('canvas-frame');
//レンダラーオブジェクトの生成
renderer = new THREE.WebGLRenderer();
//renderer = new THREE.CanvasRenderer(); //<---------------------------(※1)
if (!renderer) alert('Three.js の初期化に失敗しました');
//レンダラーのサイズの設定
renderer.setSize(canvasFrame.clientWidth, canvasFrame.clientHeight);
//キャンバスフレームDOM要素にcanvas要素を追加
canvasFrame.appendChild(renderer.domElement);
//レンダラークリアーカラーの設定
renderer.setClearColor(0x000000, 1.0); //<---------------------------(※2)
//シーンオブジェクトの生成
scene = new THREE.Scene();//<--------------------------------(※3)
}
				
  • (※1) にてレンダラーとして利用するコンテキストを指定。
  • (※2) にて背景色となるクリアーカラーを指定。
  • (※3) にてシーン(=仮想3次元空間)の準備。

カメラ初期化関数

//グローバル変数の宣言
var camera;		//カメラオブジェクト
function initCamera() {
//カメラオブジェクトの生成
camera = new THREE.PerspectiveCamera( // <---------------------------(※1)
							 45,	//fov
							 canvasFrame.clientWidth / canvasFrame.clientHeight, //aspect
							 1,	 //near
							 1000 //far
						 );	 
//カメラの位置の設定
camera.position = new THREE.Vector3(100, 100, 100); //<---------------(※2-1)
//カメラの上ベクトルの設定
camera.up = new THREE.Vector3(0, 0, 1); //<---------------------------(※2-2)
//カメラの中心位置ベクトルの設定
camera.lookAt({ x: 0, y: 0, z: 0 });	//<-------------------------------(※2-3)
}
  • (※1) にて透視投影カメラを用意。コンストラクタの引数でカメラの特徴を設定。パラメータの意味は後述。他にも正投影カメラがある。
  • (※2) にてカメラの状態(位置、向き、姿勢)を設定。

透視投影カメラ

視体積の内部にあるオブジェクトがカメラに「映る

fov視野角
aspect縦横比(width/height)
nearカメラから視体積の手前までの距離
aspectカメラから視体積の奥までの距離

オブジェクト初期化関数と描画関数

////////////////////////////////////////////////////////////////////
// オブジェクト初期化関数の定義
////////////////////////////////////////////////////////////////////
//グローバル変数の宣言
var axis; //軸オブジェクト
function initObject() {
//軸オブジェクトの生成
axis = new THREE.AxisHelper(100); //<---------------------------(※1)
//軸オブジェクトのシーンへの追加
scene.add(axis); //<-------------------------------------(※2)
}
////////////////////////////////////////////////////////////////////
// 描画関数の定義
////////////////////////////////////////////////////////////////////
function draw() {
//レンダリング
renderer.render(scene, camera); //<----------------------------(※3)
}
  • (※1) にて軸オブジェクトの準備(軸の長さ100)。
  • (※2) にて軸オブジェクトをシーンへ追加。
  • (※3) にて、シーンをカメラで写す。
  • 1. three.js の基本形
  • 2. 3次元オブジェクト
  • 3. 移動・回転・拡大
  • 4. アニメーション

3次元オブジェクトの例1

立方体オブジェクト:CubeGeometry.html

ソースコードをご覧ください。

立方体オブジェクトの生成

オブジェクト初期化関数

//グローバル変数の宣言
var axis; //軸オブジェクト
var cube; //立方体オブジェクト
function initObject() {

(省略:軸オブジェクト)

//形状オブジェクトの宣言と生成
var geometry = new THREE.CubeGeometry(50, 50, 50);//(x軸方向の幅,y軸方向の幅,z軸方向の幅) //<-(※1)
//材質オブジェクトの宣言と生成
var material = new THREE.MeshNormalMaterial(); //<---------------------------(※2)
//立方体オブジェクトの生成
cube = new THREE.Mesh(geometry, material); //<-------------------------------(※3)
//立方体オブジェクトのシーンへの追加
scene.add(cube);
}
  • (※1) にて立方体の形状を指定(x軸方向の幅,y,z)
  • (※2) にて立方体の材質として、法線材質(面の法線方向によって描画色の異なる特殊な材質)を指定。
  • (※3) にてMeshクラスを用いて3次元オブジェクトを生成。

3次元オブジェクト生成方法

three.js のルール1:3次元オブジェクトの生成

Mesh系クラス ( 形状オブジェクト, 材質オブジェクト)

Meshクラスの親戚として、
MorphAnimMeshクラス(モーフィングアニメーション)、SkinnedMeshクラス(スキンメッシュアニメーション)
が存在。

3次元オブジェクトの例2

球オブジェクト:SphereGeometry.html

ソースコードをご覧ください。

オブジェクト初期化関数

//形状オブジェクトの宣言と生成
var geometry = new THREE.SphereGeometry(
50,					 //半径 (デフォルト:50)
10,					 //y軸周りの分割数 (デフォルト:8) //<--------------------(※1-1)
10,					 //y軸上の正の頂点から負の頂点までの分割数 (デフォルト:6) //<-(※1-2)
0,						//y軸回転の開始角度 (デフォルト:0)
2 * Math.PI,	//y軸回転の終了角度 (デフォルト:2*Math.PI) //<-----------(※3)
0,						//x軸回転の開始角度 (デフォルト:0)
Math.PI			 //x軸回転の終了角度 (デフォルト:Math.PI)
);
//材質オブジェクトの宣言と生成
var material = new THREE.MeshNormalMaterial(); //<--------------------(※2)
//球オブジェクトの生成
sphere = new THREE.Mesh(geometry, material);
//球オブジェクトのシーンへの追加
scene.add(sphere);

試してみよう

  • ソースコードを以下のとおり変更して実行せよ。
    var material = new THREE.MeshNormalMaterial( {shading: THREE.SmoothShading})
  • 第5引数を「2*Math.PI」から「Math.PI」へ変更せよ。
  • 第2引数、第3引数を大きくし滑らかになることを確認せよ。

ポリゴン分割数の指定

第2、第3引数をそれぞれ「10」→「100」と大きくする。
→1つあたりのポリゴンサイズが小さくなり滑らかに見える。

スムースシェーディング

曲面的に見せるため、法線ベクトルを補間します。

var material = new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading } )

半球の裏側

第5引数を「2*Math.PI」から「Math.PI」へ変更し、半球を下から覗き込むためにカメラの位置を次のとおり変更します。

camera.position = new THREE.Vector3( 100, 100, -100 );

カウリング(ポリゴン裏面の非描画)

ポリゴンの両面を描画するプロパティの追加。

var material = new THREE.MeshNormalMaterial({
shading: THREE.SmoothShading, 
side: THREE.DoubleSide //<-----------------------------追加
});
				

材質オブジェクトのプロパティ

プロパティ名意味
shading法線ベクトルの補間 FlatShading:補間なし(デ)
SmoothShading:補間あり
side描画面を指定 FrontSide:表面(デ)
BackSide:裏面
DoubleSide:両面
transparent透過処理 false:不透過(デ)
true:透過
opacity不透明度 1.0(デ)。0.0〜1.0で指定。
blending色混合演算の指定 NoBlending:ブレンディングなし
NormalBlending:通常(デ)
AdditiveBlending:加算
SubtractiveBlending:減算
MultiplyBlending:乗算
CustomBlending:カスタム

透過処理

transparentプロパティとopacityプロパティを追加します。

var material = new THREE.MeshNormalMaterial({ transparent : true, opacity : 0.5 });

  • 1. three.js の基本形
  • 2. 3次元オブジェクト
  • 3. 移動・回転・拡大
  • 4. アニメーション

平行移動

HTMLファイル:CubeGeometryEvent.html

3次元オブジェクトの「position」プロパティの値を変更。

スライダーの追加

HTML文書のbody要素

<body>
<!-- canvas要素を配置するdiv要素 -->
<div id="canvas-frame"></div>
x軸:<input type="range"	min="-50" max="50" value="0" step="1" id="px" />
y軸:<input type="range"	min="-50" max="50" value="0" step="1" id="py" />
z軸:<input type="range"	min="-50" max="50" value="0" step="1" id="pz" />
</body>

イベントの追加

////////////////////////////////////////////////////////////////////
// windowイベントの定義
////////////////////////////////////////////////////////////////////
window.addEventListener("load", function () {
threeStart(); //Three.jsのスタート関数の実行

//input要素によるスライダーのイベントの登録
document.getElementById("px").addEventListener("change", function () {
cube.position.x = parseFloat(this.value) ;
draw();	//<-----------------------------------------------------(※)
});
(省略:y軸・z軸についてのイベント)
});
				

(※)プロパティの変更後、再描画する必要があります。

オイラー角による回転

3次元オブジェクトの「rotation」プロパティの値を変更。

//input要素によるスライダーのイベントの登録
document.getElementById("px").addEventListener("change", function () {
cube.rotation.x = parseFloat(this.value) / 50 * Math.PI;
draw();
});
				

拡大・縮小

3次元オブジェクトの「scale」プロパティの値を変更。

//input要素によるスライダーのイベントの登録
document.getElementById("px").addEventListener("change", function () {
cube.scale.x = (parseFloat(this.value) + 50) / 50;
draw();
});
				

3次元ベクトルオブジェクト

「position、rotation、scale」の各プロパティは、
Vector3クラスのオブジェクト

方法1:Vector3クラスのx,y,zプロパティ

cube.position.x = ○;
cube.position.y = ○;
cube.position.z = ○;
				

方法2:Vector3クラスの新規オブジェクト

cube.position = new THREE.Vector3( ○, ○, ○ );
cube.rotation = new THREE.Vector3( ○, ○, ○ );
cube.scale		= new THREE.Vector3( ○, ○, ○ );
				

方法3:Vector3クラスのsetメソッド

cube.position.set( ○, ○, ○ );
cube.rotation.set( ○, ○, ○ );
cube.scale.set( ○, ○, ○ );
				

オイラー角について

指定した3つの軸による回転で任意の姿勢を実現する方法。
three.js → XYZ型オイラー角

ステップ1.X軸による回転(α度)

オイラー角について

ステップ2.Y'軸による回転(β度)

オイラー角について

ステップ3.Z''軸による回転(γ度)

各軸における回転角 α、β、γ で姿勢を指定(自由度3)。

オイラー角の難点

  • 任意の回転軸に対する回転を(α,β,γ)で表現することが困難。
  • 特定の状況で自由度が確保できない「ジンバルロック」と呼ばれる現象が存在。

任意の回転軸による回転の定義

3DCGの世界では、一般的にクォータニオンが利用される。

クォータニオンによる回転

ハミルトニアンによって定義された四元数

HTMLファイル:CubeGeometryQuaternion.html

クォータニオンによる回転

プログラムソース(CubeGeometryQuaternion.html)

////////////////////////////////////////////////////////////////////
// 描画関数の定義
////////////////////////////////////////////////////////////////////
function draw() {
var x = parseFloat(document.getElementById("px").value);
var y = parseFloat(document.getElementById("py").value);
var z = parseFloat(document.getElementById("pz").value);
var theta = Math.PI / 50 * parseFloat(document.getElementById("theta").value);
var axis = new THREE.Vector3(x, y, z).normalize();
//矢印オブジェクトの移動
arrow.setDirection(axis);
//クォータニオンを宣言
var q = new THREE.Quaternion();	//<--------------------------(※)
//回転軸と角度からクォータニオンをセット
q.setFromAxisAngle(axis, theta);	//<--------------------------(※)
//立方体オブジェクトの「quaternionプロパティ」に代入
cube.quaternion.copy(q);	//<-------------------------------(※)
//レンダリング
renderer.render(scene, camera);
}
				

メソッドチェーン

//立方体オブジェクトの「quaternionプロパティ」に代入
cube.quaternion.copy( new THREE.Quaternion().setFromAxisAngle(axis, theta));
					
  • 1. three.js の基本形
  • 2. 3次元オブジェクト
  • 3. 移動・回転・拡大
  • 4. アニメーション

アニメーションの原理

原理:関数内で自己関数を呼び出す無限ループ

無限ループ関数の定義

					function loop() {

						〜各時間ステップによる描画〜

						requestAnimationFrame(loop);
					}
					

requestAnimationFrame 関数(HTML5)

var requestAnimationFrame
	= window.requestAnimationFrame ||				 // 正式な実装
		window.webkitRequestAnimationFrame ||	 // Google Chrome、Safari向け
		window.mozRequestAnimationFrame ||			// Firefox向け
		window.oRequestAnimationFrame ||				// Opera向け
		window.msRequestAnimationFrame ||			 // InternetExplore向け
		function (callback, element) { window.setTimeout(callback, 1000 / 60); };
				

60[fps]で呼び出しを実行する関数。
three.js内で定義されています。

アニメーションの実装例1

HTMLファイル:CubeGeometryAnimation.html

					//グローバル変数の宣言
					var step = 0; //ステップ数
					function loop() {
						//ステップ数のインクリメント
						step++;
						cube.rotation.set( 0, 0, Math.PI/120 * step);
						//レンダリング
						renderer.render(scene, camera);
						//「loop()」関数の呼び出し
						requestAnimationFrame(loop);
					}
				

計算アルゴリズム:オイラー法

					//初期条件
					//グローバル変数の宣言
					var z = 60;		//位置
					var vz = 0;		//速度
					var g = - 9.8; //重力加速度
					var dt = 0.1;	//時間刻み
					function loop() {
						//速度の更新
						vz += g * dt;
						//位置の更新
						z += vz * dt;
						//当たり判定
						if(z < 0) {
							z = 0;
							vz = -vz;
						}
						sphere.position.set( 0, 0, z);
						//レンダリング
						renderer.render(scene, camera);
						//「loop()」関数の呼び出し
						requestAnimationFrame(loop);
					}
					

トラックボールコントロール:視点移動

TrackBallControls.html」ファイルをご覧ください

左ドラック:カメラの回転、右ドラック:視野中心の移動
ホイール:拡大・縮小

トラックボールの実装手順

1.トラックボール用のライブラリの読み込み

					<script src="javascript/three.js_r63/controls/TrackballControls.js"></script>
				

2.トラックボールオブジェクトの用意

					////////////////////////////////////////////////////////////////////
					// カメラ初期化関数の定義
					////////////////////////////////////////////////////////////////////
					//グローバル変数の宣言
					var camera;		//カメラオブジェクト
					var trackball; //トラックボールオブジェクト
					function initCamera() {
						(省略:カメラの準備)

						//トラックボールオブジェクトの宣言
						trackball = new THREE.TrackballControls(camera, canvasFrame);
						//トラックボール動作範囲のサイズとオフセットの設定
						trackball.screen.width = canvasFrame.clientWidth;												//横幅
						trackball.screen.height = canvasFrame.clientHeight;											//縦幅
						trackball.screen.offsetLeft = canvasFrame.getBoundingClientRect().left;	//左オフセット
						trackball.screen.offsetTop = canvasFrame.getBoundingClientRect().top;		//右オフセット

						//トラックボールの回転無効化と回転速度の設定
						trackball.noRotate = false;
						trackball.rotateSpeed = 3.0;	//<--------------------------(※1)

						//トラックボールの拡大無効化と拡大速度の設定
						trackball.noZoom = false;
						trackball.zoomSpeed = 2.0;	//<--------------------------(※2)

						//トラックボールのカメラ中心移動の無効化と中心速度の設定
						trackball.noPan = false;
						trackball.panSpeed = 0.5;	//<---------------------------(※3)
						trackball.target = new THREE.Vector3(0, 0, 0);

						//トラックボールのスタティックムーブの有効化
						trackball.staticMoving = true;
						//トラックボールのダイナミックムーブ時の減衰定数
						trackball.dynamicDampingFactor = 0.3;
					}
				

3.無限ループ関数内で情報の更新

				//トラックボールによるカメラオブジェクトのプロパティの更新
				trackball.update();
				

【第1部】three.js の基本
終了

three.jsの始め方