Three.jsでJSON形式でモデルを読み込んでBoneアニメーションさせるときの注意点
ちょっと(だいぶ?)ハマったのでメモ。
いやー、Three.jsはupdateが激しいのと、そもそも日本語記事が少ないのでだいぶ苦戦した。(というか、まだ全然しっかり把握できてないけど)
とりあえず モデルを読み込んでアニメーションさせる 、というWebGLでなにかやるときに避けて通れない処理でハマったのでメモ。
ちなみにモデルデータはBlenderでThree.jsのJSON形式にExportしたものを使用。
Export設定
モデルを作成してBoneをいくつか適当に追加してから(17くらい?)Exportして読み込ませたところ、モデル自体は正常に読み込まれているものの、アニメーションしない。
試しにBoneをふたつ程度に減らしてExport→読み込み、ってしたら動いた。
なので、Boneを複数使って複雑な動きをさせる場合はモデルを分けてThree.js側で合成するなどの処理が必要かもしれない。
ただ、さすがにそれはめんどくさいのでもう少し調べて見ることにする。
ちなみにアニメーションしたソースをいちおう載せておく
var container;
var camera, scene, projector, renderer;
var mesh;
var animation;
var composer;
init();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 800;
camera.target = new THREE.Vector3(0, 0, 0);
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xefefff, 2);
light.position.set(1, 1, 1).normalize();
scene.add(light);
var light = new THREE.DirectionalLight(0xffefef, 2);
light.position.set(-1, -1, -1).normalize();
scene.add(light);
var loader = new THREE.JSONLoader(true);
var url = 'models/some-model.js';
loader.load(url, function(geometry, materials) {
var material = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.SkinnedMesh(geometry, material);
mesh.scale.x = mesh.scale.y = mesh.scale.z = 150.0;
//enable skinning
mesh.material.materials.forEach(function (mat) {
mat.skinning = true;
});
scene.add(mesh);
if (mesh.geometry.animation.name) {
THREE.AnimationHandler.add(mesh.geometry.animation);
animation = new THREE.Animation(mesh, mesh.geometry.animation.name, THREE.AnimationHandler.CATMULLROM);
animation.play();
}
animate();
});
renderer = new THREE.WebGLRenderer({antialias: true, preserveDrawingBuffer: true});
renderer.sortObjects = false;
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
//ポストプロセスの設定
composer = new THREE.EffectComposer(renderer);
composer.addPass(new THREE.RenderPass(scene, camera));
//オリジナルのポストプロセスを追加
composer.addPass(new THREE.ShaderPass({
vertexShader: document.getElementById('vshader').textContent,
fragmentShader: document.getElementById('fshader').textContent,
uniforms: {
ef: { type: 't', value: 0.2 },
tDiffuse: { type: 't', value: null }
}
}));
var toScreen = new THREE.ShaderPass(THREE.CopyShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
animation && animation.update(0.03);
render();
}
function render() {
//theta += 0.1;
//cnt++;
//camera.position.x = radius * Math.sin(THREE.Math.degToRad(theta));
//camera.position.z = radius * Math.cos(THREE.Math.degToRad(theta));
//camera.lookAt(camera.target);
//if (mesh && mesh.morphTargetInfluences) {
// // Alternate morph targets
// var time = Date.now() % duration;
// var keyframe = Math.floor(time / interpolation);
// if (keyframe != currentKeyframe) {
// mesh.morphTargetInfluences[lastKeyframe] = 0;
// mesh.morphTargetInfluences[currentKeyframe] = 1;
// mesh.morphTargetInfluences[keyframe] = 0;
// lastKeyframe = currentKeyframe;
// currentKeyframe = keyframe;
// }
// mesh.scale.set(100, 100, 100);
// mesh.morphTargetInfluences[keyframe] = (time % interpolation) / interpolation;
// mesh.morphTargetInfluences[lastKeyframe] = 1 - mesh.morphTargetInfluences[keyframe];
//}
//renderer.render(scene, camera);
composer.render();
}
参考リンク
Author And Source
この問題について(Three.jsでJSON形式でモデルを読み込んでBoneアニメーションさせるときの注意点), 我々は、より多くの情報をここで見つけました https://qiita.com/edo_m18/items/b94aafe0e47781cf2811著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .