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

相关文章

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放