《The Cg Tutorial》阅读笔记——动画 Animation
这段时间阅读了英文版的NVidia官方的《The Cg Tutorial》,借此来学习基本的图形学知识和着色器编程。
在此做一个阅读笔记。
本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4793480.html
动画 Animation
一、基于时间的运动 Movement in Time
实现动画渲染,需要应用程序对时间进行监测,并将它作为一个全局变量传递给着色器。
尽量在GPU上使用顶点着色器执行动画计算是一种高效的动画实现方式,它能够释放CPU,让CPU处理更多的复杂计算,比如碰撞检测,人工智能与游戏玩法。
二、一个做脉冲运动的对象 A Pulsating Object
1. 简介
下面是一个如何让一个对象周期性膨胀变形的例子。这个例子的目标是将时间作为输入参数,然后根据时间修改对象几何体的顶点位置。更确切地说,你需要沿着表面法线移动表面顶点的位置。

根据时间的变化,改变顶点位移Displacement的幅度,就可以创建一个膨胀或脉冲效果。

2. 位移计算 Displacement Calculation
在上述动画实现的过程中,一个重要的过程是计算顶点在法线方向上的位移displacement。你可以为displacement选择一个你喜欢的函数,比如:
displacement = time
也许你不希望物体随时间无限变大,那么你可以选择使用一个周期函数来计算displacement,比如sin函数:
displacement = 0.5 * (sin(time) + 1)
- 在着色器中,sin/cos函数的效率等同于加减法。
此外,你还可以通过为displacement增加参数来控膨胀的幅度、频率,甚至改变膨胀效果:
displacement = scaleFactor * 0.5 * (sin(position.y * frequency * time) + 1)
- scaleFactor表示了膨胀的幅度
- frequency表示膨胀的频率
- position.y用于让不同的顶点具有不同的膨胀幅度,也可以替换成其他任意与顶点属性有关的函数
- 在这里,我们可以对scaleFactor * 0.5做预计算,并将它储存为一个全局变量,以降低顶点着色器的运算压力。
三、粒子系统 Particle Systems
1. 简介
有时,不同于让顶点在网格中运动,我们希望把每一个顶点都作为一个独立的对象,或者称为一个粒子。而遵循某种规律运动的粒子的集合被称为粒子系统。粒子系统会随着时间发生变化。

粒子的运动规律可以使用一个方程来描述,比如物理中的简单矢量运动学方程:
pfinal = pinitial + v * t + 0.5 * a * t2
- pfinal是粒子的最终位置
- pinitial是粒子的初始位置
- v是粒子的初始速度
- a是粒子的加速度
- t是时间
2. 计算粒子位置
在程序中,通过监测全局时间globaTime并将它作为统一参数传递给顶点着色器,当每个粒子被创建时,粒子创建的时间被作为一个变量tInitial传递给顶点着色器。为了知道粒子被激活的时间,你需要使用globaTime减去tInitial:
float t = globaTime - tInitial
再将t代入上一节中的公式:
float4 pFinal = pInitial + vInitial * t + 0.5f * acceleration * t * t
对象空间的位置还需要被转换到裁剪空间:
oPosition = mul(ModelViewProjectionMatrix, pFinal)
3. 计算粒子尺寸 Computing the Particle Size
顶点着色器提供了一个名为PSIZE的输出语义Semantic用于表示顶点的尺寸,当你将一个点Point渲染到屏幕中时,具有该语义的输出参数将会决定该点在像素上的宽高。
4. 美化粒子系统 Dressing Up Your Particle System
我们可以通过使用点精灵Point Sprites提升粒子的外观。使用点精灵时,硬件将会把每个点当作由四个顶点组成矩形来渲染,而不是一个单独的顶点。点精灵的每个顶点会被自动分配纹理坐标,它允许你通过纹理贴图改变粒子的外观。
点精灵能够在不绘制额外三角形的情况下创建复杂的几何效果。
四、关键帧插值 Key-Frame Interpolation
1. 简介
关键帧这个术语来自卡通动画。画家在绘制动画时,会先勾勒出一个粗糙的帧序列动画,其中并没有包含每一帧的画面,而只有重要的,也就是“关键”的帧。随后,画家会补上缺失的帧。有了关键帧做参考,这些中间帧会更容易画。
计算机动画也使用了类似的技术,3D建模师会为动画角色的每个姿势制作一个关键帧。每个关键帧都需要使用相同个数的顶点,且每个顶点必须互相对应。也就是一个关键帧中的顶点必须能够对应到这个模型其他关键帧中相同的点。对于这种关键帧模型,游戏会取模型的两个关键帧,然后将其中每对对应的顶点混合。

