ブログ

blog

【WebGL特集】第4回:Blenderでモデル出力


※この記事は2013年の記事を2018年6月に加筆修正したものです。three.jsの使用バージョンはr92です。

【前記事】
【WebGL特集】第1回:WebGLって何?
【WebGL特集】第2回:回転する立方体
【WebGL特集】第3回:カメラをグリグリ

前回までは、CGソフトを使わず、three.jsのチカラのみで3Dオブジェクトを出力していました。
今回はBlenderというフリーの3DCGソフトを使い、自作のオブジェクトモデルをコンバートし出力する方法を解説します。

1、なぜBlenderなのか

2018年時点ではwebGLと最も相性のいい3DCGソフトはBlenderです。モデルのみであれば一応、各ソフトにwebGL出力用のプラグインなり、Collada出力なり、何かしらの手段がないことはないのですが、バグやエラーが多く開発途上であったりと安定的に使えるものではありません。後半の回でも説明しますが、主要3DCGソフトからアニメーションをwebGLに出力したいのであれば、一度Blenderにデータを持っていきBlenderからwebGL用にデータを出力するのが、2018年現在においても最も確実な手段です。ただし最近では、json形式以外にもglTS, FBX, 3dsを使い、MAYA, 3dsMAXなどから直接アニメーションを出力できるようになってきているようです。他の3DCGソフトからの直接出力する方法については、別記事で解説いたします。

2、Blenderの起動からsuzanneの取得

Blenderを起動したところからはじめます。

ブレンダーのマスコットキャラクターsuzannneを取得します。
追加>メッシュ>モンキー

ついでにマテリアルも変更してみましょう。
suzanne

3、suzanneをJSON(three.js)形式で出力する

JSON(three.js)形式をBlenedrで使えるようにするにはthree.jsエキスポーターというのを組み込む必要があります。以下の手順で導入してみましょう。

1,エキスポーターを入手する。

three.js-r92.zipをまるごとダウンロードしている場合は、すでに入手済みです。以下にあります。
three.js-r92\utils\exporters\blender\addons\io_three

githubから直接はこちら
three.js形式エキスポータのダウンロード

2、io_threeフォルダをコピペする。

【Windows】コピペ先は、Blenderのインストール状況により変化します。

通常インストールの場合
[C:\Program Files\Blender Foundation\Blender\2.7X\scripts\addons]

Zipフォルダを解凍してインストールしたブレンダーであれば、解凍フォルダ内の
[…./Blender[バージョン番号]/scripts/addons]

もしくはこちら
[C:Users/USERNAME/AppData/Roaming/Blender Foundation/Blender[バージョン番号]/scripts/addons]

3、Blenderで有効にする

Blenderのユーザー設定 > アドオン > 左側import&Exportで選んで右側下側にある「three.js Format」をOnにする。

4、エキスポートする

これでJSON(three.js)で、ファイルをエキスポートできるようになりました。オブジェクトを選択した状態でエキスポートしてします。

設定は赤枠で囲ったところを確認してください。デフォルトでは出力されないので、設定を変更する必要があります。

出力が成功すると拡張子(.json)ファイルが一つ出来ます。

4、scriptの記述

基本的には前回のトラックボールカメラのソースのオブジェクト部分をjson(Three.js)ファイル用のスクリプトに変更しただけです。モデルのパスは自分のパスに書き換えておいてください。

<html>
<meta charset="utf-8">
<body>
<script src="build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script>

init();
animate();
 
function init() {
    //シーン
    scene = new THREE.Scene();

    //カメラ
    camera = new THREE.PerspectiveCamera( 75, 640/480, 1, 10000 );
    camera.position.z = 1000;
    
    trackball = new THREE.TrackballControls( camera );//カメラぐりぐりしたいならこれ
    trackball.rotateSpeed = 5.0; //回転速度
    trackball.zoomSpeed = 0.5;//ズーム速度
    trackball.panSpeed = 2.0;//パン速度
    
    //ライティング
    var directionalLight = new THREE.DirectionalLight( 0xffffff, 2 ); //平行光源(色、強度)
    directionalLight.position.set(0,0,3);
    scene.add( directionalLight );
	
    //Blenderで出力したjsonオブジェクト
    loader = new THREE.JSONLoader();
    loader.load( 'suzanne.json', function ( geometry, materials ) { 
	    json = new THREE.Mesh( geometry, materials );
	    json.position.set( 0,100,0);
	    json.scale.set( 100, 100, 100 );
	    scene.add( json );
	    } );
    
    //グリッド
    grid = new THREE.GridHelper(1000, 10, 0x888888, 0x888888);
    grid.position.y = -40;
    scene.add(grid);
    
    //レンダラー
    renderer = new THREE.WebGLRenderer();
    renderer.setSize( 640, 480 );
    renderer.setClearColor(new THREE.Color('white'));//背景色の設定
    document.body.appendChild( renderer.domElement );
 
}
 
function animate() {
    requestAnimationFrame( animate );
    renderer.render( scene, camera );
    trackball.update();   //これ追加
}
</script>
</body>
</html>

5、ソースの解説

前回のトーラスオブジェクトとの、変更部分だけを解説します。

    //Blenderで出力したjsonオブジェクト
    loader = new THREE.JSONLoader();
    loader.load( 'suzanne.json', function ( geometry, materials ) { 
        json = new THREE.Mesh( geometry, materials );
        json.position.set( 0,100,0);
        json.scale.set( 100, 100, 100 );
        scene.add( json );
        } );

jsonを読み込むためには、まず、Three.jsに組み込まれている、「JSONLoader」を取得します。30行目で取得しています。loadメソッドで、作ったモデルをロード(モデルパスを入力)し、コールバック関数と言われるfunctionのカッコ内で一度ジオメトリーとマテリアルを仕分け。そのまま31行目で取得したマテリアルを32行目で、ジオメトリーと合体させて、それ以降で位置とサイズを決めて、シーンに追加します。(2013年記載のMeshFaceMaterialは廃止となりました。その代わり、materialsのように複数のマテリアルを内包している変数をTHREE.Meshの引数に直接使用できるようになっております。)

他にも、スムーシング、スペキュラー、テクスチャー、ノーマルマップなど、多くの表現が出来るっぽいのですが、追求しだすとキリが無いのでここまでにしておきます。
次回は、いよいよアニメーションの出力です。

【WebGL特集】第5回:Blenderでアニメーション出力

Mox-Motionに興味をお持ちの方はお気軽にご連絡ください!

採用希望の方は・・・