この記事はThree.js Advent Calendar 2016の4日目の記事でもあります。

はじめに

「WebGLを気軽に使ってもらう」を目標に、ここ数年いくつかの活動してしてきました。
今年はVRも後押しになり、いろいろなコンテンツでWebGLを見かけるようになりました。

しかしほとんどのコンテンツが大規模なものになっているため、WebGLに対して「難しい」「たいへん」「専門知識を要する」というイメージが付いてしまっています。

この記事では来年こそ「WebGLをもっと気軽に使ってもらう」ために、まだWebGLを触ったことのない初心者向けにWebGLのライブラリであるthree.jsを使ってのWebサイト制作の手ほどきをしていきます。

完全初心者向けであり、自分自身も日々勉強しながらの記事ですので、はじめは詳しいことや専門用語などはあえて解説せずに話をすすめます。今後少しづつ記事を書いていこうと思いますので、興味があるかたはおつきあいください。

WebGLとは

WebGLとはかなりざっくりいうと、ウェブブラウザで3Dや2Dグラフィクスを表示する規格(JavaScript API)です。 ここではあえてこれ以上は語りません。「WebGL=かっこいい&おもしろい」くらいに考えてください。

記述はJavaScriptで行います。ブラウザひとつで実行できプラグインも不要です。 ほとんどのブラウザの現行バージョンで実行できます。

three.jsとは

最もメジャーなWebGLのライブラリです。WebGLをわりと易しく記述することができます。 2016.12.4現在 r82(82改訂)で、頻繁に更新されています。

書き方

さっそく書いていきましょう。

まずはhtmlのheadタグ内でthree.jsを読み込みます。 今回はCDNで読み込んでいますが、公式サイトからダウンロードしたものを使っても良いです。

  <head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.min.js"></script>
</head>

HTMLの準備は以上です、つぎはJavaScriptを書いていきます。

  var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer();

まずは下準備として全体のScene(しーん)を作ります。
これは実際にはWebGLで使う変数などの準備をしている段階で、今後このシーンにオブジェクトを追加していきます。 「映画のワンシーン」の「シーン」と同じ英語で、これからWebGLというシーンをつくっていくわけです。

続いてRenderer(れんだらー)を作ります。 RendererとはRender + er の言葉で、Render(れんだー)が「描画する」という意味なので、「描画を担当するやつ」とおぼえてしまいましょう。

このシーンとレンダラーのふたつはthree.jsでWebGLを作っていくときに必ず必要になります。
これらにはたくさんの機能が紐付いているのですが、現時点では複雑に考えず必要な初期設定として認識しておくと良いでしょう。

  renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );//renderer.domElementはcanvas要素

次にrenderer.setSize(width, height);で、さっき作ったレンダラーの描画領域を設定します。
今回はウインドウ全体に描画する設定にしています。

そしてここではじめてhtml(DOM)に変更を加えます。
renderer.domElement の中にはWebGLのコンテンツを作るために準備した<canvas>要素が入っています。 ここでは<body>直下に<canvas>要素を追加しましたが、任意の場所に追加しても良いです。

あたりまえですが、まだブラウザの画面には何も変化はありません。 しかしDev tools等で見てみるとbodyタグ内にcanvas要素が追加されているのがわかります。


次はいよいよCamera(かめら)を追加します。
今回はPerspectiveCamera(ぱーすぺくてぃぶかめら)を使います。 PerspectiveCameraとは空間の奥行きに応じて遠くにあるものは小さく、近くにあるものは大きく撮すカメラです。

  var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 100;

カメラの設定に関しては別の記事で紹介する予定ですので、ここではあえて触れません。
ひとまずここではカメラを手前に100移動させています。これから配置するオブジェクトをカメラで撮影するわけですが、撮影対象とカメラが同じ位置にあっては映らないからです。

もちろん配置するオブジェクトのほうをカメラの前に移動させることもできますが、初期設定でカメラの方を移動させこれから撮影したい領域を決めておくほうが今後理解しやすくなります。

  var geometry = new THREE.PlaneGeometry( 20, 20 );

ここで先程述べた「カメラに撮すオブジェクト」の準備に入ります。
まずはGeometry(じおめとり)です。

ジオメトリとは「形状」のことで、これから配置するオブジェクトの形の種類を決め、その設定を行っています。 今回はPlaneGeometry(ぷれーんじおめとり)を使います。
PlaneGeometryは厚さが0の四角形です。( 20, 20 )の部分は横と高さのサイズです。

  var material = new THREE.MeshBasicMaterial( {
  color : 0xCC0000
} );

ジオメトリ(形状)を決めたら次はその形状を包む素材を準備します。
Material(まてりある)の設定です。

今回はベーシックなMeshBasicMaterialを使い、色の設定のみを行いました。
0xCC0000の部分で16進数で赤を設定しました。

  var planeMesh = new THREE.Mesh( geometry, material );
scene.add( planeMesh );

そして準備したジオメトリとマテリアル(形状と素材)を紐付けます。
three.jsではこの紐付けたものをMesh(メッシュ)と呼びます。

さらにこのメッシュをscene.add();で最初に作ったシーンに追加します。

  renderer.render(scene, camera);

最後にいよいよ、ここまで準備してきたものを描画します。
最初に作ったレンダラのrenderer.render();で描画を指示します。

()の中に今まで準備してきたシーンとカメラを指定し、実行することで、一度だけ描画します。
ここまでのコードをまとめたものがこちらです。赤い四角が表示されているのが、実行結果です。

ここまでコードだけなら13行ほどで赤い四角が出ただけですが、少し設定をいじってWebGLっぽい表示を試してみましょう。 上のまとめコードは編集できるようにしてありますので、18行目の//wireframe : true,//を削除してみましょう。

だったのがのような形になります。これはマテリアルの設定の「ワイヤーフレームの表示」を許可した状態です。「ワイヤーフレーム」とは形状(ジオメトリ)を構成する点をつなぐ線のみを表示させた状態で、形状を分かりやすく見ることが出来たり、メッシュの向こう側を見たりすることが出来ます。

まとめ

今回は完全初心者向けということで、最短のthree.jsのコードで赤い四角を表示させるだけでした。
しかし、ここまでのものでも生のWebGLで書くと倍以上の記述が必要です。また最後に示したように、設定を変更するだけで状態を変化させることも出来るので、そうした意味でも最初に触るWebGLライブラリとしてthree.jsはおすすめできます。

今回作ったものをベースにもう少し初心者向けに書いていこうと思いますので、少しでも興味がでたらぜひ見てあげてください。