当前位置: 主页 > 平面设计 > Maya用particle的instancer模拟爆破墙效果

Maya用particle的instancer模拟爆破墙效果

  • 2022-03-02
  • 来源/作者: PS.ONEGREEN.ORG    / 佚名    
  • 3 次浏览

  初始化位置

  首先打开2_1_instance_brickwall_base.mb文件,在这个文件里可以由一组砖组成的一面墙。这面墙是由一些砖块组成,稍后我们将用一些破砖代替它们,来让我们看看这个场景是怎么样设置的.

  Maya用particle的instancer模拟爆破墙效果

  设置如图。

  Maya用particle的instancer模拟爆破墙效果

  1、所有的砖都需要freeze transform。

  2、我们需要建粒子去发射它。可以运行这个命

令://create particle node particle -n wall_front_PTL;

  3、创建一个属性,当开始播放场景的时候我们将用这个属性旋转砖块。打开粒子的属性栏,增加一个per-particle的属性,名称为rotationPP。

  4、粒子将从每一块砖的位置发射。我们首先从所有的节点中捕获一个列表,然后循环每一个节点,用emit命令从每个节点的位置发射粒子。老外用了这样一段脚本来完成这个操作。

  emit_brick_particles.mel:// 获取前墙砖的名称列表string $nodeList[] = `ls -dag -type transform "o_frontWall_LOC|*PLY" "i_frontWall_LOC|*PLY" "side_frontWall_LOC|*PLY"`;

  // 用循环语句让每一块砖发射一个粒子for( $node in $nodeList ) { // 得到每一块砖的位置 float $p

os[] = `xform -q -ws -t $node`; // 确定每一块砖的大致体积 // 当我们破碎砖块的时候就会用到:    float $bb[] = `xform -q -ws -bb $node`;
    float $x = abs( $bb[3] - $bb[0] );
    float $y = abs( $bb[4] - $bb[1] );
    float $z = abs( $bb[5] - $bb[2] );
    vector $v = <<$x, $y, $z>>;
    // 得到砖的长度float $vol = mag( $v ); 
    //发射一个粒子 emit -o wall_front_PTL
    -pos $pos[0] $pos[1] $pos[2]
    -at mass -fv $vol;
    } // for $node in $nodeList
    // 将
此时的粒子保存为初始状态
    saveInitialState wall_front_PTL;

[NextPage]

  Maya用particle的instancer模拟爆破墙效果

  5.记录粒子产生的次序。因为砖和粒子之间没有真正的关联,我们不得不依靠maya的物体列表清单。按字母顺序获取$nodelist变量里的列表,这是非常重要的一点,这将帮助我们正确的对砖块进行instance。

  6.我们现在为每个粒子建立instance.我们将像前面发射粒子一样定义这个列表。

   //选择砖块
    select -r `ls -dag -type transform "o_frontWall_LOC|*
PLY" "i_frontWall_LOC|*PLY"
    "side_frontWall_LOC|*PLY"`;

   7.选择菜单particles>instancer(Replacement)>optionBox.在instanced objects列表里,你将会看到你所选择的按字母顺序排列的所有砖块。单击create 按钮,你会看到instance物体已经出现了。

  你会注意到有些砖的位置不正确。当你使用默认值创建instance时,instance会使用列表中的第一个物体。我们将指定instance使每个粒子使用它相同位置的砖。因为在前面我们已经正确的设置了我们的粒子和instance,所以现在就可以简单的将粒子的ID作为砖的列表索引。

  8.选择粒子wall_front_PTL打开属性编辑器找到instancer一栏。

  9.打开objectindex下拉菜单,设置为particleID,我们将看到砖块已经恢复到了正确的位置。

>

  10.先添加一个per-particle属性,名称为rotationPP,打开rotation下拉菜单,设置为rotationPP。

  当这些砖移动的时候,我们将用这个属性使砖产生翻滚的效果。

  Maya用particle的instancer模拟爆破墙效果

