赞
踩
为什么通过这种方式能产生动画的效果呢?
动画的形成过程是由于一张一张的图片快速在人眼识别后,并在大脑里形成短暂影像,因为人眼的视觉暂留,从而每一张图片的动作和场景形成连贯性而形成的。视觉暂留现象是光对视网膜所产生的视觉在光停止作用后,仍保留一段时间的现象,其具体应用是电影的拍摄和放映。原因是由视神经的反应速度造成的。是动画、电影等视觉媒体形成和传播的根据。
按照动画的常见类型可以划分为顶点动画、uv动画、骨骼动画、gpu动画。后续会在原理的基础上按照分类去实现最简单的demo (OpenGL+Assimp),因为再复杂的动画也不过是这些原理加上算法的衍生物。
在进入正题之前,先引入插值这个概念,在大部分的动画实现都会采用这个方式去补全不同帧下动画的状态。
接触比较多的是线性插值
根据上图两个关键帧位置,求第五帧图像所在的位置。取两帧变化的数据即x,f(frame) = kx; 得k = 1, 所以f(5) = 5。
众所周知,屏幕所显示的图元是由顶点构成的。那么我们就可以连续的修改顶点的数据就可以从而达成某种动画效果。平时引擎使用moveTo就是这样的原理。
其它示例:
a)这里通过使用一个正弦函数去控制顶点位置,然后就可以制作一个2D河流的效果
在讲uv动画之前,需要先引入下uv的概念。一般来说纹理的坐标称为uv坐标轴,可以等价为二维坐标xy,u代表x,v代表y。 uv坐标作用用于查找纹理颜色值。
一般u、v取值范围为[0,1]
(u,v)=(0.1,0.1)取得颜色值就是绿色 RGB=(181,230,29)
(u,v)=(0.2,0.8)取得颜色值就是粉色 RGB=(255,174,201)
关于采样的概念,可以简单的理解为根据uv坐标去获取纹理的颜色值。
在HLSL中(着色器的编程语言),texture方法用于以给定的纹理坐标去纹理的数据中查到相应的颜色的信息。按照上图的信息,即aniTexture是纹理数据、newTexCoord是uv坐标。
uv动画原理: 动态更新贴图的uv,以实现模型上纹理细节的变化。
在shader中去更改uv坐标
最后可以简单的实现这个效果
通过使用uv动画搭配算法可以制造有趣的效果。
示例:
溶解效果,就是让某些像素显示,某些像素消失,且这里的消失和显示都具备随机性。为了能达到随机性这里可以使用噪声函数或者直接采用一张噪声图。
实现原理:是在片段着色器中根据当前uv采样噪声图,就可以获得一个遮罩值,从cpu传入一个标准值,当遮照值小于某个标准值就会被片段着色器抛弃。当标准值从0-1变化时便能达成溶解动画。
【噪声图】
【shader源码】
外部调整阈值通道,当阈值达到1时,即代表全部溶解。
最常见的uv动画就是序列帧动画,序列帧动画的原理非常简单,它就像放电影一般一张张切换纹理最后实现动画效果。但是如果使用单张纹理去切换势必会造成显存的开销,所以一般的操作会去把这一系列的动作纹理生成一张纹理图集。
根据更改uv坐标去获取纹理图集每个子图的内容,就能做到纹理切换最后实现动画效果。
【纹理图集】
通过当前帧换算成大合图对应的中纹理坐标
骨骼动画是模型动画中的一种,通过改变骨骼的朝向和位置来为模型生成动画。
原因:人物模型是由众多个三角面组成的。为了让人物动起来,一个最简单的想法是直接修改网格的各个顶点的坐标,这带来了几个问题:逐顶点操作很容易带来非常不自然的结果,随着模型越来越精细,顶点越来越多,操作空间十分巨大,这加大了动画制作的难度。仿照自然界的生物体,一个自然的想法是,可以在网格中放置若干骨骼,骨骼的运动带动网格的运动。这样,动画师只需要操作骨骼,就可以带动网格完成动画的编辑。
相比帧动画优势:帧动画需要提供每一帧图片,而Spine 动画只保存骨骼的动画数据,它所占用的空间小,通过绑骨的矩阵变化便能为游戏提供动画内容。
模型由一个个三角面组成,这种三角面也被称为网格,网格上有一个个顶点。对应在骨骼动画中,网格也被称作皮肤;骨骼之间的连接处称作关节,骨骼可以绕着关节旋转。
原理:骨骼动画最终的效果也是对模型每个顶点做矩阵变换,通过改变模型中每个顶点的位置最终实现动画效果,至于骨骼动画较为复杂的点是在于模型中相同顶点内会受到多个变换矩阵的影响。
这里把这个逻辑简单化,假设下面模型存在一个顶点A,同时受MatA(权重0.2),MatB(权重0.3),MatC(权重0.5) 最终点A的坐标 ((0.2 * MatA) + (0.3 * MatB) + (0.5 * MatC)) * A
对于骨骼中的每一个顶点都是遵循上面的逻辑去改变位置最终实现动画效果。
可参照LearnOpenGL官方文档 [https://learnopengl-cn.github.io/08%20Guest%20Articles/2020/01%20Skeletal%20Animation/]
使用assimp库去加载模型的数据信息,不然通过读取文件的方式去获取动画信息也不免是一件难事(流下不学无术的眼泪)
原理:把动画内容记录成一张纹理,纹理信息的横坐标为顶点数据,纵坐标为动画的帧数。
Shader通过当前第几帧去采样纹理信息,再将纹理信息转换回顶点数据。
使用上述顶点动画不同帧下的顶点数据绘制成纹理,可以得到下图。(注意这里生成纹理的方式耗时相对高,应采用离线的方式或者采用使用多线程去处理,避免卡住主线程。)
后续只需要根据当前需要播放第几帧得动画采样纹理就可以得到对应的顶点数据,按照帧数的变化采样去采样纹理数据再转换成的顶点数据实现动画效果。
优点:
一般运用同屏多人场景,可以降低cpu的运算负担。
缺点:
显存会比原先的占用的高
上文总体介绍了市面上普遍的动画相关内容,并且简单的介绍了对应的原理。
1)Skeletal Animation With Assimp https://ogldev.org/www/tutorial38/tutorial38.html
2)https://learnopengl-cn.github.io/08%20Guest%20Articles/2020/01%20Skeletal%20Animation/
https://gitee.com/xu_zhenhong/open-gl_-ani_-demo_-exe.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。