图形化开发(七)03-Three.js之动画——区别-变形动画(精度要求高-人物表情) 骨骼动画(精度要求低-人物走动)

本文主要是介绍图形化开发(七)03-Three.js之动画——区别-变形动画(精度要求高-人物表情) 骨骼动画(精度要求低-人物走动),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

图形化开发(七)03-Three.js之动画——区别-变形动画(精度要求高-人物表情) & 骨骼动画(精度要求低-人物走动)

两种动画的区别

变形动画主要用于精度要求高的动画,比如人物的面部表情。优点是动画表达会很到位,缺点就是扩展性不强,只能执行设置好的相关动画。

骨骼动画主要用于那种精度要求低,而且需要丰富多样的动画,就比如人物的走动,攻击防御等动画,我们可以通过一套骨骼,修改相应骨骼的位置的信息直接实现相应的效果。确定是没有变形动画的精度高,但是可以实现多种多样的效果。

总结:我们可以根据项目的需求来设置不同的动画,就比如一个人物模型,说话我们使用变形动画去实现,而肢体动作使用骨骼动画去实现。

导入动画

https://sketchfab.com/3d-models?date=week&features=downloadable&sort_by=-likeCount

在Three.js的动画系统中,你可以为模型的各种属性设置动画:骨骼动画,变形动画,材质的相关属性(颜色,透明度, 是否可见)。动画属性可以设置淡入淡出效果以及各种扭曲特效。也可以单独的改变一个对象或者多个对象上的动画的影响程度和动画时间。
为了实现这些,Three.js动画系统在2015年修改为了一个类似于Unity和虚幻引擎4的架构。接下来我们了解一下这套动画系统的主要组件以及它们时如何协同工作。

  1. 在模型加载成功以后,我们首先将模型创建出来,并将材质的morphTargets设置为ture,可以使用变形动画:

    mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({vertexColors: THREE.FaceColors,morphTargets: true
    }));
    mesh.castShadow = true;
    mesh.scale.set(0.1, 0.1, 0.1);
    scene.add(mesh);
  2. 然后我们创建了一个针对于该模型的混合器:

    mixer = new THREE.AnimationMixer(mesh);
    
  3. 接着使用变形目标数据创建一个动画片段:

    var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('gallop', geometry.morphTargets, 30);
    
  4. 使用混合器和动画片段创建一个动画播放器来播放:

    var action = mixer.clipAction(clip); //创建动画播放器
    action.setDuration(1); //设置当前动画一秒为一个周期
    action.play(); //设置当前动画播放
    
  5. 最后,我们还需要在重新绘制循环中更新混合器,进行动作更新:

    function render() {control.update();var time = clock.getDelta();//由于模型导入是异步的,所以我们再模型没有加载完之前是获取不到混合器的if (mixer) {mixer.update(time);}renderer.render(scene, camera);
    }
    
实例

效果-live server打开

在这里插入图片描述

代码

import.html

<!DOCTYPE html>
<html lang="zh"><head><meta charset="UTF-8"><title>JSON模型动画案例</title><style type="text/css">html,body {margin: 0;height: 100%;}canvas {display: block;}</style>
</head><body onload="draw();"></body>
<script src="https://cdn.bootcss.com/three.js/92/three.js"></script>
<script src="./control.js"></script>
<script src="http://www.wjceo.com/lib/js/libs/stats.min.js"></script>
<script src="https://cdn.bootcss.com/dat-gui/0.7.1/dat.gui.min.js"></script>
<script>var renderer, camera, scene, gui, stats, ambientLight, directionalLight, control;var mixer, clock = new THREE.Clock();function initRender() {renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);//告诉渲染器需要阴影效果renderer.shadowMap.enabled = true;renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 默认的是,没有设置的这个清晰 THREE.PCFShadowMapdocument.body.appendChild(renderer.domElement);}function initCamera() {camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.set(0, 50, 100);camera.lookAt(new THREE.Vector3(0, 0, 0));}function initScene() {scene = new THREE.Scene();}function initGui() {//声明一个保存需求修改的相关数据的对象gui = {};var datGui = new dat.GUI();}function initLight() {ambientLight = new THREE.AmbientLight("#111111");scene.add(ambientLight);directionalLight = new THREE.DirectionalLight("#ffffff");directionalLight.position.set(40, 60, 10);directionalLight.shadow.camera.near = 1; //产生阴影的最近距离directionalLight.shadow.camera.far = 400; //产生阴影的最远距离directionalLight.shadow.camera.left = -50; //产生阴影距离位置的最左边位置directionalLight.shadow.camera.right = 50; //最右边directionalLight.shadow.camera.top = 50; //最上边directionalLight.shadow.camera.bottom = -50; //最下面//这两个值决定生成阴影密度 默认512directionalLight.shadow.mapSize.height = 1024;directionalLight.shadow.mapSize.width = 1024;//告诉平行光需要开启阴影投射directionalLight.castShadow = true;scene.add(directionalLight);}function initModel() {//底部平面var planeGeometry = new THREE.PlaneGeometry(100, 100);var planeMaterial = new THREE.MeshLambertMaterial({ color: 0xaaaaaa, side: THREE.DoubleSide });var plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.rotation.x = -0.5 * Math.PI;plane.position.y = -.1;plane.receiveShadow = true; //可以接收阴影scene.add(plane);var loader = new THREE.JSONLoader(); // 原生自带loader.load("./source/horse.js", function (geometry) {mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({vertexColors: THREE.FaceColors,morphTargets: true   // morphTargets 强调是动画}));mesh.castShadow = true;mesh.scale.set(0.2, 0.2, 0.2);//调节动画大小scene.add(mesh);mixer = new THREE.AnimationMixer(mesh); // 需要实例化var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('gallop', geometry.morphTargets, 30); // 可以去优化性能mixer.clipAction(clip).setDuration(0.5).play(); //setDuration 调节时间-越小动画越快});}function initStats() {stats = new Stats();document.body.appendChild(stats.dom);}function initControl() {control = new THREE.OrbitControls(camera, renderer.domElement);}function render() {control.update();var time = clock.getDelta();if (mixer) {mixer.update(time);}renderer.render(scene, camera);}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}function animate() {//更新控制器render();//更新性能插件stats.update();requestAnimationFrame(animate);}function draw() {initRender();initScene();initCamera();initLight();initStats();initModel();initGui();initControl();animate();window.onresize = onWindowResize;}
</script></html>

注意参数:

//创建模型
function initModel() {}//调节光线function initLight() {}

这篇关于图形化开发(七)03-Three.js之动画——区别-变形动画(精度要求高-人物表情) 骨骼动画(精度要求低-人物走动)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/435748

相关文章

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

JS 实现复制到剪贴板的几种方式小结

《JS实现复制到剪贴板的几种方式小结》本文主要介绍了JS实现复制到剪贴板的几种方式小结,包括ClipboardAPI和document.execCommand这两种方法,具有一定的参考价值,感兴趣的... 目录一、Clipboard API相关属性方法二、document.execCommand优点:缺点:

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

基于Python开发PPTX压缩工具

《基于Python开发PPTX压缩工具》在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,不便于传输和存储,所以本文将使用Python开发一个PPTX压缩工具,需要的可以了解下... 目录引言全部代码环境准备代码结构代码实现运行结果引言在日常办公中,PPT文件往往因为图片过大而导致文件体积过大,

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是