2018年もあと少し、気持ちも慌ただしくなってきた師走にちょっとワクワクしてみたいなと思い、
気軽にブラウザで3Dコンピュータグラフィックス(以下3DCG)を実装できる、WebGL、three.jsの記事を書いてみました。
とりあえず、今日はテキストエディタだけあればコピーandペーストで実装できる超簡単3DCGを実装してみます。
実装の前にざっくりとWebGL、three.jsについて説明します。
wikipediaによると
ウェブブラウザで3次元コンピュータグラフィックスを表示させるための標準仕様。
MDN web docsによると
互換性があるウェブブラウザーでプラグインを使用せずにインタラクティブな 3D グラフィックスや 2D グラフィックスをレンダリングするための JavaScript API です。
と説明があります。
Flash PlayerやUnity Web Playerのようなブラウザ・プラグインを必要とせずにブラウザで3DCGが表示できちゃう、
PCのみならずスマートフォンでも表現できちゃう、
というマルチプラットフォームなJavaScriptのAPIです。(しかもGPUを利用して高速!)
2018年12月現在の対応ブラウザは以下の通りです。(Can I useより)
現時点での最新版は2.0ですが
初版は2011年3月3日(7年前)
と結構昔から開発されていました。(wikipediaより)
(というわけで、新しい技術!とかではないです…)
ただし、WebGLはhtml5のcanvasタグの領域に描画するのですが、
3Dを2D(画面上)で表現するための座標変換だとか、
そのためのGLSLと呼ばれるシェーディング言語を習得しないといけなかったり、
専門知識が必要だったりと、WebGLのみで3DCGを表現しようとすると難易度がかなり高いです。
そこでJavaScriptの知識だけで簡単にWebGLを扱えるライブラリが存在します。
そのうちのひとつがthree.jsです。
three.jsを使えば簡単に3DCGコンテンツが作成できます。
以下のような四角い箱を作ってみます。
※今回、とりあえずブログ記事中でコンテンツをプレビュー表示するためにCodePenを利用しています。
ソースはこちら
<html> |
<head> |
<meta charset="utf-8" /> |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script> |
<script> |
window.addEventListener('load', init); |
function init() { |
// サイズを指定 |
const width = 712; |
const height = 397; |
// レンダラーを作成 |
const renderer = new THREE.WebGLRenderer({ |
canvas: document.querySelector('#myCanvas') |
}); |
renderer.setPixelRatio(window.devicePixelRatio); |
renderer.setSize(width, height); |
// シーンを作成 |
const scene = new THREE.Scene(); |
// カメラを作成 |
const camera = new THREE.PerspectiveCamera(45, width / height); |
camera.position.set(0, 0, +1000); |
// 箱を作成 |
const geometry = new THREE.BoxGeometry(400, 400, 400); |
// マテリアルにテクスチャーを設定 |
const material = new THREE.MeshNormalMaterial(); |
// const material = new THREE.MeshBasicMaterial({ color: '#124dae' }); //素材を変えることができる |
const box = new THREE.Mesh(geometry, material); |
scene.add(box); |
animate(); |
// 毎フレーム時に実行されるイベント |
function animate() { |
//箱を回転させる |
//ここの数値を変えると回転速度が変わる |
box.rotation.x += 0.005; |
box.rotation.y += 0.006; |
renderer.render(scene, camera); // レンダリング |
requestAnimationFrame(animate); |
} |
} |
</script> |
</head> |
<body> |
<!-- この領域に描画 --> |
<canvas id="myCanvas"></canvas> |
</body> |
</html> |
これをテキストエディタにはりつけてブラウザで開けばそれだけで3DCGが出現!
flashとかいらないのでhtmlを表示させる感覚でいとも簡単に実装できます。なんとお手軽!
three.jsの基本構造ですが、
主に
- scene…空間、三次元空間のどの領域を撮影するのか
- camera…視点、どの位置から、どの方向へ映すのか
- mesh(形状、素材)…被写体となる物体
で構成されていて
最終的に上記の内容をcanvasにrenderer(描画)します。
それでは、簡単にソースの解説をします。
<canvas id=”myCanvas”></canvas> |
[l.44]bodyに描画するcanvasタグを記述します。ここでidをmyCanvasとしておきます。
const renderer = new THREE.WebGLRenderer({ canvas: document.querySelector(‘#myCanvas’) }); |
[l.12]どのcanvasに描画するかを指定します。
ここでは上で用意したcanvasのidのmyCanvasを記述します。
const scene = new THREE.Scene(); |
[l.18]3Dオブジェクトを置く3D空間を用意します。
今回はsceneオブジェクトを作成しただけですが、背景色の指定や、3D空間にまつわる指定をします。
const camera = new THREE.PerspectiveCamera(45, width / height); |
[l.20]どの位置から3Dオブジェクトを撮影するかを指定します。
const box = new THREE.Mesh(geometry, material); |
[l.27]meshには形、素材を設定します。
今回は四角い箱を表示するので
const geometry = new THREE.BoxGeometry(400, 400, 400); |
[l.23]で箱のオブジェクトを作成しています。
const material = new THREE.MeshNormalMaterial(); |
[l.25]でその箱がどんな素材でできているか。
質感だったり色だったりを指定します。
renderer.render(scene, camera); |
[l.36]rendererにsceneとcameraオブジェクトを渡して描画します。
これさえ押さえれば簡単な3DCGは表現できます!
three.jsには色んな素材(マットだったりつやがあったり)が用意されています。
あと、公式ページにはexampleがたくさん掲載されてあり、元ネタが豊富です。
もちろん各クラスの詳細もちゃんと載っています(英語ですが…)
VRのexampleもありスマホで閲覧するともっとワクワクしてきます!
本当はもっとゴリゴリなものとかぐわんぐわん動くものを作りたかったのですが、
とりあえず今回はお手軽さを追求してみました。
three.jsのTOPではthree.js、WebGLを採用しているサイトを閲覧することができます。
どれも素敵ですが特に
TRACK | A WebGL Experiment by Little Workshop
音楽と連動してとてもクール(音楽再生あり、閲覧注意)
とか、
ROME
3DCGと物語の作品がすごい(音楽再生あり、閲覧注意)
とか、
Paper Planes
スマホで閲覧すると紙飛行機を飛ばせるVRあり
とか、どれもWebGL、VRの技術を堪能することができておすすめです。
インターネットが普及し始めた頃、本を片手に見よう見まねでホームページを作成した〇年前…
ただでさえ、電話回線を使ってインターネットに接続していたので
回線速度は遅く、PCの処理も追いつかない上にJavaScriptを駆使して画面に雪を降らせてフリーズさせるという無駄なことをしたり(苦笑)
まだまだFlash全盛の頃、html×JavaScriptでFlashコンテンツと遜色ない動的コンテンツが出始めてすごく感動した私にとっては、
ブラウザで、htmlで、JavaScriptで3DCGがみれるWebGLは、出現から7年経った今でもワクワク体験を提供してくれる技術です。
UXへの影響がとても分かりやすい技術ではありますが、今回WebGLに触れてみてあらためてUXデザインセンターの一員として、もっともっとユーザーに良い体験を提供したいと思いました。
以上、sgi-changでした。