Three.js 变形动画 geometry.morphTargets

发布于 2021-07-30 07:38:20 字数 2943 浏览 1568 评论 0

便于变形动画,你可以理解为多组顶点数据,从一个状态变化到另一个状态,比如人的面部表情。

程序创建变形动画的顶点数据

/**
 * 创建网格模型,并给模型的几何体设置多个变形目标
 */
// 创建一个几何体具有8个顶点
var geometry = new THREE.BoxGeometry(50, 50, 50); //立方体几何对象
console.log(geometry.vertices);
// 为geometry提供变形目标的数据
var box1 = new THREE.BoxGeometry(100, 5, 100); //为变形目标1提供数据
var box2 = new THREE.BoxGeometry(5, 200, 5); //为变形目标2提供数据
// 设置变形目标的数据
geometry.morphTargets[0] = {name: 'target1',vertices: box1.vertices};
geometry.morphTargets[1] = {name: 'target2',vertices: box2.vertices};
var material = new THREE.MeshLambertMaterial({
  morphTargets: true, //允许变形
  color: 0x0000ff
}); //材质对象
var mesh = new THREE.Mesh(geometry, material); //网格模型对象
scene.add(mesh); //网格模型添加到场景中

通过给变形动画几何体设置不同的权重因子查看模型显示效果,通过下面代码测试你可以了解到,如果想产生变形动画效果,一般通过帧动画控制.morphTargetInfluences属性就可以。

//启用变形目标并设置变形目标影响权重,范围一般0~1
mesh.morphTargetInfluences[0] = 0.5;
mesh.morphTargetInfluences[1] = 1;

加载解析变形动画模型

loader.load("./人/umich_ucs.json", function(geometry, materials) {
  // console.log(geometry);
  // console.log(materials);
  // 通过平均面法线来计算顶点法线,效果更光滑
  geometry.computeVertexNormals();
  var mesh = new THREE.Mesh(geometry, materials[0]);
  // 材质对象开启渲染目标
  mesh.material.morphTargets = true
  mesh.rotateX(-Math.PI / 2);
  mesh.position.y = -50;
  scene.add(mesh); //插入到场景中
  // 查看变形目标数据
  // console.log(geometry.morphTargets);
  // 变胖
  // mesh.morphTargetInfluences[0] = 1;
  // 变瘦
  // mesh.morphTargetInfluences[4] = 1;
})

生成变形动画

var mixer = null; //声明一个网格模型变量
loader.load("./鸟/flamingo.json", function(geometry) {
  // console.log(geometry);
  var material = new THREE.MeshPhongMaterial({
    morphTargets: true,
    vertexColors: THREE.FaceColors,
  });
  // 通过平均面法线来计算顶点法线,效果更光滑
  geometry.computeVertexNormals();
  var mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh); //插入到场景中
  // 创建一个混合器,播放网格模型模型的变形动画
  mixer = new THREE.AnimationMixer(mesh);
  // 通过该方法把多个变形目标自动化生成剪辑对象clip
  // 30是fps,影响动画速度
  var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('default', geometry.morphTargets, 30);
  var AnimationAction=mixer.clipAction(clip);
  AnimationAction.timeScale = 0.5; //默认1,可以调节播放速度
  // AnimationAction.loop = THREE.LoopOnce; //不循环播放
  // AnimationAction.clampWhenFinished=true;//暂停在最后一帧播放的状态
  AnimationAction.play();//播放动画
})
// 创建一个时钟对象Clock
var clock = new THREE.Clock();
// 渲染函数
function render() {
  renderer.render(scene, camera); //执行渲染操作
  requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
  if (mixer !== null) {
    //clock.getDelta()方法获得两帧的时间间隔
    // 更新混合器相关的时间
    mixer.update(clock.getDelta());
  }
}
render();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

灵芸

每个人心里都住着一个人,或眷念,或暗恋,或想念。

0 文章
0 评论
23713 人气
更多

推荐作者

挽容

文章 0 评论 0

女中豪杰

文章 0 评论 0

吻安

文章 0 评论 0

cassie

文章 0 评论 0

JinFeng

文章 0 评论 0

undefined

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文