Real-Time Rendering-第四章 Transforms(4)

4.4 Vertex Blending

想象一下数字人物的一只手臂通过两个部分,前臂和上臂产生的动画,如图4.10所示。这种动画模型可以使用刚体变换表示(见4.1.6节)。但是,使用刚体时手臂两个部分之间的关节无法组成真正的肘。这是因为使用了两个独立的对象,并且关节是由这两个独立对象的重叠部分组成的。很显然,使用单个的对象会更好一点。但是,静态模型的部分无法解决关节灵活性的问题。

Vertex blending(顶点混合)是该问题的一种可行的解决方法[770,1376]。这种技术还可以称为skinningenveloping,或skeleton-subspace deformation。虽然这里提出的算法没有确切的原始说明,但是在计算机动画中很早就有了骨骼及对应的皮肤变化的定义[807]。在简单的动画形式中,前臂和上臂与之前一样分别是独立产生动画的,但是在关节处则是通过一种有弹性的“皮肤”把这两个部分进行连接。因此,这个弹性的部分将会具有一组顶点使用前臂的变换矩阵进行变换,还有另一种组顶点通过上臂的矩阵进行变换。这种变换产生的三角形的顶点可能是由不同的矩阵变换得到的,而不是对每个三角形使用单个矩阵进行变换。如图4.10所示。这种基础技术有时也称为stitching(缝合)[1376]。

这里写图片描述
图4.10 左图中是使用两个独立对象的刚体变换,表示的由前臂和上臂组成的手臂动画。这种变换的肘部看起来很不真实。在右图中,则是对单个对象使用vertex blending技术。然后在最右边的图中显示了使用一种简单的皮肤直接把这两个部分连接起来,再覆盖关节部分产生的结果。最右边的手臂演示了使用vertex blending产生的结果,并且使用不同的权重值对部分顶点进行混合: (2/3,1/3) 表示在变换时上臂的在顶点中权重为 2/3 ,前臂的权重为 1/3 。该图中最右边还显示了vetex blending的一个缺点,从中可以明显的看出手肘内侧有一点折叠。通过使用更多的骨骼,以及更精细的权重比例可以产生更好的动画结果。

通过对此变换做进一步处理,我们可以使用多个不同的矩阵对单个顶点进行变换,然后把结果坐标通过加权混合到一起。这是通过对动画对象的每一根骨头设定一个骨骼完成的,其中每一根骨头的变换会根据用户自定义的权重对每个顶点施加影响。由于整个手臂都可能是“弹性的”,即每个顶点都会受多个矩阵的影响,因此把整个mesh称为一种(覆盖到骨头上的)skin(皮肤)。如图4.11所示。许多商业模型系统使用了同样类型的骨骼-骨头模型特性。尽管从名称上看骨头像一种刚体,但是实际上骨头并不需要具有刚体的特性。比如,Mohr和Gleicher[889]提出了添加额外的关节以支持肌肉凸起效果的想法。James和Twigg[599]讨论了如何使用骨头的动画皮肤产生压扁和拉伸的效果。
这里写图片描述 这里写图片描述

这里写图片描述
图4.11 一个使用vertex blending的示例。左上图中显示了手臂的两根骨头处于伸展的状态。在右上图中显示了手臂对应的mesh,其中使用不同的颜色标出了骨头包含的每一个顶点。最下面的图中显示了着色后的手臂mesh处于一个稍微不同的位置。

这种变换在数学上使用公式4.56表示,其中 p 表示原始的顶点, u(t) 是变换后的顶点,该顶点的位置与时间 t 有关。有 n 个骨头会影响顶点 p 的坐标位置,该顶点位于世界坐标中。其中矩阵 Mi 表示从原始的骨头坐标系变换到世界坐标。通常情况下,骨头的控制关节位于骨头坐标系的原点。例如,一个前臂骨头会将其肘关节移动到原点,之后就可以使用一个动画旋转矩阵把手臂这部分围绕关节移动。其中矩阵 Bi(t) 就是第 i 个骨头的世界变换,随着时间的推移使得对象形成动画,并且该矩阵通常是一系列矩阵的串联,比如之前骨头变换的层次矩阵结构和局部动画矩阵。Woodland[1376]深入讨论了一种方法,用于维持及更新矩阵 Bi(t) 的动画函数。最后一个参数 wi 表示第 i 个骨头在顶点 p 中的权重值。Vertex blending 公式为

