[続WebGL入門] 3DCGソフトで作られたモデルデータをWeb上で描画してみる
2015/11/2
Tag: javascript,script,three.js,webgl
久しぶりの投稿になります。TDの田辺です。
今回は、以前に投稿した
[WebGL入門] javascriptを使って3Dプログラミングをやってみる
という記事の続編として書いていきます。
分からない点等ございましたら、前回の記事も参照して頂ければと思います。
では、進めます。
前回は、WebGLのJavascriptライブラリ 「Three.js」 を使用して、
スクリプト上でカメラやライト、オブジェクト(キューブ)を作成しWeb上に描画するという内容について紹介させて頂きました。
今回紹介させて頂くのは、
3DCGソフトで作られたモデルデータをWeb上で描画してみる
というものです。
是非、チャレンジして頂ければと思います。
準備
■WebGLに対応しているブラウザ
Mozilla Firefox 24.6.0 を使用いたします。
■「dftalk」フォルダ(作業フォルダ)
どこでも良いので、dftalk という名前でフォルダを作成しましょう。
■three.js
公式サイト からダウンロードできます。
メニューの download から、 zipファイル をダウンロードしましょう。
ファイルを解凍したら、必要なライブラリ本体は buildフォルダ 内に 「three.min.js」 として配置されているので、
先ほど作成した 「dftalk」フォルダ に 「three.min.js」 をコピーします。
■OrbitControls.js
マウスでカメラの視点移動を行うために必要なスクリプトです。
three.jsを取得する際にダウンロードしたzipファイル内の
examples\js\controls\OrbitControls.js
に配置されているので、先程と同じく 「dftalk」フォルダにコピーします。
■convert_obj_three.py
objファイル からThree.jsで読める jsonファイル にデータを変換するためのスクリプトです。
three.jsを取得する際にダウンロードしたzipファイル内の
utils\converters\objconvert_obj_three.py
に配置されているので、先程と同じく 「dftalk」フォルダにコピーします。
■Maya
バージョン2014を使用します。
■objExport プラグイン
Mayaからモデルデータをobjファイルとして出力するために必要なので用意します。
■テキストエディタ
メモ帳でも大丈夫です。
■python.exe
モデルデータを変換する際にpythonスクリプトを実行するため用意します。
■モデルデータ (teapot.obj)
今回、ティーポットのモデルデータを使用します。
Wikipediaにも載っている有名なモデルだそうです。
コチラのサイトの下の方にある teapot.obj というリンクの上で
右クリック ⇒ 名前を付けてリンク先を保存 で 「dftalk」フォルダ に保存します。
モデルに簡単にマテリアルを適用する
ダウンロードした teapot.obj にマテリアルが適用されていないので
Mayaで簡単に設定したいと思います。
■作業の流れ
1.Mayaでモデルの色を変更(lambertのColorを変更)
2.plug-inマネージャーでObjExportがロードされているか確認
3.モデルを選択
4.上部メニュー > Export Selection を選択
5.File of Type を OBJexport に変更
6.ファイル名を teapot.obj に設定して、 「dftalkフォルダ」を選択して出力
マテリアルを設定しているので、同じ場所に teapot.mtl というファイルも作成されたかと思います。
このmtlファイルにマテリアルの情報が保存されています。
mtlファイル自体はわりとシンプルな構造をしているので、mayaなどを使わず自前で作ることもできます。
MTLファイルの書式についての参考ページ
モデルデータを変換する
OBJのモデルデータをThree.jsで扱える json形式のデータに変換します。
convert_obj_three.py
というスクリプトを使用します。
このスクリプトは、公式で配布されているものです。
batファイルで簡単なツールを作って実行する流れで行きたいと思います。
■convert_obj_three.pyの実行用batを作成
下記の内容でファイルを作成し、 「dftalkフォルダ」 に入れます。
■convert_obj_three.bat
@echo off ::カレントディレクトリをこのファイルの置かれている場所に設定 cd /d %~dp0 起動するpython.exeまでのパスを記入("C:\Program Files\python\python.exe"など) %~dp0convert_obj_three.py -i %1 -o %~n1.js pause
※「起動するpython.exeまでのパス」 の部分は、各自のpython.exeのインストールされている場所によって変わります。
■%から始まる文字について
bat特有の書き方でそれぞれ下記のような機能があります。
「 %~dp0 」
・batファイルの置かれているディレクトリパスを展開
「 %1 」
・batファイルに対して、ドラッグアンドドロップされたファイルのパスを展開
「 %~n1 」
・batファイルに対して、ドラッグアンドドロップされたファイルの名前を展開
■-i や -o などのフラグについて
convert_obj_three.pyで使用するフラグです。
convert_obj_three.py -i <変換元のobjファイルのパス> -o <変換後に出力するファイル名>
■batファイルを実行する
先程作成したbatファイルは、変換対象の objファイル を batファイル の上にドラッグ&ドロップすることで実行されます。
コマンドプロンプトが開き、実行結果が表示されます。
変換後のファイルは、json形式のデータで、「objファイル名.js」というかたちでdftalkフォルダに保存されています。
今回の場合は、teapot.js という名前で保存されているかと思います。
これでWeb上に描画出来る形式に変換が完了しました。
では、いよいよWeb上に描画する作業に移りたいと思います。
Web上にモデルデータを描画する
■HTMLファイルを作成する
まずは、下記のコードをテキストエディタにコピーし、 index.html という名前で 「dftalkフォルダ」に保存して下さい。
Three.jsについての説明に関しては、前回の記事で紹介しているため割愛させて頂きます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>DFTALK three.js モデルデータの描画テスト</title> <!-- three.jsを読み込む --> <script type="text/javascript" src="three.min.js"></script> <script type="text/javascript" src="OrbitControls.js"></script> </head> <body> <div id="render-area"> <!-- この中で描画する --> </div> <script> // シーンの作成 ------------------------------------------ var scene = new THREE.Scene(); // カメラの作成 ------------------------------------------ // fov: 画角(視野角) var fov = 75; var height = 600; // 縦幅 var width = 400; // 横幅 // aspect: アスペクト比、カメラで撮影したものの縦横比 var aspect = height/width; // near: ニアークリップ、 カメラからの撮影開始位置、これより近いものは撮影しない var near = 1; // far: ファークリップ カメラからの撮影終了位置、これより遠いものは撮影しない var far = 5000; // カメラ作成 var camera = new THREE.PerspectiveCamera(fov, aspect, near, far); // カメラ配置 camera.position.set(100, 100, 100); // (x, y, z) // ライティングを設定する ------------------------------------ var color = 'white'; // 光の色 // ライトオブジェクト作成 var directionalLight = new THREE.DirectionalLight(color, 1.0); directionalLight.position.set(-2, 1, 1).normalize(); // 光源の角度を設定 scene.add(directionalLight); // シーンに追加 // 屋外のライティング効果をリアルにしてくれるそうなので、もうひとつライトを追加 var hemisphereLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.25); scene.add( hemisphereLight ); // オブジェクトを配置する ---------------------------------------- // ジオメトリーの作成 var geometry = new THREE.CubeGeometry(50, 50, 50); // サイズ設定(x, y, z) // マテリアルの作成 var material = new THREE.MeshPhongMaterial({color: 'orange'}); // メッシュの作成 cube = new THREE.Mesh(geometry, material); cube.position.set(-50, 0, 0); // 位置を設定(x, y, z) scene.add(cube); // シーンに追加 // レンダラーの追加 ------------------------------------------- var renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setSize(height, width); // Canvasのサイズ設定 // 背景を灰色に変更 (背景が真っ暗になるのを回避) renderer.setClearColor(0xdddddd, 1 ); // レンダリング ----------------------------------------------- function render() { // 回転アニメーションを追加 requestAnimationFrame(render); cube.rotation.y += 0.01; // y軸に0.01加算 // シーンとカメラを渡してレンダリング(表示) renderer.render(scene, camera); } // カメラコントロール ----------------------------------------- var controls = new THREE.OrbitControls(camera); // HTMLの読み込みが完了してから実行する window.onload = function(){ // render-area内に描画用エレメントを追加 document.getElementById('render-area').appendChild(renderer.domElement); render(); } </script> </body> </html>
前回の記事で作成したものをベースに少し修正を加えました。
■修正箇所
・カメラのfarの値を大きく
・カメラの初期位置を変更
・directionalLightの角度を変更
・hemisphereLightを追加
・Cubeを少し大きく
・rennderar.setClearColorを追加し、背景が真っ暗だったのを灰色に変更
・render-areaというIDを持つdev要素内で描画するように変更
コードが書けたら、HTMLファイルをブラウザで開いてみましょう。
設定の変更により前回よりもオブジェクトがだいぶ見やすくなったと思います。
では、次にCubeの隣にモデルデータを表示したいと思います。
■モデルデータをシーンに追加する
66行目の レンダラーの追加 と書かれている行の上に下記のコードを追加します。
JSONLoaderというものを使用してモデルデータを読み込みます。
// モデルデータをシーンに追加 var jsonObj, faceMaterial; // オブジェクトとマテリアルの変数定義 // JSONLoaderを使ってモデルデータを読み込む loader = new THREE.JSONLoader(); // 引数としてモデルデータのジオメトリーとマテリアルが入ってきます loader.load( "teapot.js", function ( geometry, materials ) { // モデルデータのマテリアルを作成 faceMaterial = new THREE.MeshFaceMaterial( materials ); // フェースを両面とも表示するための設定 for(var i = 0, len = materials.length; i < len; i++){ materials[i].side = THREE.DoubleSide; } jsonObj = new THREE.Mesh( geometry, faceMaterial ); jsonObj.position.set( 50, -25, 0); jsonObj.scale.set( 15, 15, 15 ); scene.add( jsonObj ); }); // レンダラーの追加 -------------------------------------------
画像のようにCubeのとなりにティーポットが表示されたでしょうか。
■モデルデータのマテリアルを変更する
では、最後にモデルデータのマテリアルに手を加えて、見た目を変更したいと思います。
load関数の中を下記のように変更します。
// モデルデータをシーンに追加 var jsonObj, faceMaterial; // オブジェクトとマテリアルの変数定義 // JSONLoaderを使ってモデルデータを読み込む loader = new THREE.JSONLoader(); // 引数としてモデルデータのジオメトリーとマテリアルが入ってきます loader.load( "teapot.js", function ( geometry, materials ) { // // モデルデータのマテリアルを作成 // faceMaterial = new THREE.MeshFaceMaterial( materials ); // // フェースを両面とも表示するための設定 // for(var i = 0, len = materials.length; i < len; i++){ // materials[i].side = THREE.DoubleSide; // } // 新しくマテリアルを作成 faceMaterial = new THREE.MeshPhongMaterial({color: 'pink', side: THREE.DoubleSide}); jsonObj = new THREE.Mesh( geometry, faceMaterial ); jsonObj.position.set( 50, -25, 0);// 位置を設定(x, y, z) jsonObj.scale.set( 15, 15, 15 );// スケール設定 scene.add( jsonObj );// シーンに追加 });
ティーポットがオレンジ色からピンク色に変更されたでしょうか。
このようにモデルを読み込んだ後は、マテリアルなどの設定を変更することが出来ます。
あとがき
ここまでお付き合い頂きありがとうございました。
今回は、ティーポットの軽いモデルだったため、スムーズに描画まで出来ましたが、
ポリゴン数が多いモデルなどでは、上手くいかない場合があるかもしれません。
色々試して頂ければと思います。
いずれこの技術を使ってWeb上で3Dモデルライブラリなどが作れたりしたら面白いですね。
今後も調査を続けて行きたいと思います。
※免責事項※
本記事内で公開している全ての手法・コードの有用性、安全性について、当方は一切の保証を与えるものではありません。
これらのコードを使用したことによって引き起こる直接的、間接的な損害に対し、当方は一切責任を負うものではありません。
自己責任でご使用ください
コメント
コメントフォーム