[NextPage]

  开始模拟

  有趣的事马上就要发生了,我们会从内部炸毁这面墙。我们遇到的第一个问题是重力,怎样使砖块受到重力影响呢,在它们被推出去之前不让它们发生移动。有许多方法:

  味  1)在粒子的runtime expression里创建一个重力,当粒子的速度不为零的时候它将受到重力影响,如果粒子已经接触到了地面,将它所受的重力设置为0。

   //获取位置
    vector $pos=position;
    //如果粒子已经移动,并且没有掉到地面上,受重力影响。
    if(mag(velocity)>0&&$pos.y>0.01)
    velocity+=<<0,-32.17,0>>;

   2)创建一个真正的重力场,将它的volume shape设置为cube。将它的位置放在墙的前面,当粒子被推出去以后它就会受到重力的影响。

  第二种方法比较实用,如果你的场景物体不是很规则,那可能需要建立很多个重力场,并确保他们互相不交迭。

  Maya用particle的instancer模拟爆破墙效果

  现在我们打开2_2_instance_brickwall_s

im_base.mb,前面砖墙已经设置好了instance,一些场和碰撞物体将在适当的时间将砖墙碰出去。如果现在播放,会看到砖被推了出去掉在了地上。这是因为有许多的场和碰撞物体来模拟这个爆炸动画。可以看到在砖飞出去的时候并没有旋转,现在我们来加这个效果,让砖旋转着飞出去。

  我们将根据一些因素来旋转这些砖:

  a.砖的速度。

  b.砖的质量(大的砖相对重一些,因此它们转的会慢一些)。

  c.上面的砖朝一个方向旋转,下面的砖会朝另一个方向旋转,距离爆炸中心的会旋转的快一些。

[NextPage]

  d.用一个随机数值去乘以旋转值,让它们的速度有些变化。

  现在我们要为粒子增加一些属性。因为我们是使用emit命令来发射的粒子,所以它们的创建表达式将被忽略。我发现可以在运行表达式中创建一个“假的”创建表达式。这个创建表达式将出现在第二帧,是在爆炸前运行。

  我们也可以用epicentre_LOC

这个locator的位置来决定爆炸什么时候发生。

  1.首先,我们给wall_front_PTL的粒子增加几个per-particle的属性。3个per-particle float属性的,名称为rotXPP,rotYPP和rotZPP,1个per-particle float属性的,名称为magVelPP。

  2.接下来,我们创建这个“假的”创建表达式。它将运行在模拟之前,在runtime expression中输入下列表达式:

   //假的创建表达式if(frame==`playbackOptions -q -min`+1){
    //获取位置
    vector $pos = position;
    //获取质量,并且取它的倒数
    float $mass=1/(mass);
    //获取爆炸中心的位置
    float $epicentreF[]=`xform -q -ws -t epicentre_LOC`;
   
vector $epicentre=<<$epicentreF[0],$epicentreF[1],$epicentreF[2]>>;
    //确定粒子和爆炸中心的距离
    float $distToCentre=mag($pos-$epicentre);
    //定义旋转值
    float $rx=deg_to_rad(deg_to_rad(rand(-10)));
    float $ry=deg_to_rad(deg_to_rad(rand(5)));
    float $rz=deg_to_rad(deg_to_rad(rand(2)));
    //根据粒子与爆炸中心的关系修改旋转值
    if($pos.y<$epicentre.y)$rx*=-1;
    if($pos.x<$epicentre.x)$ry*=-1;
    //根据粒子与爆炸中心的距离关系修改旋转速度
    float $distNorm=1-smoothstep(0,10,$distToCentre);
    //最后为粒子指定旋转值
    rotXPP=$rx*$distNorm*$mass;
    rotXPP=$ry*$distNorm*$mass;
    rotXPP=$rz*$distNorm*$mass;
    }//假的创建表达式结束

[NextPage]

   3.现在我们继续给增加运行表达式

   //获取旋转值
    vector $rot=rotationPP;
    //获取速度
    //确保当粒子没有移动的时候不旋转。
    magVelPP=smoothstep(1,30,mag(velocity));
    //加上现有的旋转值
    float $rx=$rot.x+rotXPP*magVelPP;
    floa

 << 上一页  [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]  ... 下一页  >>