当前位置: 首页 > article >正文

[计算机图形学]动画与模拟:关键帧动画、质点弹簧系统、运动学与绑定(前瞻预习/复习回顾)

一、动画的简要概念

动画和语言一样,一开始都是作为传达信息的工具。什么是动画呢?简单的理解就是让画面变成“活的”,也就是让它们能够动起来,其次需要一定的美观。在图形学上,我们可以把动画理解为建模或者是几何的一种扩展,动画就是可以让这些建模和几何在不同的时间有不同的形状或其它属性,也就是加了一个时间的维度。

动画的形成过程就是一些列图片去按顺序播放的过程,我们说过一般来说达到每秒30张图,也就是30FPS,就可以当成视频了,相对来说流畅。而对于一些游戏,要求可能更高,比如144Hz的刷新率或者是165Hz的刷新率。同时对于VR来说,要想达到真实且不使人晕眩的效果,两个眼睛的帧数都要达到90FPS以上。

二、Keyframe Animation—关键帧动画

关键帧动画关键帧,英文Keyframe,就是一段动画中比较重要的几个位置对应的帧,我们将几个重要的帧找出来,然后它们之间的过渡过程来补出来。一开始这些关键帧都是需要大量的人力来补的,且补出来的帧风格大小都要看起来一致,这样才能达到不违和的效果。但是之后有一款软件叫Flash,它可以自动计算补出关键帧之间的帧。

其实关键帧中间补帧就是一个插值的过程,我们之前讲过插值计算,我们可以看到在关键帧中间补帧的过程就是插值的过程如上图,只不过它不一定是线性插值,因为有时候人们可能会要求它有更好的连续性和过度,让它看起来不那么生硬,就和我们之前说的贝塞尔曲线C1,C2,C3,几阶连续类似,所以动画和样条这些东西密不可分。虽然如何过度我们不能直接确定,但是补出的帧一定在两个关键帧之间这是可以确定的。 

三、Physical Simulation—物理模拟

最简单的物理,如牛顿的F=ma,它可以计算力和加速度的关系。物理模拟其实就是计算各种不同的物理公式,从而知道,在不同的时间,我们这些物体的位置,速度,这些属性。如上图的抛物线就是一种物理模拟,而右边的衣服,虽然是一个网格,但是我们可以知道每个顶点所受的重力,以及它的质量,或者受其它顶点牵引的力等等,我们同样可以计算它的各种物理量和受力,从而模拟。

1.Mass Spring System—质点弹簧系统

质点弹簧系统可以模拟绳子,布料,头发等等,是最简单的一种模拟之一。它的最基础的单位是一根弹簧连着两个质点如上图。其中的弹簧是理想弹簧,也就是说它没有长度,拉多长就产生多大的力,如上图公式 fa→b=ks(b-a),其中ks是劲度系数。

当然,实际的弹簧是不可能没有长度的,那么我们也只需在公式中减去弹簧本身的长度l即可。如上图所示,其中b-a的归一化表示的是单位向量,也就是方向。但是这个模型有一个问题,它永远不会停,一直会震动,因为我们没有考虑摩擦力。

于是我们引入摩擦力f,它时刻与速度方向相反,这样物体最终一定会停下来。(上图所示的\dot{b}表示速度,它表示位移b的导数)。当然它也有问题,我们引入的摩擦力,它只能表示外部的力,无法表示弹簧内部的力。 

 于是我们想到了相对速度,它比绝对速度更能表示弹簧内部的关系,所以我们得到如上图的公式\small \bg_white \fn_jvn f_{b} = -k_{d}\frac{b-a}{\left \| b-a \right \|}\cdot \left ( \dot{b}-\dot{a} \right )\cdot \frac{b-a}{\left \| b-a \right \|}{\color{Emerald} },和之前的公式比起来,无非就是把绝对速度改成了相对速度,但是左边再次做了一次归一化是什么意思呢?这里其实是相当于把相对速度在ab方向做投影,为什么要做投影呢?因为某些情况下的相对速度对弹簧是没有影响的,比如b不动,拉着a围绕b做圆周运动,速度方向始终与ab方向垂直,那对弹簧也就没影响。