u(t)=i=0n1wIBi(t)M1ip,i=0n1wi=1,wi0.(4.526)

每个骨头将顶点变换到相对于其参照帧的位置,然后由计算的位置点集插值得到最终的位置。在一些关于skinning的讨论中并没有明确指出矩阵 Mi ,而是把该矩阵看成是 Bi(t) 的一部分。在本书中我们之所以描述该矩阵是因为这是一个实用的矩阵,几乎总是矩阵串联过程的一部分。

实际上,矩阵 Bi(t) Mi 总是串联到一起用于动画的每一帧中的每一个骨头,并使用所产生的矩阵对顶点进行变换。通过不同骨头的串联矩阵对顶点 p 进行变换,然后使用权重值 wi 混合顶点——因此称为vertex blending。由于权重都是非负值,并且总和为1,因此计算的过程是把顶点变换到多个位置然后在这些位置点之间进行插值。由此变换得到的点 u 位于 对于所有 i=0n1 t 为固定值)的Bi(t)M1ip点集组成的convex hull(凸包)中。另外,也可以使用公式4.56变换顶点的法线。根据所使用的变换(比如,如果骨头发生了相当大程度的拉伸或挤压),可能会需要用到 Bi(t)M1i 的逆矩阵的转置,如4.1.7节所述。

Vertex blending非常适合在GPU上使用。可以Mesh中的顶点集存放到静态缓存中一次性发送到GPU中,并重复使用。在每一帧中,只有骨头矩阵会发生变化,并使用一个vertex shader计算这些矩阵对存储的mesh产生的影响。通过这种方法,可以最小化在CPU中处理并传递的数据量,从而使GPU更高效的渲染mesh。如果可以同时使用模型的全部骨头矩阵,则计算是最简单的;否则就要把模型分割成多个部分,一些骨头就会被重复计算。

注:在DirectX中提供了一个通用的ConvertToIndexedBlendedMesh函数用于执行这种分割操作。

在使用vertex shader的情况下,可以指定超出[0,1]范围的权重值,或者所有权重值的总和不为1。但是这种情况只有在使用其他的混合算法,如morph targets(见4.5节)时才有意义。

使用基本vertex blending的缺点之一是,产生多余的折叠,扭曲,以及自相交的效果。如图4.12所示。解决该问题最好的文案之一是使用由Kavan等人提出的dual quaternions[636]。使用这种执行skinning操作的技术有利于保持原始变换刚体属性,因此可以避免产生类似“糖果包装纸”的四肢扭曲效果。这种算法相对于线性的skin blending算法来说只是增加了不到1.5倍的计算成本,但是产生的结果却是非常好的,因此这处技术被迅速采用。有兴趣的读者可以参考相关的论文,其中包含了对改进的线性blending的简要总结。
这里写图片描述 这里写图片描述

这里写图片描述 这里写图片描述
图4.12 左侧两个幅图中显示了使用线性blend skinning时关节处出现的问题。在右边的两幅图中使用dual quaternions的混合改善了显示效果。(图片由Ladislav Kavan等人免费提供,模型由Paul Steed提供[1218])

4.5 Morphing

在执行动画时从一个三维模型渐变到另一个三维模型的操作是非常有用的[16,645,743,744]。想象这样一种情形,在 t0 时刻显示了某个模型,我们希望在 t1 时刻变成另一个模型。对于 t0 t1 之间的所有时刻,可以使用某种插值运算获得一连串的“混合”模型。图4.13中显示了一个使用morphing技术的示例。
这里写图片描述

