Heath's Blog

There is no end, it is just the beginning! - A Game Developer's Notes

Real-time Cutscene中的摄像机插值研究

     很多DCC工具都提供了Curves Editor,通过控制点来构造插值曲线,这样可以精确地插值轨迹。在我们游戏的过场编辑器中,我们并没有开发这类工具,一方面由于时间人力有限,另一方面希望能够提供一种直观简便的方式达到想要的效果。因此我们支持两种摄像机路径创建方法:1)以摄像机视角直接将摄像机摆到想要位置,保存此时摄像机的位置与旋转;2)将3DS Max中的路径导出为游戏的过场格式。前者可以满足90%的过场编辑需求,后者满足了10%的复杂路径编辑需求。

     不管使用那种方式,都需要将离散点进行插值(interpolation)以便得到平滑路径。这里就牵涉到位置插值和朝向插值。

     从插值函数上可分为三类:1)线性;2)多项式;3)样条。顾名思义,线性插值采用线性函数,多项式插值采用多项式,而样条插值则采用了一组多项式组成的分段函数。由于摄像机的关键路径点通常都会大于2个,所以插值方法上就必须选取样条方法。

一、位置插值

1.1 样条类型选择

     在这里我们仅考虑三次样条插值,因为它们可达到C2连续。三次样条中主要以Bezier、Catmull-Rom、均匀B样条为考查对象,它们都具有计算开销小的优点。可以通过下面公式来定义它们:

Image(18)

     简化为:

Image(19)

     下面表格列出了三种插值曲线对应的G和M:

Image(20)

     如下图所示,对4个点进行Bezier插值得到的曲线只会有两个点被曲线穿过,而B-Spline插值得到的曲线不会经过控制点,只有Catmull-Rom Spline可以得到穿过除起点和终点之间的所有控制点。正因为Catmull-Rom具有这个特性,使得它被广泛地应用在关键帧平滑插值上,因此我们选择了Catmull-Rom样条作为摄像机位置点的插值算法。

Image(21)

1.2 实现

Image

参考:

[1] Mathematics for 3D Game Programming and Computer Graphics 3e by Eric Lengyel

[2] http://en.wikipedia.org/wiki/Catmull-Rom_spline#Catmull.E2.80.93Rom_spline

[3] http://www.codeproject.com/Articles/30838/Overhauser-Catmull-Rom-Splines-for-Camera-Animatio

二、朝向(旋转)插值  

2.1 Euler Angles VS Quaternion        

     三维空间中描述旋转的主要方法有Euler Angles和Quaternion。Euler Angles有三个明显的问题:1)三轴上的旋转顺序敏感;2)Gimbal Lock现象导致旋转自由度丢失;3)独立地对三个旋转分量进行插值,忽略了三轴之间的依赖关系,导致插值结果不理想。与Euler Angles不同的是,Quaternion没有将旋转分解到三个轴向上,而是用一个旋转轴和绕该轴的旋转角度来描述,所以从根本上消除了Euler Angles的三大问题。有关Quaternion的详细描述可参考[1],在此不再累述。

2.2 LERP VS SLERP

     四元数线性插值(Linear Quaternion interpolation)的计算公式为:

Image(1)

     四元数球面线性插值(Spherical Linear Quaternion interpolation)的计算公式为:

Image(2)

Image(3)

     其中,θ为两个四元数的夹角。

     为了方便展示,我们考虑在2D情况对角度V进行两次插值,两种算法在插值效果上存在的差异,如下图(b为LERP、c为SLERP):

Image(4)

     从图中可以看出LERP其实是对两四元数在圆上的弦进行了等分,而SLERP则是对圆弧进行等分。由此得出的结论是,SLERP得到了比LERP更平滑的插值结果。

     为了保证插值曲线的C2连续性,需要使用球面四边形插值(Spherical Quadrangle interpolation)方法。例如,对q1和q2插值,首先要用q0、q1、q2、q3计算出两个控制点(Inner Quadrangle Point),公式如下:

Image(5)

     然后通过下式得到最终插值结果:

Image(6)

2.3 实现

Image(7)

     上面代码没有考虑两个四元数之间夹角大于180°的情况。例如,考虑q1->q2的插值角度θ>180°,我们可以让q1->q2反向旋转2π-θ,即旋转-(2π-θ),根据四元数的定义[v*sin(θ/2) , cos(θ/2)],那么对q2进行处理变为[-v*sin(θ/2) , -cos(θ/2)]。这个处理可以放在AddSplinePoint中来做:

Image(8)

参考:

[1] Quaternions, Interpolation and Animation by EB Dam - 1998

[2] Game Engine Architecture by Jason Gregory - 2009

[3] https://theory.org/software/qfa/writeup/node12.html

posted on 2013-10-26 09:07 Heath 阅读(2771) 评论(1)  编辑 收藏 引用 所属分类: Game Development

Feedback

# re: Real-time Cutscene中的摄像机插值研究[未登录] 2013-10-27 14:53 烟圈

博主用的什么编程字体,看着好酷。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理