四、制作多条蔓藤植物
下面我们要让很多植物在这个“崖壁”上生长出来,也就是要重复很多次前面的工作,当然可以这样一步一步地做,在“崖壁”面片上手动画很多的线,但下面尝试一种新的方法来制作,让粒子在“崖壁”面片Plane _Wall上产生很多条曲线。
(1) 用上一节中相同的方法在Plane. Wal上再画一条曲线,用于发射粒子,这条曲线的位置就是植物生长的最初位置,如图所示。
(2)从曲线发射粒子。选择这条曲线,然后执行主菜单命令Particle> Emit from Object (粒子>从对象发射),建立一个粒子发射器,设置Emitter type (发射器类型)为Curve (曲线), 在新创建的发射器Rate (速率)属性上Key帧,设置60帧时的参数值为50,65帧时的参数值为0,并将发射速度调为0,如图所示。
(3)选择新产生的粒子particlel,然后加选“崖壁”面片Plane_ Wall,执行菜单命令Particle>Goal (粒子>目标),在属性编辑器中设置Goal weight (目标权重)值为1,然后为粒子添加属性(goalU, goalV) 。
(4) 现在我们在Script Editor (脚本编辑器)中输入命令“createNode closestPointOnSurface",这样会产生一个closestPointOnSurface节点,这个节点可以求出粒子到NURBS平面上最近距离点的位置和UV值。重命名这个节点为“cPOS1”,如图所示。
(5)在Outiner (大纲视图)窗口中的Display (展示)菜单下,不勾选DAG Objects Only (仅DAG对象),便可以找到这个节点,如图所示。
(6)打开Connection Editor (连接编辑器)窗口,把plane. WallShape的World Space连接到cPOS1的Input Surface上,如图所示。
(7)在粒子上写表达式,如图所示。
在粒子creation表达式里写下如下命令
vector $pos=particleShape1. position;
setAttr "cPOS1.inPositionX" ($pos.x);
setAttr "cPOS1.inPositionY" ($pos.y);
setAttr "cPOS1.inPositionZ" ($pos.z);
particleShape1.goalU=' getAttr cPOS1.parameterU';
particleShape1.goalV=' getAttr cPOS1,parameterV;
vector $pos=particleShapel. position;
curve -d 1 -p ($pos.x) ($pos.y) ($pos.z) -n ("Ij curve" + particleShapel particed);
在粒子Runtime before dynamics里写如下表达式,如图所示。
float $stepU=0.01*sin(particleShape1.particled);
float SstepV=0.035*cos(articleShape1 particleld)* abs(oise(articleShape.particleld+rame);
particleShape1.goalU+ = $stepU;
particleShape1.goalV + =$stepV;
vector $pos =particleShape1.position;
curve -a -P ($pos.x) ($pos.y) ($pos.z) ("Ii .curve" + particleShape1.particleld);
下面我们来分析一下表达式中每-句话的作用。
在creation表达式里:
vector $pos= particleShape1.position;
setAttr "CPOS1.inPositionX" ($pos.x);
setAttrt“cPOS1.inPositionY" ($pos.y);
setAttr "cPOS1.inPositionZ" ($pos.z);
以上几句,会把粒子的空间位置连接到cPOS1节点上,这样cPOS1这个节点就能计算出粒子到平面plane. WallShape上最近点的UV值,cPOS1 parameterU和cPOS1.parameterV,然后就让粒子的初始(goalU goalV)等于这个值,也就是接下来的两句:
particleShape1.goalU= getAttr cPOS1.parameterU';
particleShape1.goalV= getAttr cPOS1.parameterV;
下面两句的作用是根据粒子的空间位置和粒子的ID号,为每一个粒子-出生就创建一条曲线,并且要根据粒子的ID号为曲线取一个新的名称,这个是必须的,因为在接下来的Runtime before dynamics表达式中,我们要用到这个曲线名称。
vector $pos = particleShapel. position;
curve -d 1 -p ($pos.x) ($pos.y) ($pos.z) -n ("Ij curve"+ particleShape1 particleld);
在Runtime before dynamics表达式里:
float $stepU=0.01 *sin(particleShape1.particleld);
float $stepV=0.035*cos(particleShape1 particleld)*abs(noise(particleShape1. particleld+frame));
particleShape1.goalU+ = $stepU;
particleShape1.goalV+ =sstepV;
以上几句的作用,就是让粒子在平面上运动起来,我们知道(sin ,cos)是一个- 1到1的范围,如果我们的取值足够多,粒子就会呈一个圆形向四周运动,从而使产生的曲线分布均匀。
下面两句的作用是根据粒子的位置和曲线的名称,不断加长曲线的长度,从而实现曲线跟着粒子的运动而生长。
vector $pos = particleShape1.position;
curve -a -p ($pos.x) ($pos.y) ($pos.z) ("IjL curve" + particleShape1,particleld);
(8)播放动画至150帧位置,此时在画面中就会产生很多的曲线,如图所示 。
下面就用这些线曲线来生长植物,然后删除镜头外的曲线,或者删除不喜欢的曲线,节省资源。
Tips :如果读者习惯用粒子创建曲线,只要想像力丰富,可以做出多种特效,这是用Maya粒子做特效的一个基本技能,一定要掌握。
(9)删除粒子,选中所有新生成的曲线,单击菜单命令Edit Curves> Rebuild Curve (编辑曲线>重建曲线)后面的口按钮,在打开的Rebuild Curve Options (重建曲线选项)窗口中设置Number of span (跨度数)值为8,单击Rebuild (重建)按钮优化曲线,然后删除历史,如图所示。
Tips:现在的破法,粒子产生完曲线后已经没有用了,所以要将其删除。读者可以尝试一下,粒子一边产生曲线。同时一边产生植物的做法.
(10)选中所有曲线,执行菜单PaintEffects > Curve Utilites> Attach Brush To Curve (PaintEfects>曲线工具>将笔刷附加到曲线)命令;选择最初产生的那个笔触(在上面第4步中产生的) ,执行菜单Painteffects > Get Setting from Selected Stroke (PaintEffects> 从选定笔画获取设置)命令,选择所有新产生的笔触,再执行菜单Paint Effects > Apply Setting to Selected Stroke (PaintEffects> 将设置应用于选定笔画)命令,这样原先产生的植物的所有属性就一模一样地赋给了我们新产生的植物。
(11)选择所有新产生的笔触,在Max Clip (最大片段)属性上key帧,在第60帧时设置参数值为0.2,在第150帧时设置参数值为1,如果想让动画有一些变化, 也可以分开单独调节,如图所示。
下面我们开始打灯光,准备渲染输出。
(12)新建一盏聚光灯,模拟场景中的太阳光,打开灯光阴影,同时打开笔触的投射阴影。
Tips:测试灯光时,为了加快效率,可以先把大部分植物隐藏,最终渲染时再显示出来;修改多个笔触的属性时,可以用菜单命令Paint Effects>Share One Brush (Paint Effects>共享一个笔刷) 。
(13)渲染输出的效果如图所示。