关键帧插值假定了顶点在每个关键帧中的个数和顺序都是相同的,这样一来就能够保证顶点着色器总能够正确地将顶点进行配对与混合。
2. 插值方法 Interpolation Approaches
插值的方法有很多,常见的两种是线性插值和二次插值。
1) 线性插值 Linear Interpolation
通过线性插值,位置会以固定的速率转。线性插值公式为:
BlendedPosition = positionA * (1 - f) + position * f
2) 二次插值 Quadratic Interpolation
如果想让转换速率根据时间变化,可以采用二次插值,公式为:
IntermediatePosition = positionA * (1 – f * f) + position * f * f
3) 其他插值方法
除了上诉两种插值公式以外,你还可以使用阶梯函数、样条函数或者指数函数进行插值。

3. 带有光照的关键帧插值 Key-Frame Interpolation with Lighting
当你需要对关键帧模型进行照明时,关键帧插值就不仅涉及到位置的混合,还包括了顶点法线的混合。混合后的法线可能不再是单位向量,因此此时需要对它进行标准化。
五、顶点蒙皮 Vertex Skinning
1. 简介
动画的另一种实现方式是顶点蒙皮,这项技术也被称为“矩阵调色混合“。
不同于关键帧动画,顶点蒙皮动画存储了模型的一个默认姿势和大量用于旋转与移动默认姿势的多边形网格子区域的矩阵,通常,这些矩阵变换被称为骨骼Bones。
每个默认姿势中多边形网格的顶点都被一个或多个这种矩阵所控制,每个矩阵都没指定了一个权重因子,用于指明当前矩阵对顶点的影响程度。假定每个顶点的所有控制矩阵的权重和为1。
当你需要渲染拥有顶点蒙皮的模型时,你需要使用每个顶点的骨骼集合中的所有矩阵对这个顶点执行变换,再将它们按照权重进行混合,得到的位置就是蒙皮顶点的位置。
当所有的矩阵都是单位矩阵时,模型展现的就是默认姿势——通常是站立面向前方,手脚分开向外伸展。
本人博客地址,防止无脑抄袭,影响阅读见谅:http://www.cnblogs.com/dbylk
2. 通过矩阵构建姿势 Constructing Poses from Matrices
通过控制矩阵,你能够创建出不一样的姿势。3D建模师需要将矩阵和对应的权重分配到模型的默认姿势上,而创建姿势的过程就变成了操作矩阵的过程,而不是控制每个独立的顶点。通过这种方式,改变模型的姿势与制作动画变得非常简单。
通常,影响一个顶点的矩阵不会超过4个。
对于角色模型来说,最重要的矩阵被用来代表人物身体中骨骼的移动和旋转,因此顶点蒙皮矩阵被称为骨骼。而顶点则代表了皮肤上的点。
3. 光照 Lighting
同关键帧插值动画一样,在启用光照时,顶点蒙皮动画也需要对法向量进行变换。需要注意的是你需要对每个法向量只需要使用旋转缩放矩阵而不是原矩阵进行变换。同时,混合后也需要对法向量进行标准化。
4. 在存储需求上对比关键帧动画 Storage Requirements Compared with Key Frames
关键帧动画中,每个姿势都需要不同的顶点位置与法向量集合,当角色动作很多时,采用这种方式存储动画是非常不明智的。
顶点蒙皮动画,只需要存储一个默认姿势的顶点位置与法向量集合以及每个姿势的矩阵。通常对一个模型来说,因为矩阵的个数远少于顶点个数,所以使用顶点蒙皮的方式存储动画需要的空间远远少于关键帧动画。
存储顶点蒙皮动画时,每个顶点还需要额外存储控制该顶点的矩阵索引,以及相应的权重因子。
顶点蒙皮非常适合用于存储和回放动作捕捉序列。我们可以将每一个动作捕捉的帧作为骨骼矩阵集合存储起来,并将它应用在拥有相同默认姿势的不同模型上。反向运动学求解器Inverse Kinematics Solver也可以通过生成骨骼矩阵来实现。反向运动学求解器的目的是找到一个能让一个姿势真实自然地过渡到另一个姿势的增量骨骼矩阵序列。
《The Cg Tutorial》阅读笔记——动画 Animation的更多相关文章
- exploit writing tutorial 阅读笔记总结
近日阅读Corelan Team编写的exploit writing tutorial系列,大致了解了一下原理,记了一些笔记.此系列文章有中文翻译版,在看雪论坛上发表. 英文版地址:https://w ...
- [IOS笔记] - 动画animation
//移动 - (IBAction)translation:(id)sender { CABasicAnimation *traslation = [CABasicAnimation animation ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
- amazeui学习笔记--css(常用组件15)--CSS动画Animation
amazeui学习笔记--css(常用组件15)--CSS动画Animation 一.总结 1.css3动画封装:CSS3 动画封装,浏览器需支持 CSS3 动画. Class 描述 .am-anim ...
- View 动画 Animation 运行原理解析
这次想来梳理一下 View 动画也就是补间动画(ScaleAnimation, AlphaAnimation, TranslationAnimation...)这些动画运行的流程解析.内容并不会去分析 ...
- Head First HTML与CSS阅读笔记(二)
上一篇Head First HTML与CSS阅读笔记(一)中总结了<Head First HTML与CSS>前9章的知识点,本篇则会将剩下的10~15章内容进行总结,具体如下所示. div ...
- Detectron2源码阅读笔记-(一)Config&Trainer
代码结构概览 核心部分 configs:储存各种网络的yaml配置文件 datasets:存放数据集的地方 detectron2:运行代码的核心组件 tools:提供了运行代码的入口以及一切可视化的代 ...
- 阅读笔记 1 火球 UML大战需求分析
伴随着七天国庆的结束,紧张的学习生活也开始了,首先声明,阅读笔记随着我不断地阅读进度会慢慢更新,而不是一次性的写完,所以会重复的编辑.对于我选的这本 <火球 UML大战需求分析>,首先 ...
- [阅读笔记]Software optimization resources
http://www.agner.org/optimize/#manuals 阅读笔记Optimizing software in C++ 7. The efficiency of differe ...
随机推荐
- UTF-8具体解释
UTF-8是一种变长字节的编码方式.它以8位(1字节)为单位对Unicode进行编码. UTF-8理论上最多能够达到6字节长.但眼下全世界的字符仅仅须要4字节就能够表示完. UTF-8规定,对于某一字 ...
- lucene实现初级搜索引擎
一.系统设计 搜索引擎项目代码主要分为三个部分,第一部分是构建索引,全文检索:第二部分是输入问题,对问题进行分词.提取关键词.关键词扩展:第三部分是将搜索结果输出到GUI图形用户界面. 二.搜索引擎 ...
- python 对象和类
python中所有数据都是以对象形式存在.对象既包含数据(变量),也包含代码(函数),是某一类具体事物的特殊实例. 面向对象的三大特性为封装.继承和多态. 1.定义类 #定义空类 class Pers ...
- 笔记-CSS空背景图片会导致页面被加载两次
如果页面样式的背景图片路径设置为'' 或 '#', 会导致页面被重复加载两次 (Chrome.56.0.2924.87 测试) 因为:空图片路径属性值,默认加载当前页面的URL作为图片路径 Safar ...
- Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration info
Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the ...
- jmeter之报告和分析
转载:http://www.cnblogs.com/miaomiaokaixin/p/6118081.html jmeter -n -t 脚本名字.jmx -l xxx.jtl -e -o 指定目录( ...
- C#中各种数据类型可以表示的数据的范围
C#中各种数据类型可以表示的数据的范围 BOOL型为int型,一般认为占4个字节,取值TRUE/FALSE/ERROR. sbyte型为有符号8位整数,占1个字节,取值范围在-128 - 127之间. ...
- python继承,判断类型,多态
1.python中继承 如果已经定义了Person类,需要定义新的Student和Teacher类时,可以直接从Person类继承: class Person(object): def __init_ ...
- jQuery动态网址标签
在线演示 本地下载
- zabbix监控php-fpm的性能
zabbix监控php-fpm主要是通过nginx配置php-fpm的状态输出页面,在正则取值 要nginx能输出php-fpm的状态必须要先修改php-fpm的配置,这个配置没有开启nginx 就没 ...