1、AE 高级教程运用 AE 表达式建立自定义粒子系统许多常用的合成软件都具有表达式的功能,用来实现一些特殊的效果。Aftereffects 当然也不例外,Aftereffects 提供基于 JavaScript 的优秀表达式工具和函数,使许多平时难以想象的效果的制作有了可能。有人也许会认为使用表达式会因为不熟悉脚本语言和 JavaScript而难以掌握,其实完全没有必要。不得不承认,对于那些完全没有编程基础的合成师而言,使用表达式可能会有一些困难,但是其实难度并不是太大的,而且在你用表达式完成了一个以往无法完成的效果时,成功的满足感会让你对 AE 和它的表达式充满兴趣。下面我们就将通过制作一个复
2、杂而有趣的效果向大家解释 AE 表达式的使用过程和一般思路。静态效果:动态效果: http:/ . extstream_final.mov注:为了不重复那些手册里面有,而且是最基础的语法规则等基本常识,本文不再赘述这些内容。这些问题如有不明白请自己查阅,对于那些没有看过相关的说明也没有任何编程背景的朋友,我建议先看一下再来。首先让我们看看我们将要完成的是个什么样的效果。今天我们将要制作的是一股文字形成的“流”,就是说成千上万内容颜色各异的文字汇合成一股流,并且我们将可以通过一系列的控制杆控制整个“流” 的形状,里面的文字的大小,路径,颜色,以及各项参数的随机程度。其实实用粒子系统可以制作类似的
3、效果,但是,如果你需要你的粒子系统受某个路径的控制,这就比较困难了。例如,如果我们要这个流最终形成一个心形,这种效果 AE 以及大部分合成软件的粒子系统就有些力不从心了。当然,使用 3D 软件,例如 3Dmax 我们也可以完成这样的效果,但是也就意味着我们在把 3D 元素和合成的视频组合的时候可能遇到更加严重的困难。好了,鉴于 AE 的粒子系统甚至插件也难以完成这样的特效,我们决定向表达式求助了。在设计表达式之前,就像所有程序设计的过程一样,我们需要了解我们需要完成什么,如何完成。我决定用这样的方法完成这个效果:首先创建一个“向导”层,他将按照我们给定的 3D 路径运动,然后我们将通过表达式创
4、建一系列文字层,每一层都会自动模仿向导的动作,形成一股流。但是流的概念包括很多混乱因素,即所有文字层都模仿向导,但是每层都模仿的不完全一样,有的出发早,有的晚;有的飞行快,有的慢;有的大,有的小;颜色和文字内容也不一样;等等。之后,为了便于控制所有这些因素,我们还需要用一些控件对他们进行控制。这里补充一句,trapcode 的插件在本教程写好几个月后更新了,已经具备了类似的功能。但是请注意,使用过的就会明白,这两者仍然是有区别的。那么我们到底要计算机怎么做才能实现我们的要求的效果呢?首先要明白,计算机只不过是工具,他们不会直接给出解决的方案,他们最擅长的就是“模仿”。要知道我们需要他模仿什么,
5、只要想,如果让你手动做这个效果,你怎么做?我们通常制作这个效果的方法是这样的:首先创建一个新的文字层,输入内容,设置颜色,设置关键帧动画,让它沿我们给出的路径运动。再然后复制该层,修改内容、颜色、关键帧、出入点等属性,得到一个新的“粒子”,然后再复制,再修改,直到拥有足够的粒子为止。使用这个方法,应该是可以实现这个效果的,而且其实一点难度都没有,不需要什么高级的操作。但是复制调节几十个层也许还只是比较累人,如果要调节几百个层呢?万一调节完了需要改动呢?看问题来了把?这就需要表达式出手了。但是到这里,我们也从中得到了灵感,就是我们将这些调整的工作交给表达式去做,中间给他赋予一些规则,让他按照这些
6、规则完成我们的工作,而我们甚至可以随时修改某些规则,从而改变最终的结果。明白了这些思路,我们得出了以下结论:我们要对文字层的几个属性加入表达式,让计算机再合适的范围内,随机为属性选择数值,而所有层选择的规则又可以受一些统一的控件的控制。下面让我们进入实际的操作。之后为了在这个教程中显示这种做法带来的好处,我们将先建立一个 3D 的灯箱,然后让我们的文字流围绕这个灯箱,呈螺旋形运动。1:制作一个 3D 的灯箱。(因为本教程的重点不是 3D 层的合成,这一段会比较简略。)首先启动 AE,建立一个新的 comp,大小设置为 400*400,命名为 Cubeface。打开这个comp,创建一个 400
7、*400 的 solid 层,颜色设置灰色,修改透明度值为 50%,这层将成为灯箱半透明的玻璃部位。复制该层,设置透明度为 100%,颜色改为白色,为图层添加一个矩形 mask,设置 maskshape 为 substract,mask expansion 为-17, 得到了一个白色的框框,这个将成为灯箱的框。最后导入一个你喜欢的图片,放在最上层。这样灯箱的一面就做好了。我的图片:2:新建一个 comp 命名为 cube,倒入刚才制作的 cubeface,复制为 4 个,转化为 3D 层,设置他们的 position 和 orientation 属性分别为下图,组成一个方盒子(没有底和顶) 。
8、3:新建一个 comp 命名为 main,长度设置为 30 秒,导入刚才制作的 cube, 打开层塌陷开关,复制改层,把盒子堆叠成柱状,并用类似的方法制作一个文字框,组成一个灯箱,添加旋转关键桢,让灯箱的不同部件转动起来。为了让场景更加美观,我们用两个 solid 层制作了地面和背景墙壁,并添加了几盏灯光,让场景更加有质感。最终整个场景的效果如图:忙了这么半天,你可不要以为已经接近成功了,我们还只是为我们的效果搭了一个舞台,真正的好戏才刚要开场呢。首先我们要制作一个“向导” ,这个向导将沿螺旋形轨道,从下往上围绕我们的灯箱旋转,之后我们的所有文字层都将跟随他运动,最终产生一个“文字流”。这里我
9、们要新建一个 20*20 的 solid 层。之所以选择 solid 层而不选择 null 层是因为,我们可以通过它观察场景中的灯光对它的影响得知最终灯光将对文字造成的影响,这样会给我们带来一些小小的便利,而 null 层由于不会被渲染出来,没有这个功能,所以我们不采用。完成以后把这个层转化为 3D 图层,准备给他的 position 属性加入关键桢动画。这个时候,我们发现我们遇到了第一个难题:怎么让一个物体沿一个 3D 螺旋形轨道运动?在一些三维动画软件中,这个效果是非常简单的:制作一个螺旋形曲线,然后以它为路径,让一个物体沿曲线运动。但是 Aftereffects 虽然可以粘贴路径给物体的
10、位移属性,但是没有办法粘贴一个三维路径。怎么办呢?其实这是后最快捷的方法也就是表达式动画。这个表达式怎么写呢?首先我们需要观察一下到底我们需要的路径是什么样的。以下是在 3DMAX 中绘制的一条螺旋线的三视图。 从这张图的顶视图,我们不难发现,其实螺旋线的轨迹,在 x-z 平面上作的是圆周运动和一个向外的匀速运动,着两个运动导致它的轨迹呈现螺旋形。而他的角度变化可以认为是个匀速变化的过程。通过前视图,我们也不难发现,在 y 轴方向,他做的是个匀速(或者变速)直线运动。这里我们把它暂定为一个匀速运动。这样,明白了整个过程以后,我们就可以得到一个大致的思路:给运动定义三个变量,其中 vel1(ve
11、locity1 的简称)即运动在 x-z 平面上单位时间内转过的角度(单位是弧度/秒) ;vel2,即物体在 x-z 平面上那个向外的速率;vel3,即物体在y 方向上的速率;然后利用这三个变量,我们将计算出任何时刻物体的坐标。同时,我们规定起初时候圆周的半径是个常量,命名为 radius。有了这些数值,我们可以得到以下结果:某个时刻(time)物体圆周运动的半径是:radtemp=radius+vel3*time(小学算术,不难理解把?)这个时刻,他和初始位置的夹角是:angertemp=vel2*time这个时刻在顶视图他的位置可以用下图形容: 其中的 a 角就是 angertemp那么他
12、的 x-z 坐标通过最基本的三角函数不难获得,应该是:x=-cosa* radtempz=sina* radtemp而此时物体的 y 轴坐标更简单,应该是:y= -vel3*time,注意, ae 中坐标轴的方向和我们平时用的不太一样, y 轴正方向是向下的。通过以上步骤的计算,我们就得到了物体的坐标,把这些改写成表达式如下:vel1=20; /旋转速度vel2=40; /向外速度vel3=50; /y 方向速度radius=30; /定义初始的半径值radtemp=radius+vel2*time; /定义任意时刻半径的算法angertemp=vel1*time; /定义任意是刻角度的算法a
13、= -Math.cos(vel1*time)* radtemp; /定义物体 x 坐标的算法b= -vel3*time; /定义物体 y 坐标的算法 c=Math.sin(vel1*time)* radtemp; /定义物体的 z 坐标的算法a,b,c /最终输出物体坐标选择 guide 层,打开 position 属性,通过菜单:animation/add expression 给 position 属性加入表达式,并把以上的内容写入。现在看看 guide 层的运动,怎么样看到螺旋形的轨迹了把?但是你大概也发现了一个问题:怎么运动是从屏幕的左上角开始的?不是从中央的地面开始的呢?因为我们刚才
14、的表达式是假定运动的中心点是在坐标(0,0,0)而设置的。实际上,(0,0,0)这个点的位置正是屏幕左上角。这个问题怎么解决呢?下面新建一个 null 层,命名为 center 并将之转换为 3D 层,把它放到灯箱的下方中央。然后打开 guide 层的 position 属性的表达式,把最后一行改为:a,b,c+ thisComp.layer(“center“).position 即把这各点的坐标和 center 的相加,获得了当 center 层为螺旋线底部中央点的时候物体的坐标。好了,现在试着调整 center 层的位置,看到 guide 层轨迹随之改变了没有?开始感觉到 AE 表达式的强
15、大了吧? 这时候,我要说一些题外话。上面的表达式中“/”后面的是注解,实际对 AE 的运行没有作用,对于最终的结果也没有直接作用,因此可以不写。另外,这个表达式分 10 行表达函数值,其实可以用一行写完。即:-Math.cos(20*time)* (30+40*time ), -50*time, Math.sin(20*time)* (30+40*time ) 。这个表达式其实就是把上面的诸多变量、数值代入得到的。看起来似乎要比我之前写的简单很多。但是,实际工作中,我不推荐这样的写法。因为,这样写出来的表达式有几个缺点:1 由于单个表达式比上面的复杂很多,容易写错,只要漏了哪怕 1 个 “(”
16、,最终也会导致AE 报错罢工的。2 没有注解,也就意味着别人将很难理解你写的表达式,在团队合作中这是很不好的习惯。更糟糕的是,时间稍微一长,很可能连你自己都会忘记它的含义,这样在修改和调试的过程中就容易造成一些错误。3 把所有不变的数值,直接代入,在调整数值的过程中容易搞混,毕竟要记住几个不断变化的数值到底哪个代表什么,最好的方法就是写下来。题外话说完,现在回到主题。我们已经写好了表达式,预览一下动画效果,看到你的 guide层螺旋上升了吧?看看他的速度是否符合要求,如果不符合,比如上升太快或者太慢可以修改相应的变量数值,直到最终对所做的效果满意。最终让 guide 层在 10 秒左右飞出屏幕
17、。这时候,可以把表达式转换为关键帧,因为之后我们并不需要不断调整 guide 的路径。点击 guide 的 position 属性,选择菜单 animation/keyframe assistant/convert expression to keyframes。把表达式值转换为关键桢。 (为了让这个路径更加简单,也可以使用 smooth 工具对其进行简化。 )这时候表达式已经没用了,把它删除吧。同时打开 position 属性,删除10 秒后的所有关键帧。现在我们可以看到,guide 层再 0 秒时候从底部出发,沿一个螺旋轨道上升,最终在 10 秒左右出画。我们可以让他在 1 秒后不断重复这样的运动,因此我们现在再次给 position 属性加入表达式:loopOut(type = “cycle“, numKeyframes = 0),这段表达式可以让该层 10 秒后回到第一帧的位置,重新开始运动,并且不断循环。到了这里,我们终于完成了向导层的设置,其实主要的部分才刚刚要开始。但是只不过这简简单单的几下,已经让我们领略到了表达式的强大与便利。相信应该能让许多本来对数字头痛的朋友对表达式有点兴趣了吧?