
デザイナー・ノンプログラマにおすすめしたいThree.jsのカンタン3D体験
こんにちは、はっちゃんです。
今回は、もはやお馴染み、WebGLを簡単に扱えるライブラリー「three.js」をご紹介します。WebGLを使った3D表現が一般的になってきたとはいえ、実際取り入れられていない方も多いと思います。
そこで今回は、自分の勉強を兼ねて、できるだけ詳しくまとめてみましたので、これから覚えようとしているフロントエンドやデザイナーの方の参考になれば幸いです。
JavaScriptから利用できるAPIで、ブラウザー上で3DCGプログラミングを実現できる技術です。ブラウザーを通してデバイスのGPUにアクセスすることができます。
下記の記事でもまとめをしているので、気になる方はこちらもあわせてどうぞ。
デザイナー・ノンプログラマにおすすめしたいThree.jsのカンタン3D体験 圧倒的な3D表現にWebの未来を感じるWebGLを使ったサイト・デモ20選
WebGLをそのまま扱おうとすると、APIの扱いに冗長な準備が必要になってしまい、とても高度な技術を要します。
そこで、JavaScriptライブラリーを通して、それらを簡単に取り扱うことができるものが登場しました。それがthree.jsです。
それではさっそく使ってみましょう。
最初に3DCGを描画する領域を用意し、その後にライブラリーを読み込みます。zipで落としてきたり、npmでインストールする方法もあるのですが、今回はCDNで読み込みます。
<div id="stage"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
これで準備は完了です。簡単ですね。
ここからはjsをガンガン書いていきましょう。
物体(メッシュ)を置くためのステージ(シーン)を用意します。
three.jsを読み込んだことで、THREEというオブジェクトが使えるようなったので、このように記述します。
(function() {
var scene;
scene = new THREE.Scene(); // scene ステージ
})();
何もない空間に、これから表示する要素の土台だけがある状態です。
次は、メッシュを用意します。また、今回は球体を作ろうと思うので、Mesh関数の引数に、以下の関数を渡します。
new THREE.BoxGeometry(幅, 高さ, 奥行き)
SphereGeometry・・・球体を作る
new THREE.SphereGeometry(半径, 経度分割数, 緯度分割数, 開始経度, 経線中心角, 開始緯度, 緯線中心角)
CylinderGeometry・・・円柱を作る
new THREE.CylinderGeometry(上面の半径, 底面の半径, 高さ,円周の分割数, 高さの分割数, フタをしない:true,フタをする:false)
new THREE.MeshLambertMaterial({color: 0xから始まる16進数})
その後、set関数で配置する位置(幅, 高さ, 奥行き)を決め、add関数でシーンに反映させます。
まとめると以下のようなコードになります。
(function() {
var scene;
var sphere;
// scene ステージ
scene = new THREE.Scene();
// mesh 物体
sphere = new THREE.Mesh(
new THREE.SphereGeometry(100, 20, 20), // geometry 形状
new THREE.MeshLambertMaterial({color: 0x8dc3ff}) // material 材質、色
);
sphere.position.set(0, 0, 0);
scene.add(sphere);
})();
カメラ越しに物体を見るイメージになるので、シーンにカメラを設置します。
PerspectiveCamera関数の引数に、以下の値を渡します。
new THREE.PerspectiveCamera(画角, アスペクト比, ニアークリップ, ファークリップ)
OrthographicCamera・・・正投影。物体の見た目の大きさが視点からの距離によらず、変わらない(どこから見ても物体のサイズは同じ)
new THREE.OrthographicCamera(画角, アスペクト比, ニアークリップ, ファークリップ)
その後、カメラの位置とカメラの向きを設定します。
カメラの向きは、lookAt関数を使用します。シーンの方を向かせたいので、以下のようにしまししょう。
camera.lookAt(scene.position);
まとめると以下のようなコードになります。
(function() {
var scene;
var sphere;
var camera;
var width = 500;
var height = 250;
// scene ステージ
scene = new THREE.Scene();
// mesh 物体
sphere = new THREE.Mesh(
new THREE.SphereGeometry(100, 20, 20), // geometry 形状
new THREE.MeshLambertMaterial({color: 0x8dc3ff}) // material 材質、色
);
sphere.position.set(0, 0, 0);
scene.add(sphere);
// camera
camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
camera.position.set(200, 100, 300);
camera.lookAt(scene.position);
})();
いよいよレンダリングです。今まで設定したものをHTMLと紐付けます。
今回レンダラーにはWebGLRendererを使用します。
new THREE.WebGLRenderer({ antialias: true})
CanvasRenderer・・・一般的に2Dグラフィックスを描画するときに使用するCanvas2Dで、3Dグラフィックスを実現する。CPUで演算を行うため3Dグラフィックス処理において実行速度が遅い。Three.jsの一部の機能しか使えないが、対応しているブラウザが多い。
次にsetSize関数とsetClearColor関数とで、
<div id="stage"></div>
にセットするサイズと背景色を指定します。
色は0xから始まる16進数で記述します。その後、idからDOMオブジェクトを取得し、appendChildでcanvasタグをdiv内にセットします。
最後にrender関数の引数にsceneとcameraを渡し、レンダリング完了です。まとめると以下のようなコードになります。
(function() {
var scene;
var sphere;
var camera;
var renderer;
var width = 500;
var height = 250;
// scene ステージ
scene = new THREE.Scene();
// mesh 物体
sphere = new THREE.Mesh(
new THREE.SphereGeometry(100, 20, 20), // geometry 形状
new THREE.MeshLambertMaterial({color: 0x8dc3ff}) // material 材質、色
);
sphere.position.set(0, 0, 0);
scene.add(sphere);
// camera
camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
camera.position.set(200, 100, 300);
camera.lookAt(scene.position);
// renderer
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width, height);
renderer.setClearColor(0xeeeeee);
document.getElementById('stage').appendChild(renderer.domElement);
renderer.render(scene, camera);
})();
codepenにも同じコードを用意したので、実際に見てみましょう。
See the Pen three.js sample1 by k_hatsushi (@hatsushi_kazuya) on CodePen.
球体は表示できていますが、真っ暗ですね。
私たちの住んでる世界も同じですが、物体は光が当たらないと目には見えませんよね? WebGLを扱う場合も光が必要で、光源を設置してあげなければいけません。
new THREE.DirectionalLight(0xから始まる16進数, 光の強さ)
PointLight・・・点光源。1点から放射状に光を放つ光源。その為影は物体の位置に影響され、地面と物体の距離が離れるほど影は大きくなる。
AmbientLight・・・環境光自然光の乱反射をシュミレートする光源。全方向に光が当たる。よりリアルな光や影を演出するための補足として使用。
光源の設定をしたら、位置を設定し、シーンに追加します。
(function() {
var scene;
var sphere;
var camera;
var light;
var renderer;
var width = 500;
var height = 250;
// scene ステージ
scene = new THREE.Scene();
// mesh 物体
sphere = new THREE.Mesh(
new THREE.SphereGeometry(100, 20, 20), // geometry 形状
new THREE.MeshLambertMaterial({color: 0x8dc3ff}) // material 材質、色
);
sphere.position.set(0, 0, 0);
scene.add(sphere);
// light
light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 100, 30);
scene.add(light);
// camera
camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000);
camera.position.set(200, 100, 300);
camera.lookAt(scene.position);
// renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
renderer.setClearColor(0xeeeeee);
document.getElementById('stage').appendChild(renderer.domElement);
renderer.render(scene, camera);
})();
それではどんな風に表示されたか実際に見てみましょう。
See the Pen three.js sample2 by k_hatsushi (@hatsushi_kazuya) on CodePen.
光のおかげで色と影が見えるようになりました。
基本的な流れは、
になるのがわかるかと思います。
次回は、物体をマウスや自動で動かしたり、画像を物体に反映させてみようと思います。