首页 百科知识 粒子和群集动画

粒子和群集动画

时间:2023-10-16 百科知识 版权反馈
【摘要】:群集动画是现在电影制作中经常会听说的单词,很多好莱坞大片中都会有气势磅礴的大场面,成千上万的飞机或者士兵在屏幕上运动,给人很强的震撼力,使用Sprite粒子可以很轻松的完成这种效果的制作。可以看出粒子有大小。

第五节 Sprite粒子和群集动画

群集动画是现在电影制作中经常会听说的单词,很多好莱坞大片中都会有气势磅礴的大场面,成千上万的飞机或者士兵在屏幕上运动,给人很强的震撼力,使用Sprite粒子可以很轻松的完成这种效果的制作。

这里我找到了一些经典游戏的角色跑动的图片,在这里有强烈的冲动制作一个大家一起跑的大场面,所以先使用AfterEffect将所有的图片转换成了iff各式的图片序列:

img796

img797

是不是很眼熟?这一节就要让这些角色变成大片的士兵然后排山倒海的往前冲锋,在制作前先确定每一个角色在图片序列中的位置:

img798

img799

所以一共使用了57帧。

接下去进入Maya制作场景,这次利用粒子目标(goalPP)制作一个在凹凸不平的地面上一群战士从一边冲向另一边的地群集动画,所以场景很简单就是一个nurbs的地面就可以了:

img800

接下来使用雕刻刀将地面休整一下,只要有起伏就可以了:

img801

接下来就是创建一个粒子发射器,然后使用goalPP属性将粒子制作成在面上移动的效果:

使用菜单命令Particles→CreateEmitter创建一个粒子发射器(使用默认参数就可以):

img802

接下去,先选中发射出来的粒子,再同时选中地面,使用菜单命令:Particles→Goal制作粒子目标:

img803

这时候,粒子的PerParticleAttributes里面增加了一个goalPP属性,粒子也附着到了地面上面:

img804

这还不够,我需要的是粒子瀑布的效果(在本书基础部分有详细制作)所以为粒子添加另外两个属性goalV和goalU,这两个属性将会被用来制作粒子沿着地面移动的效果,在此之前还是要显示出地面nurbs的U和V的方向,如上图所示。

(显示出地面nurbs的U和V的方向使用菜单命令Display→nurbsComponents→SurfaceOrigins)

img805

为粒子添加goalV和goalU属性:

img806

接下来结合地面的UV方向为goalV和goalU属性进行控制,在粒子前进的方向使用ramp控制产生顺序前进的效果,在垂直于前进的方向使用表达式rand(0,1)来产生这个方向上面随机出现的效果,所以这个地面的表达式和ramp控制如下:

在V方向上随机出现在goalV上面使用了Creation表达式:

img807

img808

在U方向上面前进,所以使用了ramp控制goalU:

img809

所以粒子在u方向上面前进,在v方向上面一字排开,很像是瀑布一泻而下的感觉,用在士兵冲锋陷阵上面很有视觉震撼力。

接下去把粒子的生命周期设置到适当的值,因为默认的使用了ramp控制以后,粒子的生命周期就变成了1。

修改粒子的生命周期值:

粒子的生命后期越长,粒子运动的速度就会越慢,使用随机值会产生粒子的速度各不相同,效果更加真实:

img810

这样,粒子在地面上前进的效果做好了,接下来就是把粒子变成我们的图片序列了,所以首先是把粒子变成Sprite(精灵)粒子:

img811

我们将摄影机视角放到如上图的角度,原因是Sprite(精灵)粒子总是正面对着摄像机,而图片序列是正侧面,面向右边的。只能使用这个角度,制作一群人向右奔跑的效果。

给粒子一个Lambert材质,紧接着就是开始粒子动画贴图的工作,这次的贴图不再是循环那么简单了,但是除了控制spriteNumPP属性的表达式不一样以外,其他的软件操作都是一样的:

首先给粒子材质一个文件纹理节点:

img812

接下来在文件纹理节点里倒入贴图的第0张:

img813

接下来,使用UseImsgeSequence,并设置关键帧如下图,同时启动粒子贴图缓存(UseInteractiveCathing)并且进行设置如下:

img814

这样贴图序列被缓存,可以通过spriteNumPP控制粒子的贴图动画了,首先还是为粒子添加spriteNumPP属性:

img815

接下来是给spriteNumPP属性一个Creation表达式:particleShape1.spriteNumPP= trunc(rand(0,56));这样粒子在出现的时候就是57张图片中的一个,产生大群角色出现的场面:

img816

现在的角色是不会循环跑动的,只是一张静止的图片而已,要让角色跑动起来就必须要使用RunTime表达式,但是简单的循环是不可以的了,因为所有的角色都在同一个图片序列里面,所以表达式就比较复杂:

按照前面所学的知识,为了制作粒子贴图的循环我们通常会使用这个RunTime表达式:

img817

这里的X代表图片序列的总的帧数。

在这里不能使用这样的简单的表达式了,因为所有的角色图片序列都处于同一个图片序列中,在本节开始的时候有过对这个图片序列的分析,要使不同的角色产生循环可以用以下的表达式:

img818

这里的Y就是角色第一帧在整个图片序列里面的位置,particleShape1.spriteNumPP%X产生0~X的循环,加上Y就产生了Y-(Y+X)的循环,于是就可以产生角色单独循环了。

所以我们为粒子添加一个自定义的PerParticles粒子属性(num),用这个属性来确定那一个粒子使用哪一个角色(一共10个角色):

img819

为这个属性添加一个Creation表达式:

img820

img821

于是,该属性拥有0~9随机整数,我们认为它代表了10个角色中的一个。也就是说,粒子产生的一瞬间就确定了在这个粒子身上产生的那一接下来,为了能够清晰的控制每一个角色的spriteNumPP,我们为粒子添加一个自定义的属性:cycle

img822

我们将使用这个属性的递增,来产生单个角色的循环计数器,所以首先为它制作Creation表达式,产生一个随机数,用于产生单个角色循环开始时候的不同Pose:

img823

于是,整个粒子贴图的循环控制表达式(RunTimeExpression)是:

img824

img825

这里通过if(particleShape1.num==X)来确定使用哪一个角色,然后使用particleShape1.spriteNumPP=(particleShape1.spriteNumPP%X)+Y;来产生该角色的循环。

if(...){...}是一个条件语句,只要小括号中的条件满足了,那么就执行中括号中的语句,这里的两个等于号==表示判断是否相等,如果相等就执行后面中括号里面的表达式。

所以,不同的粒子有不同的num值,不同的num值就对应了不同的角色循环,于是就产生了不同的角色在跑动:

以下两张图片相隔两帧:

img826

img827

接下去进入粒子运动形态的细节处理,进入侧视图:

img828

很容易发现两个问题:

1.所有的角色的大小都一样;

2.角色没有站在地面上,因为粒子时中心位置处于地面上的;

3.粒子始终保持水平和垂直,并没有随着地面的起伏而产生旋转。

第一个问题很好解决只需要控制粒子的spriteScaleYPP和spriteScaleXPP属性就可以了,所以为粒子添加spriteScaleYPP和

img829

img830

然后,为这两个属性添加Creation表达式:这样就会使得粒子的大小处于0.8到1.2之间,角色也就有大有小了。可以看出粒子有大小。角色也同时产了大小的变化了:

img831

效果如下图:

img832

接下来要解决的是角色没有落在地面上,要解决这个问题就需要从粒子的目标属性上解决,粒子是使用goalPP属性产生运动效果的,所以在目标属性上能够产生偏移量那么就能够让粒子在地面上产生上移的效果。

要产生目标点位置的偏移量可以使用goalOffset属性,这个属性可以产生粒子对目标点的偏移,所以为粒子添加goalOffset粒子属性:

