はじめての「three.js」で3D雪だるまを作ろう!
UI開発者 工藤(優)この記事はミツエーリンクスアドベントカレンダー2019の20日目の記事です。
今回はJavaScriptで手軽に3D表現ができるライブラリ「three.js」を使って雪だるまを作ります。
まずは完成品を見てみましょう。(※PC推奨)
See the Pen abzmPMv by kudo (@kudo3) on CodePen.
作成手順 5step
本記事では5つのステップに分けて作り方を説明していきます。
step1 「three.min.js」ファイルを公式サイトからダウンロード
公式サイト (https://threejs.org) から「three.min.js」ファイルをダウンロードしましょう。
サイドナビにあるCodeのdownloadを押すとすぐにダウンロードが始まります。
three.js-master.zipがダウンロードされますので、buildフォルダの「three.min.js」を使用します。
step2 htmlを作成
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>three.js snowman</title>
</head>
<body>
<style>
body {
margin: 0;
}
</style>
<div id="stage"></div><!--表示する領域-->
<script src="js/three.min.js"></script><!--three.min.jsを読み込む-->
<script>
(function () {
'use strict';
//ここにthree.jsの記述を書いていきます!
})();
</script>
</body>
</html>
step3 three.jsの記述を追加
step2で作成したhtmlの中に下記のコードを追加します。
const width = 460;
const height = 250;
// scene
const scene = new THREE.Scene(); //3Dを表現する空間
// mesh
//直方体のジオメトリー(幅, 高さ, 奥行き)
const buttonGeometry = new THREE.BoxGeometry(5, 5, 5)
//奥行きと影があり、光沢感のないマテリアル({ color: 0xから始まる16進数カラー})
const hatMaterial = new THREE.MeshLambertMaterial({ color: 0x333333 })
const headMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff })
const buttonMaterial = new THREE.MeshLambertMaterial({ color: 0x228b22 })
//3Dを2Dの手書き風にできるマテリアル({ color: 0xから始まる16進数カラー})
const eyeMaterial = new THREE.MeshToonMaterial({ color: 0x000000 });
const hat = new THREE.Mesh(
//円柱のジオメトリー(上面半径,下面半径,高さ,円周分割数)
new THREE.CylinderGeometry(25, 25, 40, 30),
hatMaterial
);
hat.position.set(0, 50, 0); //(x,y,z)
const hat_line = new THREE.Mesh(
new THREE.CylinderGeometry(26, 25, 20, 30),
new THREE.MeshLambertMaterial({ color: 0xe60033 })
);
hat_line.position.set(0, 35, 0);
const hat_collar = new THREE.Mesh(
new THREE.CylinderGeometry(40, 40, 5, 30),
hatMaterial
);
hat_collar.position.set(0, 32, 0);
const head = new THREE.Mesh(
//球のジオメトリー(半径,緯度分割数,経度分割数)
new THREE.SphereGeometry(40, 40, 20),
headMaterial
);
head.position.set(0, 0, 0);
const right_eye = new THREE.Mesh(
new THREE.SphereGeometry(5, 25, 40),
eyeMaterial
);
right_eye.position.set(15, 18, 30);
const left_eye = new THREE.Mesh(
new THREE.SphereGeometry(5, 10, 40),
eyeMaterial
);
left_eye.position.set(-16, 18, 33);
const nose = new THREE.Mesh(
new THREE.SphereGeometry(5, 30, 20),
new THREE.MeshLambertMaterial({ color: 0xed9121 })
);
nose.position.set(3, 10, 35);
const body = new THREE.Mesh(
new THREE.SphereGeometry(50, 50, 50),
headMaterial
);
body.position.set(0, -60, 0);
const button_first = new THREE.Mesh(
buttonGeometry,
buttonMaterial
);
button_first.position.set(0, -30, 37);
const button_second = new THREE.Mesh(
buttonGeometry,
buttonMaterial
);
button_second.position.set(0, -40, 43);
const snowman = new THREE.Group(); //メッシュをグループ化
snowman.add(hat,hat_line,hat_collar,head,right_eye,left_eye,nose,body,button_first,button_second);
scene.add(snowman); //3D空間にsnowmanを配置
// light
//平行光源(ディレクショナルライト):一方向から同じ強さで平行に照らすライト(色, 光の強さ)
const light = new THREE.DirectionalLight(0xffffff, 0.9);
light.position.set(0, 50, 30); //ライトの位置(x,y,z)
scene.add(light); //シーンにディレクショナルライトを追加
//環境光源(アンビエントライト):すべてを均等に照らす、影のない、全体を明るくするライト
const ambient = new THREE.AmbientLight(0xf8f8ff, 0.9);
scene.add(ambient); //シーンにアンビエントライトを追加
// camera
//遠近感のあるカメラ(視野角,上映するスクリーンの縦横比,カメラから手前までの距離,カメラから奥までの距離)
const camera = new THREE.PerspectiveCamera(90, width / height, 1, 1000);
camera.position.set(60, 50, 140); //(x,y,z)
camera.lookAt(scene.position); //カメラの視点(注視点)
// renderer
const renderer = new THREE.WebGLRenderer({ antialias: true }); //メッシュの輪郭を滑らかに表示
renderer.setSize(width, height); //幅と高さを設定
renderer.setClearColor(0xe6e6fa); // 空間の背景色
renderer.setPixelRatio(window.devicePixelRatio); //高解像度対応
document.getElementById('stage').appendChild(renderer.domElement); //div要素にcanvasを追加
function render() {
requestAnimationFrame(render); //再度render関数を実行
renderer.render(scene, camera); //シーン, カメラをもとに描画
snowman.rotation.y += 0.01; //反時計周りにsnowmanを回転
}
render();
step4 three.jsの知識
three.jsには、5つの要素があります。 各要素の役割についてみてみましょう。
- 1.scene:3Dを表現する空間
- 2.mesh:物体(geometryとmaterialを組み合わせたもの)
- geometry:物体の形状(円柱、球、直方体、ドーナツ型など)
- material:物体の素材(光沢感や影、色など)
- 3.light:光源
- 4.camera:視点
- 5.renderer:画面に表示
5つの要素を図で考えると、
薄紫の背景(1.scene)に配置された雪だるま(2.mesh)を太陽(3.light)が照らし、その様子をカメラ(4.camera)で撮影しながらサンタクロース(5.renderer)がディスプレイに投影する仕組みです。
step5 マウスでカメラを操作
three.jsには、カメラを操作する機能があります。
現在のままだと、反時計回りに雪だるまが動くだけになりますので、
遊び心を加えて、いろいろな角度から雪だるまを見られるようにしましょう!
OrbitControls.jsファイルを準備
最初にダウンロードした、 three.js-master.zipの中にある「OrbitControls.js」を使用します。
htmlに記述を2つ追加
1.OrbitControls.jsを読み込む記述を追加
<script src="js/OrbitControls.js"></script>
2.OrbitControlsを追加 第二引数にcanvas要素を渡します。
var controls = new THREE.OrbitControls(camera, renderer.domElement);
これで完成です!
終わりに
今回は、円柱(CylinderGeometry)・球(SphereGeometry)・直方体(BoxGeometry)の3種のmeshを組み合わせて、3D雪だるまを作りました。
three.jsでは、この他にも
- 3D文字を作ること
- 3D空間に粒子を散らすこと(Particleと言います)
- 3Dオブジェクトの表面に画像を張り付けること などのさまざまな表現をすることができます。
みなさまもこの冬、three.jsで遊んでみてはいかがでしょうか。
参考文献
- three.js公式
- three.js入門|ドットインストール
- three.js 入門|LinkedInラーニング
- 『初めてのthree.js 第2版 ―WebGLのためのJavaScript 3Dライブラリ』O'Reilly Japan
ありがとうございました。