3DやWebGLをネーティブでコーディイングするのはやっぱり大変! Flashだと「Alternativa3D」「 Away3D」「Papervision3D」らが有名ですが、JavaScriptの場合は「Three.js」「Sprite3D.js」「jQuery 3D」とかでしょうか?
この中でも「Three.js」が一番強力そう(妄想)なので試してみる事に。
この中に「example」があるので動作確認できます。
THREE.js Doc 引数説明とサンプルがあるので、どういう動作するのかの材料になるかと。
とりあえずメインの「three.js(three.min.js)」とパフォーマンス監視ツール「Stats.js」を読み込む
グラフィック描画するベースのhtml要素を追加し、JavaScriptで取得する。 ここまでは、何の知識もいらないかと。
var container;
container = document.getElementById('container');
3Dオブジェクトの視点であるCameraを追加するが、今回はOrthographicCamera()を利用する。
var left = window.innerWidth / - 2;
var right = window.innerWidth / 2;
var top = window.innerHeight / 2;
var bottom = window.innerHeight / - 2;
var camera = new THREE.OrthographicCamera(left, right, top, bottom, -2000, 1000);
camera.position.x = 200;
camera.position.y = 100;
camera.position.z = 200;
引数の内容は、
OrthographicCamera(left, right, top, bottom, near, far, projectionMatrix)
ちなみに、現在3種類のカメラがある。
・THREE.OrthographicCamera:平行投影(正投影) ・THREE.PerspectiveCamera:透視投影 ・THREE.CombinedCamera:透視投影と平行投影の複合
Sceneはグラフィックオブジェクトを配置する元のオブジェクトです。
scene = new THREE.Scene();
Three.jsの3Dオブジェクトは以下のものがあります。
・THREE.CubeGeometry ・THREE.CylinderGeometry ・THREE.ExtrudeGeometry ・THREE.IcosahedronGeometry ・THREE.LatheGeometry ・THREE.OctahedronGeometry ・THREE.PlaneGeometry ・THREE.SphereGeometry ・THREE.TorusGeometry ・THREE.TorusKnotGeometry ・THREE.BinaryLoader ・THREE.UTF8Loader
だいたい名前で想像がつくが、今回は直方体の CubeGeometry を利用。
MeshLambertMaterial() で光反射のマテリアルを作成。 元の3Dオブジェクトとマテリアルを引数に、Mesh()でCubeオブジェクトを作成し、Sceneに追加します。 (Three.jsの場合、Cubeオブジェクトというよりメッシュと言った方が通じるか?)
var geometry = new THREE.CubeGeometry(50, 50, 50);
var params = {
color: 0xffffff,
shading: THREE.FlatShading,
overdraw: true
};
var material = new THREE.MeshLambertMaterial(params);
var cube = new THREE.Mesh(geometry, material);
cube.scale.y = Math.floor(Math.random() * 2 + 1);
cube.position.x = Math.floor((Math.random() * 1000 - 500) / 50) * 50 + 25;
cube.position.y = (cube.scale.y * 50) / 2;
cube.position.z = Math.floor((Math.random() * 1000 - 500) / 50) * 50 + 25;
scene.add(cube);
Lightを追加する事で、3Dに影をつけて奥行き感を出します。
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.x = 0.5;
directionalLight.position.y = 1.5;
directionalLight.position.z = 3.5;
directionalLight.position.normalize();
scene.add(directionalLight);
var ambientLight = new THREE.AmbientLight(0x10);
scene.add(ambientLight);
Lightには以下のものがある。
・THREE.AmbientLight ・THREE.DirectionalLight ・THREE.PointLight ・THREE.SpotLight
どう違うかは、後に調べてみよう。。。
Renderer系には以下の種類があるようだが、今回は無難に CanvasRenderer を利用する。
・CanvasRenderer ・WebGLRenderer ・DOMRenderer ・SVGRenderer
CanvasRenderer.domElement をcontainer(HTML要素)に追加後、Scene と Camera をレンダリングする。
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
renderer.render(scene, camera);
とりあえず3D静止オブジェクトが描画される。
アニメーションさせる場合は requestAnimationFrame() で時間軸をつけてやる。
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
var timer = Date.now() * 0.0001;
camera.position.x = Math.cos(timer) * 200;
camera.position.z = Math.sin(timer) * 200;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
animate() でrequestAnimationFrame()を連続で呼び、render()で状態に応じてレンダリング処理している。
Cube Sample
Chrome環境で、テクスチャーをつけてないので結構スムーズに動きます。 何となく、Papervision3Dに近い気がしました。 ただ、これだけのサンプルだと何のイベントもないので「で?」ですねw 次は、イベント使ったサンプルを調べてみよう。