こんにちは、エンジニアののびすけです。最近毎日ハムスターになる夢を見ます。
前回の記事「圧倒的な3D表現にWebの未来を感じるWebGLを使ったサイト・デモ20選」にまとめましたが、WebGLを使ったサイトが最近話題になっていますね。
従来の平面で考えるWebの時代から次の時代への移り変わりを感じる今日この頃です。
今回は実際にWebGLを使った3D表現にチャレンジしてみます。
JavaScriptで記述しますが、初心者向けにまとめたのでノンプログラマやデザイナーの方にもチャレンジしてほしいです!実際にコード書くところは5分(早い人なら1分)でできると思います。
そもそもWebGLとは
PC上で3Dを描画するための技術にOpenGLというものがあります。OpenGLは3DグラフィックスAPIとも呼ばれていて、様々なプラットフォームに対応しており、広く普及しています。
このOpenGLをWebブラウザから操作することを可能にした技術がWebGLになります。WebGLはJavaScriptを使って操作することが可能なので、Web制作者が3D表現をする際の敷居を大きく下げてくれました。
そしてGoogleChromeなどの主要ブラウザでWebGLの対応が進んできたおかげで、新しいWebの表現手法として注目されています。
参考: WebGL による 3D 開発: 第 1 回 WebGL の紹介
参考: WebGL OpenGL ES 2.0 for the Web
https://www.khronos.org/webgl/
対応ブラウザ
WebGL利用の可否はページを表示するブラウザの性能に依存します。Can I Use …というサイトでHTML5界隈の技術のブラウザ対応状況を調べることができるので、チェックしてみました。
これを見ると分かりますが、現時点(2014年6月)ではIE10以前が対応していないだけで、それ以外のPCブラウザでは対応しているみたいです。
でも、スマートフォンのブラウザではまだまだ未対応が多いみたいですね。iOSの次期バージョンとBlackberryではWebGLを利用することができるみたいです。
参考:Can I Use … WebGL
https://caniuse.com/#search=webGL
その他のHTML5の機能
今回の記事はWebGLがメインの内容ですが、HTML5のAPIは他にも色々とあるので、調べてみるともっとWebの未来を感じられると思います!
WebRTCやWebSocketなんかも組み合わせると更に色々な表現ができそうです。これらのブラウザ対応状況もCan I Useで調べることができます。
参考:HTML5と WebSocket / WebRTC / Web Audio API / WebGL 技術解説
参考:ようこそ、HTML5裏APIの世界へ – HTML5 Conference 2013
WebGLで3Dにチャレンジしてみよう
今回はWebGLをJavaScriptからカンタンに扱えるライブラリ「Three.js」を使った書き方を紹介したいと思います。
Three.jsとは
WebGLをJavaScriptから操作するためのライブラリです。他にもBabylon.jsやAway3D、CubicVR.jsといったライブラリもありますが、最近ではWebGLを使って3D表現をする際にはThree.jsを使うことがデファクトスタンダードになりつつある印象です。
Web制作などではjQueryがデファクトスタンダードになっていますが、それに近い関係だと思います。
参考: WebGL 対応のライブラリの比較 – Qiita
作ってみましょう
細かいところは気にせずにコードを真似て(もしくはコピペで!)書いてみましょう。ここから5分で3D表示までできます!(5分でやる場合は解説をあとで読んでみてください笑)
こちらの公式チュートリアルをもとに進めてみます。
1. Three.jsの準備
何はともあれ、Three.jsをダウンロードしましょう。
まず、Three.jsのサイトからダウンロードします。
左のサイドバーのdownloadリンクからダウンロードできます。
mrdoob-three.js-〜.zipという圧縮ファイルがダウンロードできるので展開しましょう。ここではThreejsというフォルダを作ってその中にダウンロードしました。
展開したフォルダの中の、buildフォルダにあるthree.min.jsをコピーしましょう。
場所はどこでも良いのでコピーしたthree.min.jsを設置して、同じフォルダにindex.htmlというファイルを作りましょう。ここではlessonというフォルダの中にthree.min.jsを設置してindex.htmlを作りました。
参考:Three.js
2. HTMLを用意する
先程用意したindex.htmlに以下を記述しましょう。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Threejsの練習</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
/*ここに3Dを表現する記述を書いていきます*/
</script>
</body>
</html>
- 補足
8行目:先程設置したthree.min.jsを読み込んでいます。
10行目:コメントなので記述しなくて大丈夫です。
3. シーンを作る
↑の11行目のコメント部分に以下を追記しましょう。
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
- 解説: ここでは画面全体の設定をしています。
1行目:シーンを作ります。
2行目:カメラを作ります。
3行目:レンダラーを作ります。
4行目:レンダラーサイズを設定します。
5行目:レンダラーをbodyに設定しています。
- 用語の説明
シーン・・・3D表現をする空間です。
カメラ・・・シーン内で表示する場所を決めます。
メッシュ・・・3Dオブジェクト(物体)を指します。メッシュはジオメトリーとマテリアルから構成されます。
ジオメトリー・・・座標やメッシュの形です。
マテリアル・・・表面素材やメッシュの色です。
レンダラー・・・用意したシーン、メッシュを画面に表示させる命令です。
4. キューブを作る
更に追記していきましょう。
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
- 解説:3Dオブジェクトの設定をしています。
1行目:3Dオブジェクトの形と大きさを設定しています。キューブ(立方体)で1cm四方の大きさです。
2行目:3Dオブジェクトの素材と色を設定しています。素材はデフォルト設定で、色は緑です。
3行目:↑の設定に基づいて、3Dオブジェクトを作成しています。
4行目:作成された3Dオブジェクトを③で設定したシーンに適応させます。
5行目:表示する際のカメラの角度を設定しています。(ここだけカメラ設定なので若干性質が違いますね)
5. シーンをレンダリングする
更に追記していきましょう。
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
- 解説:3.と4.で設定したsceneやcameraを実際に表示させるための設定です。
とりあえずここでひと段落です。index.htmlをブラウザで動作させてみましょう。index.htmlをブラウザにドラッグ&ドロップすればOKです。
※ブラウザはGoogle Chrome推奨です
こんな感じで緑色のキューブが表示されていれば成功です! 🙂
⑥キューブを動かす
5.の2行目と3行目の間に以下を追記してみましょう。
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
- 解説: 3Dオブジェクトに回転を掛けています。
1行目:3Dオブジェクトをx軸に0.1度/秒で回転させます。
2行目:3Dオブジェクトをy軸に0.1度/秒で回転させます。
デモA
完成版のソースコード
ここまでの流れで上手くいかなかった方は、以下のソースコードをindex.htmlにコピペして試してみましょう。それでも上手くいかない場合は、three.min.jsが同じ階層にあるか確認してみてください。
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
お疲れ様でした!カンタンに3D表現ができましたね。
これで皆さんも3DCGエンジニアの仲間入り(?)ですね!
まだ物足りない人は次のステップもやってみてください! ^^b
LIGのロゴを3Dで作ってみる!
クリエイティブな方なら、3Dでキューブを作っただけで満足ってことはないですよね?
ということで、LIGのロゴを3Dで作ってみました。
今度のデモはマウス操作でグリグリ動かせますので試してみて下さい。
デモB
ソースコードはこんな感じです。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Threejsの練習</title>
</head>
<body>
<script src="three.min.js"></script>
<script src="OrbitControls.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 600 / 400, 1, 1000);
camera.position.set(50, 0, 100);
renderer = new THREE.WebGLRenderer();
renderer.setSize(655, 437);
document.body.appendChild(renderer.domElement);
var directionalLight = new THREE.DirectionalLight('#ffffff', 1);
directionalLight.position.set(0, 7, 10);
scene.add(directionalLight);
var geometry = new THREE.BoxGeometry(12, 12, 12);
var material = new THREE.MeshPhongMaterial({color: 'white'});
var cube = [];
var position = [
[-15,0,0],
[-15,15,0],
[-15,30,0],
[-15,45,0],
[-15,60,0],
[0,0,0],
[15,0,0],
[30,0,0],
[60,0,0],
[60,15,0],
[60,30,0],
[60,45,0],
[60,60,0],
[90,60,0],
[90,45,0],
[90,30,0],
[90,15,0],
[90,0,0],
[105,0,0],
[120,0,0],
[135,0,0],
[105,60,0],
[120,60,0],
[135,45,0],
[135,15,0],
];
for (var i = 0; i < position.length; i++) {
cube[i] = new THREE.Mesh(geometry, material);
cube[i].position.set(position[i][0]-60,position[i][1]-30,position[i][2]);
scene.add(cube[i]);
};
var controls = new THREE.OrbitControls(camera, renderer.domElement);
function render() {
requestAnimationFrame(render);
for (var i = 0; i < cube.length; i++) {
cube[i].rotation.x += 0.01; // 追加
cube[i].rotation.y += 0.01; // 追加
};
controls.update();
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
- 解説
14行目:カメラの位置ですが、x=50で少し右側から、z=100でちょっと引き気味の位置から表示させています。
9,62,72行目:3D空間をマウスでコントロールできるようにしています。
20〜22行目:シーンに対して光の設定をしています。
27行目:今回はcubeをいくつも作るので配列として変数定義します。
28〜54行目:各cubeを設置する場所(ポジション)を設定しています。ここの配列の数で設置するcubeの数も決めています。
56〜60行目:各cubeを各ポジションに設置していきます。
マウスコントロールをするためにはOrbitControls.jsをindex.htmlやthree.min.jsと同じフォルダに設置しましょう。
場所は examples > js > controls > OrbitControls.js となっています。
これで終了です!実際にLIGのロゴがブラウザ上に表示されたでしょうか?
今回作ったサンプルはGithubで公開しているのでコメントなどもお待ちしております。
参考: Javascriptで簡単3D!three.jsを使ったWebGLプログラミング! | nanapi TechBlog
参考: n0bisuke/practice_threejs
https://github.com/n0bisuke/practice_threejs
まとめ
いかがでしたでしょうか。Three.jsを使うことで、とてもカンタンな記述で3Dの表現が可能になったと思います。ノンプログラマでも3Dの表現をする敷居がグッと下がったのではないでしょうか。
これからはブラウザ性能がドンドン上がっていくはずですし、ほぼ確実にWebGLが扱えるブラウザが標準的になっていくことが予想されます。
iPhoneではiOS8からWebGLが対応されるということなので、次はスマホ×3Dというコンテンツが“来る”と個人的にはニラんでいます。
そうなったときにWebGLを使った3Dコンテンツを自在に生み出せれば、新たな市場開拓ができて、周りと差が付くかもしれませんね。是非チャレンジしてみましょう!
もし今回のソースコードでここが分からん!という質問などがあればコメントください。
それでは!
キャリアアップ
「Studio上野でWebクリエイターを目指す!」
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。