2011年12月5日月曜日

THREE.js での輪郭線表示


 4日目 nakamura001 さんの「PhiloGL でのカメラの移動処理」に続きまして、JavaScript Advent Calendar 2011(WebGLコース)5日目担当の 3DCG Arts の角(@santarh)です。

 この記事では、THREE.js というライブラリを用いて、簡易的な輪郭線描画を行います。ライブラリの導入については、2日目 yomotsu さんの「THREE.js で WebGL」がとても解りやすい解説になっています。


概要
 まず、3DCG においての輪郭線表現する手法のひとつとして、画像処理の手法を用いて輪郭検出を行なう方法があります。この方法では、シェーダを書く必要があり、導入難易度が高くなります。そこで、 Mesh で輪郭線を描くことができる昔ながらの方法を紹介します。

 輪郭線を表示したい Mesh に対して、反転した Mesh を用意します。
そして、反転した Mesh を拡大して表示します。このようにすることで、拡大することで元のモデルからはみ出た部分が輪郭線として表示されます。


実装
 次の例では、半径 50 、分割数 32 の球体を作成します。

var geometrySphere = new THREE.SphereGeometry( 50, 32, 32 );

 THREE.js では "glCullFace" を利用した表裏反転を実行するための THREE::Object3D (Mesh)の表裏反転フラグ(flipSided)が用意されています。
表裏判定フラグを立てたら、輪郭線の太さの幅だけスケールを大きく調節します。次の例では球半径の0.05倍の太さの輪郭線を表示するために、スケールを1.05倍に設定しています。

var outline = new THREE.Mesh( geometrySphere, new THREE.MeshBasicMaterial );
outline.flipSided = true;
outline.scale.x = 1.05;
outline.scale.y = 1.05;
outline.scale.z = 1.05;

 最後に THREE::Scene に THREE::Object3D (Mesh)を追加します。
ここでは THREE::Object3D (Mesh) に子を持てる機能を利用して、輪郭線を球の子として追加します。

sphere.add( outline );

 こうしてレンダリングされた結果が次の画像です。球体の周りに黒色の輪郭線が表示されていることが分かると思います。


まとめ
 このように、シェーダを記述しなくとも、輪郭線が簡単に描画することができました。ただし、ポリゴンの形状によっては、この方法を利用すると輪郭線がズレてしまいます。理由は、単純な等比拡大ではなく、法線方向への拡大が求められるためです。

 今回利用した THREE.js では、 OpenGL ES の煩わしいコードを書くことなくシェーダを記述することもできます。描画エンジンとしてとてもよく出来たライブラリなので、皆さんガシガシ使って行きましょう!


最後に
 すみません…最後にサービスの宣伝をさせて下さい(汗)
3DCG Arts のサービス機能追加等のアップデートを本日行いました。クリエータの皆様の素敵な 3DCG 作品が沢山投稿されているので、是非ご覧になってみてください。