ブログ

BLOG

Three.jsで3D的表現に挑戦!

OB・OG Other Blog

まなべぇです。
ウェブデザインのギャラリーサイトを見ていると、配色や配置がキレイなサイトはもちろんですが
「これ、どうやって作ってるんだ!?」と思うようなサイトに出会う時ってありますよね。
メインビジュアルが動画みたいにぐにゃぐにゃ動いたり、カーソルに合わせて派手なエフェクトが登場したり…。
サイトによって手法は様々ではありますが、WebGLで実装している事が多いようです。

WebGLって何??

一言で表すと「ブラウザで3DCGを表示させるための標準仕様」です。
2011年リリースと新しい技術では無いのですが、現在(2019年)ほぼ全てのブラウザで対応しています。


引用:Can I use...

Three.jsって何??

WebGLを手軽に実装することができるJavaScriptライブラリです。
JavaScriptのファイル内で飛び交う記号や黒背景のエディターを見るだけでクラクラしてくる自分でも頑張ればできるかな…と思えるくらいのお手軽さ。
どういうものが実装できるのかは一度公式サイトに掲載されているデモを見てみる事をおすすめします。
中にはブラウザゲームのようなものもあったりと自由度高め。

入門編 - 簡単な3Dオブジェクトを表示させる

 1.ダウンロード

公式サイトの【download】からファイルをダウンロードします。
three.js-masterファイルを解凍し【build】フォルダ内のthree.min.jsを作業フォルダ内に移動させます。

 

2.html作成

three.jsを読み込むhtmlを作成します。


index.html
<!DOCTYPE html>
<html lang="ja">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1"/>
 <title>three.js</title>
 <meta name="robots" content="noindex,follow">
</head>
<body>
 <canvas id="canvas"></canvas>
 <script src="three/three.min.js"></script>
 <script src="three/setting.js"></script>
</body>
</html>

 

3.基本設定

setting.jsに基本のコードを書き込んでいきます。


setting.js
$(function(){
 //基本設定
 var width = 900;//横幅
 var height = 900;//縦幅

 var renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector("#canvas"),//id="canvas"に描画
  alpha: true //背景を透過する
 });
 renderer.setPixelRatio(window.devicePixelRatio);
 renderer.setSize(width, height);
 var scene = new THREE.Scene();

 // カメラ設定
 var camera = new THREE.PerspectiveCamera(3,width / height,1,10000);//視野角,縦横比,手前の距離,奥の距離
 camera.position.set(0, 0, 1000);//カメラ位置
    
 // ライト設定
 ambientLight = new THREE.AmbientLight(0xffffff);//環境光源
 hemisphereLight = new THREE.HemisphereLight(0xffffff,0x4169e1, 0.5);//半球光源
 scene.add(hemisphereLight);
 scene.add(ambientLight);

 // 実行
 animate();
 function animate(){
   renderer.render(scene, camera);
 };
});

これでthree.jsを表示させる土台ができました。

 

4.ボックスを表示させる

土台だけで何も要素が入っていない状態のため、ボックスを追加します。
scene.add(ambientLight);の下に以下のコードを追加します。


setting.js
 // ボックス
 var geometry = new THREE.BoxGeometry(10, 10, 10);//x,y,z
 var material = new THREE.MeshStandardMaterial({color: 0xaaaaaa});
 var box = new THREE.Mesh(geometry, material);
 scene.add(box);

ここまでの結果がこちら。

【DEMO】※PCでの閲覧推奨

ブラウザ上でボックスを表示させることができました。
今は単純なボックスですが、ここからボックスを円に変えたり、ランダムに大量のボックスを表示させたり…と様々なものに応用することができます。

 

応用編 - メインビジュアルっぽいものを作る

これまで作成したファイルを応用して以下を実装していきます。

・3Dモデルの表示
・マウスでのカメラ操作
・画面リサイズ

1.3Dモデルの用意

MagicaVoxelBlenderというフリーソフトで作成しました。
MagicaVoxelはモデリングの知識が無くても、3Dモデルを直感で簡単に作成する事ができるソフトです。
モデリングの知識がある方はBlender一本で作成できますが、今回はMagicaVoxelで作った3Dモデルをブラウザで読み込める形式にエクスポートするために使用しました。

我が家の愛犬(かわいい)と自室(理想)とペンギン(個人の趣味)。
MagicaVoxelの操作・モデリング方法は割愛します。機会があれば今後の記事で紹介する予定です。

Blenderで作成した3Dデータを読み込み、obj,mtl形式に変換します。

 

2.ファイルの追加

先程ダウンロードしたthree.js-masterから以下を作業フォルダ内に移動させます。
・examples/js/controls/OrbitControls.js (マウスでのカメラ操作用)
・examples/js/loaders/OBJLoader.js (3Dモデルの表示用)
・examples/js/loaders/MTLLoader.js (3Dモデルの表示用)

htmlへの読み込みも忘れずに。


index.html
<script src="three/three.min.js"></script>

<!-- 追加 -->
<script src="three/OrbitControls.js"></script>
<script src="three/OBJLoader.js"></script>
<script src="three/MTLLoader.js"></script>

3.setting.jsにコード追加

setting.jsにコードを追加していきます。


setting.js
 //基本設定
 var width = 900;
 var height = 900;

 var renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector("#canvas"),
  alpha: true
 });
 renderer.setPixelRatio(window.devicePixelRatio);
 renderer.setSize(width, height);
 var scene = new THREE.Scene();

 // カメラ設定
 var camera = new THREE.PerspectiveCamera(3,width / height,1,10000);
 camera.position.set(1,300, 500); 
    
 // ライト設定
 ambientLight = new THREE.AmbientLight(0xffffff);
 hemisphereLight = new THREE.HemisphereLight(0xffffff,0x4169e1, 0.15);
 scene.add(hemisphereLight);
 scene.add(ambientLight);

 // ★追加 マウス操作
 var controls = new THREE.OrbitControls(camera);
 controls.enableZoom = false;
 controls.autoRotate = true;

 // ★追加 MTL,Obj読み込み
 new THREE.MTLLoader().setPath('./three/')
 .load('table.mtl',
 function(materials){
  materials.preload();
  new THREE.OBJLoader().setPath('./three/').setMaterials(materials).load('table.obj',
  function(object){
   objmodel = object.clone();
   obj = new THREE.Object3D();
   obj.add(objmodel);
   obj.position.set(0, -1.2, 0);
   scene.add(obj);        
  }
  );
 });
 var obj = new THREE.Mesh();

 // 実行
 animate();
 function animate(){
  requestAnimationFrame(animate);//★追加 アニメーション実行
  obj.rotation.y += 0.002; //★追加 3Dオブジェクトを自動回転させる
  renderer.render(scene, camera);
 };

 // ★追加 画面リサイズ
 onResize();
 window.addEventListener('resize', onResize);

 function onResize() {
  var width = window.innerWidth;
  var height = window.innerHeight;

  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);

  camera.aspect = width / height;
  camera.updateProjectionMatrix();
 }
 });

ボックスから3Dモデルに変更するにあたって、カメラとライトの設定を微調整しています。

そして完成したのがこちら。

【DEMO】※PCでの閲覧推奨

背景色とテキストを足してメインビジュアル風にしてみました。
ドラッグすると3Dモデルがグリグリ動きます。

まとめ

3Dを加えることでインパクトのあるビジュアルができました。
もう少し凝ったエフェクトなんかも実装していきたいので、これからは真面目にJavaScriptの勉強をしていこうと思います。