这里写图片描述

这里写图片描述
图4.1 Vertex morphing示例。每个顶点都定义了两个位置和法线向量。在每一帧中,通过vertex shader进行线性插值得到中间顶点的位置和法线向量。(图片由NVIDIA公司免费提供)

动画渐变主要包括两个问题,分别为vertex correspondence问题以及interpolation问题。给定两个任意的模型,可能具有不同的顶点topology顺序,不同的顶点数量,以及不同的mesh连通性,通常需要先建立顶点之间的对应关系。这是一个非常困难的问题,而且在该领域已经有了大量的研究。我们建议有兴趣的读者可以查看Alexa的概述。

但是,如果两个模型的顶点之间具有一一对应的关系,那么可以以每一个顶点为基础进行插值运算。也就是说,对于第一个模型中的每个顶点,在第二个模型中必须只存在一个对应的顶点,反之亦然。这种情况下,插值运算是非常简单的。例如,可以在顶点上直接进行线性插值(关于其他的插值方法,详见第13章13.1节)。要计算 t[t0,t1] 时刻的渐变顶点,首先需要计算插值因子 s=(tt0)/(t1t0) ,然后执行线性的vertex blend运算,

m=(1s)p0+sp1.(4.57)

其中 p0 p1 对应于不同时刻 t0 t1 的同一个顶点。

关于渐变操作有一种非常有趣的变种,能让用户进行更直观的控制,通常称为morph targets或者blend shapes[671]。可以使用图4.14简单描述这种基本思想。
这里写图片描述
图4.14 给定两种嘴型,通过计算一组差值向量可以控制对内的插值运算,甚至是对外插值。在morph targets的情况下,使用差值向量可以在中性面部表情上“添加”一些情绪。对于包含正权重值的差值向量,会得一种微笑的嘴型;而负权重值将会产生相反的效果。

我们从一个中性的模型开始讨论,在这里表示一种面部表情。我们使用记号 N 表示该模型。此外,我们还有一套不同的面部表情。在示例图中,仅有一种微笑的表情。一般情况下,可以支持 k1 种不同的表情,分别表示为 Pii[1,,k] 。作为预处理,使用公式 Di=PiN 计算“面部的差值”,即从每一种面部表情减去原始的中性模型。

此时,我们有了一个中性模型 N ,以及一组表情差值 Di 。然后就可以使用以下公式获得渐变模型 M

M=N+i=1kwiDi.(4.58)

该公式表示根据需要使用不同的权重值 wi ,在中性模型的基础上添加不同的表情特性。如图4.14所示,设置 w1=1 会得到如中间图所示的微笑的面部表情。而设置 w1=0.5 则会得到半微笑的表情,依次类推。也可以设置权重值为负数,以及大于1的权重值。

对于这种简单的面部模型,我们可以增加另一种带有“悲伤”皱眉的面部表情。对眉部使用一个负的权重值可以创建“高兴”的眉部。由于位移是累加的,这种眉头姿势可以与一种微笑的嘴部姿势一起使用。Morph targets这种强大的技术,为动画师提供了大量的控制,因为一个模型的不同特征可以独立于其他的模型进行操作。Lewis等人[770]引入pose-space deformation概念,这种方法结合了vertex blending和morph targets技术。支持DirectX 10的硬件可以使用stream-out和其他改进的功能,支持在单个模型中使用多个targets,并且这种效果专门使用GPU进行计算[793]。

图4.15中显示了一个同时使用skinning和morphing技术的示例。

这里写图片描述 这里写图片描述

这里写图片描述 这里写图片描述
图4.15 Rachel角色的面部表情及情绪变化由skinning和vertex morphing进行控制,这种技术是在图形加速硬件的支持下实现的。(图片由Alex Vlachos,John Isidoro,Dave Gosselin和Eli Turner制作;ATI Technologies Inc.和LifeFX免费提供)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值