
前回(BlenderでFBX形式をglTF形式に変換してThree.jsでアニメーションさせる (1/2)) の続きです。
OUTLINE
- Get started (前の記事)
- glTF (GL Transmission Format)とは
- Exporter の準備
- FBXファイルの準備
- Autodesk FBX Converter で変換
- FBXをglTFに変換する (前の記事)
- glTF Metallic Roughness をリンク
- glTFを出力する
- Three.js で3Dを表示させる (前の記事)
- ライブラリの読み込み
- JavaScript 追加
- OrbitControls 追加
- glTFを表示させる (この記事)
- glTFをアニメーションさせる (この記事)
最終的にはこんな感じになります。
Three.js で3Dを表示させる
Three.js はブラウザ上で3Dコンテンツを扱うことができるJavascriptライブラリです。 公式サイトに実例がたくさんあり、見てるだけで楽しいです。
上記公式サイトの左カラムからDLして使います。結構頻繁にアップデートされていて、今回は 90dev を使用。
ライブラリの読み込み
3つのライブラリは上記でDLしたディレクトリ内にあります。 それぞれ適切な位置に配置し、読み込みます。
- three.js-master/build/three.min.js
- three.js-master/examples/js/controls/OrbitControls.js
- three.js-master/examples/js/loaders/GLTFLoader.js
index.html
・ ・ ・ <div class="stage" id="stage"></div> <!-- Three.js本体 --> <script src="three.min.js"></script> <!-- カメラをコントロールするためのライブラリ --> <script src="OrbitControls.js"></script> <!-- glTFを取り扱うためにライブラリ --> <script src="GLTFLoader.js"></script> <script src="index.js"></script> ・ ・ ・
JavaScript 追加
Three.js の基本の流れは
- レンダラの作成、DOMに追加
- シーンの作成
- カメラの作成と追加
- ライトの作成と追加
- メッシュの作成と追加
- レンダリング
という感じです。
index.js
// 幅、高さ取得 const width = window.innerWidth; const height = window.innerHeight; // レンダラの作成、DOMに追加 const renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height); renderer.setClearColor(0xf3f3f3, 1.0); document.body.appendChild(renderer.domElement); // シーンの作成、カメラの作成と追加、ライトの作成と追加 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(50, width / height, 1, 100 ); camera.position.set(0, 1, 5); const light = new THREE.AmbientLight(0xffffff, 1); scene.add(light); // メッシュの作成と追加 const grid = new THREE.GridHelper(10, 5); const sphere = new THREE.Mesh( new THREE.SphereGeometry(1), new THREE.MeshPhongMaterial( { color: 0x0074df } ) ); sphere.position.set(0, 1, 0); scene.add(grid, sphere); // レンダリング const animation = () => { renderer.render(scene, camera); requestAnimationFrame(animation); }; animation();
青い球体が表示されます。
OrbitControls 追加
カメラをグリグリ動かせるように OrbitControls を追加します。
// OrbitControls の追加 const controls = new THREE.OrbitControls( camera, renderer.domElement ); controls.userPan = false; controls.userPanSpeed = 0.0; controls.maxDistance = 5000.0; controls.maxPolarAngle = Math.PI * 0.495; controls.autoRotate = true; controls.autoRotateSpeed = 1.0; // レンダリング const animation = () => { renderer.render(scene, camera); controls.update(); requestAnimationFrame(animation); }; animation();
レンダリングの関数に controls.update();
を追加しています。
これで controls.autoRotate = true;
なので、カメラがオートで回ります。 マウスドラッグやarrowキーで操作も可能です。
glTF を読み込む
その他の形式と同様、ローダークラスを使って、読み込むだけです。
const loader = new THREE.GLTFLoader(); const url = 'tamane.gltf'; loader.load(url, (data) => { const gltf = data; const object = gltf.scene; scene.add(object); });
たまねちゃんが表示されました! が、なんか暗いです。ライティングは問題ないはずでしたが、こちらの解決策はTwitterで教えていただきました。
ありがとうございます!
renderer.gammaOutput = true;
これでとりあえず、glTF形式のモデルを表示させることができました。
glTF をアニメーションさせる
THREE.AnimationMixer
クラスでアニメーションを管理する mixer
を作成し、 gltfオブジェクトの AnimationClip をミキサーに追加、再生します。 作成した mixer
はレンダリング関数で随時 update させることで gltfオブジェクトが動きます。
const clock = new THREE.Clock(); let mixer; // レンダリング const animation = () => { renderer.render(scene, camera); controls.update(); if (mixer) { mixer.update(clock.getDelta()); } requestAnimationFrame(animation); }; animation(); ・ ・ ・ loader.load(url, (data) => { const gltf = data; const object = gltf.scene; const animations = gltf.animations; if (animations && animations.length) { let i; mixer = new THREE.AnimationMixer(object); for (i = 0; i < animations.length; i ++ ) { mixer.clipAction( animations[ i ] ).play(); } } scene.add(object); });
たまねちゃんが走りました! その場で足踏みしてるようになってしまってるので、位置と向きを調整をしてみました。
複数のアニメーションクリップを書き出す方法が分からずここで断念。 待機・走りを切り替えたり、タップ(クリック)した場所に向かって走らせるとかやりたいですね。
FBXをそのままBlenderに読み込めるかどうかは、元データの作り方にかなり依存しているようでした。 3Dデザイナー、モーションデザイナーの方と連携して上手くファイル変換ができるとよいのですが、 企業案件でBlenderを導入してる例をほとんど見たことないのでなかなか難しそうです。 自分でその辺り賄えるようになるのが一番早いのかな……。
おしまい。
※誤りなどありましたら、twitterとかで教えていただけるとありがたいです。