今回は、Blenderでモデリング、アニメーションをつけて、JSON形式で書き出して、three.jsでJSONデータを読み込んで、モーフィングアニメーションを再現する流れを、ざっくりと説明出来ればと思います。
モデリングとアニメーションの作成にBlenderを使っています。Blenderはオープンソース(無償)の3DCG制作ツール
で、現時点での最新バージョンは2.72bになります。3DCG制作ツールはMayaや3dsMaxやLightwave3D等、高機能なプロ用ソフトが多くありますが、どれもそれなりの価格になります。Webコンテンツでの利用においては、レンダリングはあくまでブラウザ上なので、使う機能と言えば、せいぜいモデリングとアニメーション程度になり、高価で高機能な3DCG制作ツールは、オーバースペックだと思います。Blenderは無償ですが、高機能な3DCG制作ツールに、勝るとも劣らない機能を有している、素晴らしいツールだと思っています。
Blenderでモデリング
まずはBlenerでアニメーションを行うキャラクターのモデリングを行います。Blenderで作業するのに、まず覚えなくてはならないのはショートカットです。今回使ったショートカットをリストアップしました。マウスホイールやテンキーも多用するショートカットになっているので、テンキーとホイール付きのマウスがないと、Blenderの作業は厳しいかもしれません。
- マウス操作
- マウス左ボタン : 移動の確定
- マウス右ボタン : 選択/選択解除
- マウス右ボタン+ Shift : 追加で選択/選択解除
- マウス右ボタン(プレス) + ドラッグ : 選択した物を移動
- マウスホイール(プレス) + ドラッグ : 視点移動
- マウスホイール(回す) : 拡大/縮小
- マウスホイール(回す) + Shift : 移動(上/下)
- マウスホイール(回す) CTRL : 移動(左右)
- 表示・モード切り換え系ショートカット
- Tab : Objectモード/Editモードを切り替え
- アーマチュアを選択 + CTRL + Tab : ポーズモード
- オブジェクトを選択 + CTRL + Tab : ウエイトペイント
- Z : ワイヤーフレーム/ポリゴン表示を切り替え
- N : プロパティパネル
- T : ツールシェルフ
- 5 : 透視投影/平行投影
- 7 : 視点切り替え(上)
- 1 : 視点切り替え(前)
- 3 : 視点切り替え(横)
- 0 : 視点切り替え(カメラ)
- 選択系ショートカット
- A : オブジェクトを全選択/全選択解除
- B : 矩形範囲選択
- 移動・変形系ショートカット
- G : 移動
- R : 回転
- S : 拡大/縮小
- E : 押し出し
- F : 面を張る
- CTRL + T : 四角形を三角形に分割
- CTRL + R : ループカット
- アニメーション系ショートカット
- Option + R : ボーンの回転をクリア
- Option + G : ボーンの移動をクリア
- ボーンを選択した状態でI、LocRotを選択
: ボーンの移動(Location)と回転(Rotation)のキーフレームを打つ
- その他ショートカット
- X : 削除
- Shift + A : 新たなオブジェクトを追加
- CTRL + J : 複数のオブジェクトを一つに結合
- Shift + C : 3Dカーソルを中心に
- M : オブジェクトごとにレイヤーを分ける
Blenderの基本操作は、以下のサイトのチュートリアルが、非常に分かりやすいです。
このチュートリアルを実践していくうちに、Blenderにも慣れてくると思います。今回はAway3Dの時から、three.jsやBlenderでもよく見かける猿のあたまを利用して、簡単なモデリングを行いました。
Blenderでアーマチュアを作成し、設定
アニメーションを行うには、まず動きの元となる骨格(ボーン)が必要となります。アーマチュアとは、そのボーンの集合体の事を言います。アーマチュアの設定は、以下の流れになります。
- モデルデータにアーマチュアを追加して関連づけます。
- モデルデータに合わせて、アーマチュア内にボーンを作成していきます。
- 後々分かりやすいように、ボーンに名前を付け、ボーン同士の親子関係や、動きの連動を設定します。
- ウエイトペイントモードで頂点のグループを作って、それぞれの頂点が、どのボーンに追従するかを設定します。
ボーン : 太い方の丸がRoot、細い方の丸がTipで、太い方から細い方に、親 -> 子へとボーンが繋がっていきます。
ウェイトペイントモード : 頂点毎に、青 -> 赤と、選択しているボーンとの連動具合に応じてペイントを行います。
このような流れで、モデリングデータにアーマチュアを追加する事が出来ました。
Blenderでアニメーションの設定
作成したアーマチュアを元に、アニメーションを設定します。アニメーションをつける方法は、タイムラインにキーフレームを打つFlashと同じイメージです。以下の流れになります。
- ポーズモードでボーンを移動、回転させて、ポーズをとらせます。
- ドープシートを使って、とらせたポーズを元にキーフレームを打つことで、キーフレーム間の差異が補完されて、自動的にアニメーションがつきます。
- 作成したアニメーションをアクションパターンとして登録します。
- NLAエディターでアクションパターンを組み合わせ、調整します。
Blenderでモデルとアニメーションを書き出す
作成したモデルデータとアニメーションを、three.jsで扱いやすいthree.js用のJSON形式で書き出すのですが、デフォルトではBlenderは、three.js用のJSON形式の書き出しが出来ません。three.js公式のBlenerのアドオンを追加する必要があります。
ちなみに、以前試したBlender2.7では、アドオン(2.65)が正常に動きませんでしたが、Blender2.72bではアドオン(2.65)が、問題なく動くようです。
three.js用のJSON形式での書き出し設定
- Step1 : まずはThree.jsの最新版をダウンロードしてください。
- Step2 : ダウンロードしたアドオンThree.js Blender Import/ExportをBlenderのscriptsフォルダにコピーします。
cp -r three.js-master/utils/exporters/blender/2.65/scripts/addons/ /Applications/Blender/blender.app/Contents/Resources/2.72/scripts/addons/
- Step3 : Blenderを起動し、File -> User Preferences -> AddonsタブとImport-Exportを選択して、Import-Export:three.js formatにチェックし、Save User Settingsを押下します。
- Step4 : File -> Export にThree.js(.json)が表示されれば設定完了です。
モデルデータとアニメーションを、three.js用のJSON形式で書き出す
いよいよモデルデータとアニメーションを書き出します。File -> Export -> Three.js(.json)で、書き出し設定パネルが表示されます。
アニメーション部分で特に重要なのが、Morph animationとSkeletal animationのチェック項目です。
- Morph animation
- キーフレームごとの頂点位置を補完し、その補完された全頂点データを保存して、頂点情報を切り替えながらアニメーションさせます。
- 計算負荷は低くなりますが、複雑なモデルやアニメーション自体が長くなると、その分のデータ量が増えます。
- Skeletal animation
- ボーンの動きだけを保存し、そのボーンの状態に応じて、頂点位置を計算します。
- 読み込むデータ量が少なくなりますが、計算負荷が高くなります。
今回はMorph animationを選択します。これでBlenderの作業は完了です。
three.jsでの基本設定
今回は、three.jsの基本的な部分を、特に説明しませんが、いつも通りにシーン、カメラ、光源、レンダラー等を設定しています。
var width = window.innerWidth;
var height = window.innerHeight;
// シーン
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x000000, 0.00035);
// カメラ
camera = new THREE.PerspectiveCamera(50, width/height, 1, 10000);
camera.position.z = 1000;
camera.position.y = 200;
// 光源
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(200, 200, 200);
scene.add(directionalLight);
// 環境光
var ambientLight = new THREE.AmbientLight(0x999999);
scene.add(ambientLight);
// 地面
var ground = new THREE.Mesh(new THREE.PlaneGeometry(10000, 10000, 1, 1), new THREE.MeshLambertMaterial({color: 0x333333}));
ground.position.y = -200;
ground.rotation.x = Math.PI / -2;
scene.add(ground);
// レンダラー
renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
//
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
controls.autoRotateSpeed = -1.0;
//
document.body.appendChild(renderer.domElement);
three.jsでJSON形式のモデルデータとアニメーションを読み込む
Blenderで書き出したJSON形式のモデルデータとアニメーションを、THREE.JSONLoaderで読み込みます。読み込み完了後に、マテリアルのmorphTargetsにtrueを代入して、モーフィングアニメーションを有効にしてください。読み込んだGeometryとMaterialsを元に、アニメーション用のメッシュを作成してください。今回はTHREE.MorphAnimMeshを使用しています。
- THREE.MorphAnimMesh : フレーム(タイムライン)を扱うのに便利なメソッドが用意されています。
- THREE.SkinnedMesh : ボーンを扱う事ができます。
// モデル
var loader = new THREE.JSONLoader();
loader.load('models/monkey2.json', function (geometry, materials) {
for (var i = 0, l = materials.length; i < l; i++) {
materials[i].morphTargets = true;
}
mesh = new THREE.MorphAnimMesh(geometry, new THREE.MeshFaceMaterial(materials));
mesh.position.set(0, -200, 0);
mesh.scale.set(100, 100, 100);
scene.add(mesh);
//
animate();
});
three.jsで表示するフレームを切り替えながらレンダリング
アニメーションをレンダリングします。mesh.morphTargetInfluences[index]で表示するフレームを切り替えながらレンダリングしていきます。mesh.morphTargetInfluences[index]は、アニメーションのフレーム数と同一数のインデックスの配列となっていて、表示したいフレームのインデックスに1を代入し、それ以外の非表示のフレームに0を代入する事で、表示するフレームを切り替える事ができます。ちなみにTHREE.MorphAnimMeshでは、.updateAnimation(delta)メソッドを実行するだけで、自動的にフレームを切り替えながらレンダリングしてくれます。今回のような単純なループアニメーションの場合は、これで十分かとおもいます。
function animate() {
requestAnimationFrame(animate);
// モーフィングアニメーション
lastKeyFrame = currentKeyFrame;
currentKeyFrame ++;
if (TOTAL_FRAMES < currentKeyFrame) {
currentKeyFrame = 0;
}
mesh.morphTargetInfluences[lastKeyFrame] = 0;
mesh.morphTargetInfluences[currentKeyFrame] = 1;
//
renderer.render(scene, camera);
//
controls.update();
}
これで完了です。モーフィングアニメーションが再現されたかと思います。
モーフィングアニメーションのパフォーマンステスト
今回のサンプルでは、60フレーム程度のアニメーションで、2M近いデータ容量となりました。モーフィングアニメーションは、フレーム毎の頂点データを保持していますので、データ容量は、モデリングデータのポリゴン数と、アニメーションのフレーム数が増えるに応じて、増えて行きます。そのため、モーフィングアニメーションを行うキャラクタやポーズが増えてくると、Webコンテンツとしては、容量的に現実的ではなくなります。
メリットとしては、読み込んだデータを表示するだけですので、計算負荷はそれほど高くなりません。試しに400体配置して、モーフィングアニメーションを行ってみました。
まとめ
このような流れで、モーフィングアニメーション実装する事ができます。Blenderは、とにかく触って慣れるしか無いと思いますが、と言ってる僕も複雑な作業は全然出来ません。もうすこし、ちゃんとモデリングしたデータでモーフィングアニメーションを行いたいですね。もっと精進したいと思います。
ピンバック: Blenderでキャラクターアニメーション - code snippets
ピンバック: 3DCG版たぬきを作った(3) 〜three.jsをつかう〜 | DogooBaco
ピンバック: three.jsサンプルを解析してみた。アニメーションミキサー | KnockKnock