Three.js에서 JSON 형식으로 모델을로드하고 Bone 애니메이션을 만들 때의주의 사항
아니-, Three.js는 update가 격렬한 것과 원래 일본어 기사가 적기 때문에 상당히 고전했다. (라고 할까, 아직 전혀 제대로 파악할 수 없지만)
우선 모델을 읽고 애니메이션 시킨다는 WebGL에서 뭔가 할 때 피할 수없는 처리로 빠졌기 때문에 메모.
우선 결론부터 말하면, **Bone 애니메이션을 시킬 때는,Bone의 수가 문제가 된다**같다.
bone의 수는 아무래도 관계없는 같다. 다시 작성해 보면 정상적으로 애니메이션했습니다.
덧붙여서 모델 데이터는 Blender에서 Three.js의 JSON 형식으로 Export한 것을 사용.
내보내기 설정
모델을 작성해 Bone를 몇개인가 적당히 추가하고 나서(17정도?) Export해 읽어들였는데, 모델 자체는 정상적으로 로드되고 있지만, 애니메이션하지 않는다.
시험에 Bone를 두 정도로 줄이고 Export → 읽고, 하면 움직였다.
그래서 Bone를 복수 사용해 복잡한 움직임을 시킬 경우는 모델을 나누어 Three.js측에서 합성하는 등의 처리가 필요할지도 모른다.
다만, 과연 그것은 귀찮기 때문에 좀 더 조사해 보기로 한다.
덧붙여서 애니메이션 된 소스를 일일이 올려 놓는다.
animation.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();
}
참고 링크
Reference
이 문제에 관하여(Three.js에서 JSON 형식으로 모델을로드하고 Bone 애니메이션을 만들 때의주의 사항), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/edo_m18/items/b94aafe0e47781cf2811텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)