规定好了这么一个质点弹簧系统我们可以尝试用它模拟一块布如上图,但是我们发现了问题。第一个问题,如果我们拽着这块布的两个角向两边拉他,它会发生切变,但实际上我们真实的布被这样拉拽是不会发生切边的,也就说明真实的布有抵抗切变的性质。第二个问题,我们这块布可以沿着对角线折成三角形,折成一个平面,但是真实的布并不会,它有一种抵抗对折成一个平面的力,我们把这种力叫做out-of-plane bending。这是我们发现的两个问题。

我们先解决第一个切边的问题,我们在原本的正方形网格的布模型上面加入对角线的弹簧,这样就可以阻止切边,我们再次两角拉动这块布的时候,新加入的如上图的蓝色的弹簧会被压缩会抵抗这种切边,这就符合我们真实的一块布了。但是它不对称,这仍然不符合真实的布,一块布的属性各处按理来说都应该是一样的,所以我们两条对角线都加上弹簧,如下图。

当然,单纯的引入两条对角线,并不能解决我们说的第二个问题,它仍然没有抵抗对折成一个平面的力,所以我们最后做一步改进,加上横竖的跨越弹簧,任何一个点都和隔着它的一个点连一根线,这次我们得到了无论怎么形边,它都会影响一些弹簧长度变化的一块布的模型。

2.Particle Systems——粒子系统

有些东西不适合用质点弹簧系统来描述,比如一些很细小的东西,如粉尘,雾等。那么我们就可以用粒子系统来描述它,粒子系统中,我们把这些细小的东西一个一个建模出来,然后定义它们收到的力,有来自粒子之间的力,外部的力如重力,风力等等。与此同时,粒子系统还能模拟流体,我们把一片水可以看成一大堆小水滴。其次,我们说的粒子之间的力可不止有碰撞,还有粒子之间的引力,电磁力等等,我们要计算引力那要考虑一个粒子周围的最近的多少个粒子对它的影响,同时粒子位置的移动导致我们需要更新它,所以粒子的模拟还是有很多挑战性的。

简单的算法模拟就是,1.动态生成新的粒子。2.计算每个粒子所受的各种力。3.更新粒子的位置和速度。4.粒子有存活时间,有些粒子死亡后会有新的粒子加进来。5.最后渲染

我们之前提到过粒子系统可以模拟海浪,水这些东西。而实际上只要是一个群体,是由一群微小的个体组成的,我们都可以用粒子系统去模拟,如鸟群,鱼群,蜜蜂群,只要定义一些简单的规则和相互关系就可以,就像引力和斥力这些东西一样。

四、Kinematics——运动学

1.Forward Kinematics—正向运动学

运动学定义了一套谷骨骼系统,这个 骨骼系统能表示和人一样的骨骼连接的拓扑结构。我们可以定义各种各样的关节。如上图的Pin关节,Ball关节,Prismatic joint关节。Pin关节就是可以旋转的一种关节,当然它只能在2D平面上360°旋转,相当于一个圆,而Ball关节可以在球面上旋转,也就说3D空间中任意旋转。Prismatic joint则是可以拉长一定距离的关节。

如上图中的这么一个关节,如果我们知道每个关节是怎么运动的,那我们就可以算出最后的尖端p最终落在哪个位置,如上图的公式。而这就是正向运动学。

 我们还可以算出随时间位置的变化,p点的位置。

但是正向运动学看起来并不直观,我们并不希望调整这些角度,而是直接调整这些位置,像拉木偶一样。当然好处是给定任意角度,我们都可以计算位置。

2.逆向运动学

