图形化开发(七)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

相关文章

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

MySQL中VARCHAR和TEXT的区别小结

《MySQL中VARCHAR和TEXT的区别小结》MySQL中VARCHAR和TEXT用于存储字符串,VARCHAR可变长度存储在行内,适合短文本;TEXT存储在溢出页,适合大文本,下面就来具体的了解... 目录一、VARCHAR 和 TEXT 基本介绍1. VARCHAR2. TEXT二、VARCHAR

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

python中getsizeof和asizeof的区别小结

《python中getsizeof和asizeof的区别小结》本文详细的介绍了getsizeof和asizeof的区别,这两个函数都用于获取对象的内存占用大小,它们来自不同的库,下面就来详细的介绍一下... 目录sys.getsizeof (python 内置)pympler.asizeof.asizeof

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建