img833

为了能够让角色正好站在地面上,我们需要使粒子偏移1/2的粒子的高度(因为粒子是中点落在地面上的),1/2的高度就是particleShape1.spriteScaleYPP的一半了,所以可以得出goalOffset的表达式:

由于goalOffset属性是一个矢量值是在三维空间里面的偏移,所以表达式写成:

img834

img835

img836

可以看到,粒子中的角色已经站在地面上了,接下来就要解决最后一个问题,粒子没有随着地面的形势,产生应有的倾斜。

使Sprite(精灵)粒产生倾斜,可以使用Sprite(精灵)粒产特有的粒子属性spriteTwistPP:

SpriteTwistPP属性可以设置设置场景中每一个粒子位置的旋转角度。例如,值为45时,将沿逆时针旋转图像45度。

所以,我们希望粒子能够垂直于地面,那么就应该旋转一个角度,这个角度应该和地面的切线方向与水平面形成的角度有关:

img837

所以我们可以得出结论,粒子旋转的角度就等于Y轴方向和地面切线方向的夹角减90度,由于粒子是逆向旋转,所以应该是:90-夹角。

那么每个粒子所在地面的那一点的切线方向又如何得到呢?很简单,切线方向就是粒子的速度方向:particleShape1.worldVelocity.

所以我们有如下表达式:

img838

//angle函数就是用来产生两个向量之间夹角的函数。

particleShape1.spriteTwistPP=90-(rad_to_deg($angle));

//由于是使用向量产生的夹角,得到的值的单位是:弧度。所以必须通过rad_to_deg函数将弧度转换成角度值,这个函数就是转换弧度值用的。

于是表达式窗口:

img839

效果如下图:

img840

可以看到角色除了站在地面上,还随着地势的起伏产生相应的倾斜,效果到了这一部已经很好了。

最后的一个问题就是粒子脚步和移动速度不协调的问题了,这个问题必须通过解决两个问题来完成:

1.控制角色脚步循环的速度:

要控制角色脚步循环的速度,就只有减小每一帧粒子图片序列循环时增加的值,也就是修改粒子贴图循环RunTime表达式中的img841中的最后的那个常数1,减小它,粒子贴图序列循环的速度就会减慢。

所以我们把它改成0.5,也就是说每两帧进入下一张图片,也就是将循环的速度放慢了一倍。

通过上面的方法,解决了脚步过快的问题。

2.控制粒子移动的速度:

由于粒子的速度是由粒子的生命周期决定的,所以我们只要控制粒子的生命周期(lifespanPP)就控制了粒子移动的速度。

所以我们通过调整粒子的生命周期(lifespanPP)来进一步匹配角色的脚步循环。

调整粒子的生命周期(lifespanPP):

img842

最后:由于我们的粒子是有大有小的,所以角色也有大有小,那么大的角色速度应该快一点,小的角色就会慢一点。

如何解决这个问题,就是制作进一步细节必须考虑解决的了。

很简单只要将粒子的大小(spriteScaleYPP)和粒子的生命周期(lifespanPP)相关联,就可以匹配粒子中角色脚步和移动速度了,于是得到这个表达式:

img843

//后面的常数8是为了匹配角色脚步的循环,通过不断调试最终得到的,读者可以自己指定不同的数值。

当然了,要想使这个表达式产生效果就必须将粒子的生命周期改为:LIfespanPP:

img844

至此,所有的细节都制作完成了。

img845

最后要提醒读者,有两个重要注意事项:

1.对Sprite(精灵)粒子进行渲染前,必须事先制作粒子缓存,否则渲染出来的粒子会有意想不到的效果:

img846

2.如果希望粒子不受灯光的影响,可以取消灯光影响:

img847

使用灯光意味粒子被灯光照亮,取消则不接受灯光,每个粒子显示其全部颜色,不受阴影,灯光的影响。

img848

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