逆向运动学干了这么一件事,我们不调整角度,我们去调整我们之前说的尖端p,拽着p任意的移动,这些骨骼关节都会自动的调整角度从而可以实现这个尖端p就是在我们拽的位置,这就是逆向运动学。

上图,同样的例子与正向运动学相对的,逆向运动学就是给定p的位置,计算两个关节的角度θ1θ2,如上图的公式,我们发现特别复杂,方程特别难解。

而且逆向运动学还有一些问题,比如它的方程的解并不唯一,如上图所示,虽然两种情况的尖端位置相同,但是关节的角度有两种截然不同的组合形式。

其次,有些情况下,方程还会无解,比如上图,我们把尖端可能的位置表示出来,发现它只可能停留在半圆的一个扇面上,而如果我们尝试把尖端拽到扇面外,或者扇面里面靠近圆心的位置,这不可能实现,也就是方程无解。

而解决这种问题,本质上仍然是一个优化问题,解决方法有梯度下降法和牛顿法等等,涉及到机器学习的知识,有兴趣的朋友可以自行了解,这里不做介绍。

五、Rigging—绑定

Rigging,绑定,也是制作动画中很重要的一步操作,它的意思就是通过调整不同的控制点从而达到不同的造型目的,就像皮影戏,木偶之类的东西。通过绑定,我们可以调整许多东西,比如角色的姿势,表情等。

同时,通过两种不同的形状下的控制点位置中间的插值,我们同样可以做一些平滑的过度,我们常常用这种方法做表情动画,它有专有的名词叫做Blend Shapes。

六、Motion Capture—动作捕捉

我们说了可以用控制点来达到调整虚拟角色的姿势,那么有一种方法可以在真人身上装备控制点,然后通过真人的运动把控制点的信息返回到虚拟角色上面去,这种方法叫做动作捕捉,如上图。这样我们就可以让动作演员来做动作然后通过控制点记录下来,而不需要人为的手动的去调整,而且更贴近真实感。

动作捕捉有很多的方法,如不在身上绑小球和贴片,而是一些机器。但是人们最常用的还是光学的方法,虽然光学的捕捉方法有很多问题,比如人的胳膊会挡住里面的传感点,而且要用无死角的大量的摄像机去记录,成本高等等。

动作捕捉到的数据

参考:

GAMES101_Lecture_21 (ucsb.edu)

Lecture 21 Animation_哔哩哔哩_bilibili


http://www.kler.cn/news/17275.html

相关文章:

  • 为什么用Selenium做自动化测试
  • ebpf-linux 安全“双刃剑”
  • 不合格机器人工程讲师如何坦然面对失败
  • Java算法比赛常用方法
  • Java入门超详细(内含Java基础 Java高级)
  • 100种思维模型之万物系统思维模型-57
  • Packet Tracer - 配置扩展 ACL - 场景 1
  • C语言通过控制台命令行传入参数
  • 安卓联发科MT6737手机开发核心板 开发模块
  • 【Java笔试强训 15】
  • JS逆向系列之猿人学爬虫第5题
  • 网络编程 总结一
  • Vim 文本查找/替换
  • 都23年了你还记得渐进式框架是什么意思吗
  • 国民技术N32G430开发笔记(18)- I2C1 从机收发数据
  • 【react全家桶学习】react组件中的ref属性(详)
  • K8S之HPA自动扩缩容机制
  • 【五一创作】QML、Qt Quick /Qt中绘制圆形
  • 第四章 数据关联分析方法
  • C/C++每日一练(20230504)
  • [Leetcode] 0697.数组的度
  • api 和 implementation 区别
  • 最大和+翻硬币(蓝桥杯JAVA解法)
  • 【python】创建python包
  • 浅谈MySQL索引以及执行计划
  • 自定义类型:结构体
  • Windeployqt 打包,缺少DLL 的原因分析,解决方法
  • 【网络】网络基础入门
  • Bean的作用域和生命周期
  • Splunk 转移数据之collect 命令