I、创建一个Sprite图像
用一个简单的点发射器和软件渲染粒子云,创建一系列用作sprite纹理的图像,粒子产生和消失的动画——结合软件渲染粒子云的动画和体积纹理——能够制作出变化多端的动画纹理。
1、设置Timeline Range:从1到60
2、创建一个点发射器
3、第30帧,rate关键帧为100
4、第31帧,rate关键帧为0
5、设置粒子lifespan为lifespanRandom
6、设置lifespanRandom为0.3
7、设置lifespan为1
回放动画,注意:第60帧粒子的生成和消失。
1、设置conserve为0.9
2、增加一个紊乱场
3、设置magnitude为25
4、设置attenuation为0
5、设置frequency为2
6、第1帧,关键帧TranslateY为0
7、第60关键帧,关键帧TranslateY为5
回放动画,注意:粒子现在更随机自由地运动并夹在一起。这些团块在软件渲染里有更大的密度,给最终的精灵影像添加了更多的变换。
1、创建一个粒子云shader
2、设置颜色为100%的白色
3、创建一个Volume Noise 3D Texture
4、将3D Texture Placement做为动画紊乱场的父物体
5、将Volume Noise连接到粒子云材质的Blob Map属性
6、打开Volume Noise纹理属性编辑器
7、设置Threshold为0
8、设置Amplitude为1
9、设置Ratio为0.4
10、设置Frequency Ratio为0.2
11、设置Depth Max为5
12、设置Scale为3.0,3.0,3.0
13、设置Noise Type 为Wispy
不同的气体要求不同的图像,从壶里发出的蒸汽更细弱一点,但从烟囱里出来的烟雾更浓密更“圆”一点。云层是浓密的,但却有一个纤细的边,你就要为你的图像复制这样的边。一旦增加了不同的扭曲和缩放值到你的sprite粒子,而且还有成打的粒子彼此重叠,那它们都将混合并创建理想的外观。
1、打开粒子物体属性编辑器
2、设置粒子渲染类型为cloud
3、点击的Add Attibutes 后的Current Render Type
4、打开Better Illumination
5、为OpacityPP创建一个ramp
6、ramp底部和顶部设置为黑色,中间为白色
7、设置Interpolation为Smooth
8、增加一个预粒子radiusPP属性
9、创建表达式类型里:
radiusPP=rand(0.3,1.3)
从顶部摄影机观看场景,设置视口大小,确保这样粒子到了窗口的边却不会跑出边外。
1、 打开全局渲染窗口
2、 设置理想的文件名
cg/image/的粒子系统在为sprite图像命名方面是非常特别的,cg/image/倾向于用Name.#这样的命名格式,例如:cloudTex.1, cloudTex.20等等。
1、 设置Frame/Animation Ext为name.#
2、 设置Frame Range为1-60
3、 设置camera为Top
4、 打开RGB和Alpha通道
一个Sprite图像应该始终是正方形的,比如1:1的比例。即使图像分辨率非常高,但其大小也不应该超过512Χ512。因为图像在硬件里渲染,所以需要图形卡里的纹理储存器。每个sprite图像被载入纹理储存器,所以,如果你有100个不同的图像,它们都是512Χ512分辨率,那多数图形卡将没有足够的内存有效地回放场景,并会“卡壳”。在帧里一个sprite应该是多大,这才是获得分辨率的真正决定性因素。考虑到一旦你运用了运动模糊sprite,任何像素都趋向于完全消失,你可以用更低分辨率的图像操作。
设置分辨率为128*128
附加tweaks到渲染图像序列,比如添加模糊,调整对比度,用一个合成包修改alpha通道。
最后,渲染图像序列。
II、粒子发射
重新设置frame range为1-100
当一辆汽车踢起灰尘的时候,从轮胎下半部分会发出像一团云样的东西。刻化这个发射形状的简单方法就是用一个体积发射器。
打开wheelsOnPath.ma文件.
在这个场景里,沿着凹凸表面的一条运动路径有一个简单的汽车装备。车轮通过一个closestPiontOnSurface约束粘附在地面。
现在从轮胎发射粒子。
1、创建一个发射器
2、设置Emitter Type为Volume
3、设置Volume shape为sphere
尘埃没有特定的运动方向,其运动源自汽车周围的空气运动,因此,你不用在体积形状基础上给与尘埃任何速度。
1、设置Away From Center为0
2、设置Away From Axis为0
3、设置Along Axis为0
4、设置Around Axis为0
但是,尘埃的运动基于汽车运动的基础上,所以,汽车踢起的尘埃要稍微随着汽车的向前运动而向前运动。
1、打开outliner
2、选择Fitire和你刚才创建的发射器:Emitter1
3、点约束和方向约束发射器到轮胎
4、缩放发射器,大概有轮胎的1/3高,长于和宽于轮胎大约1/4。
5、调整发射器的VolumeOffsetZ属性,重新定位发射器,低于轮胎1/3。
回放时,你会看见左前轮胎后面有粒子轨迹。
1、复制Emitter1三次
2、删除复制品潜在的点约束和方向约束节点
3、点约束、方向约束每个发射器到每个轮胎,这样,每个轮胎都有了一个发射器。
4、重新命名这些发射器为:IEmitter,frEmitter,blEmitter,brEmitter
5、用动力学关系编辑器,连接粒子物体到每个发射器。
回放,你会看见所有轮胎左后方都留下了一道粒子轨迹。
当一辆汽车奔跑在一条满是灰尘的溪谷时,它会碰到各种各样的凹凸地,水沟,岩石和沙地,每次碰撞的结果就是:汽车不仅改变一点点方向,而且汽车踢起的尘土和碎片数量都会不同,利用noise和rand功能,你可以很容易地模拟这种随意的变化。
1、选择flEmitter
2、在通道盒里,右键点击任何属性并选择Expressions……
3、在Expression Editor中键入:
float $rate=100.0
float $rateRand=0.5
flEmitter.rate=$rate+$rateRand*$rate*noise(frame)
这个表达式运用了noise功能,可以依据不同的帧在-1到1之间取一个值。这个值将与rate的百分数相乘再相加。
FlEmitter发射器的rate的最终结果是围绕着$rate大概成平均状,但是,这个参数可以低到0.5,也可以高到1.5,主要看noise值的回馈。
不是随便用一个数字发生器就可以得到声音功能的值,将声音功能视为一个预定的曲线,可以无限延伸,这个曲线在它的值里有各种各样的声音,但声音平滑插入,声音功能回到什么样的值依赖于你在曲线哪里取样。如果你给声音功能取10的值:
print(noise(10));
…cg/image/回到-0.465903的值
如果你给声音功能取10.01的值:
print(noise(10.01));
…cg/image/回到-0.474992的值
参数表达式里:
flEmitter.rate=$rate+$rateRand*$rate*noise(frame)
…我们用“帧”作为声音输入,所以,每个帧的声音功能回到一个新的值。
既然帧以每帧的整数增加,来自声音功能的结果可能变化很大。如果你想从声音功能那里获得一个更加平滑的数字流,那就用“time”来代替 “frame”。
一样的输入值,声音功能返回的值也一样,所以,每个发射器需要用不同的输入值。
在表达式编辑器里,增加:
frEmitter.rate=$rate+$rateRand*$rate*noise(frame+100)
blEmitter.rate=$rate+$rateRand*$rate*noise(frame+200)
brEmitter.rate=$rate+$rateRand*$rate*noise(frame+300)
现在每个rates参数都是从声音曲线不同部分取样,回放时候,你会看见粒子的轨迹有点更加随意稀少了。
参数rates任何明显的提高都表示模拟轮胎碰到了凹凸块或者是岩石。发生碰撞的时候,粒子方向突然随意改变,就好像刚刚发生了一场小的爆炸。
因为声音功能对同样的输入总是返回到同样的值,所以,我们检查rates参数的一个突然变化并添加一些随意性到发射速度上。
在表达式编辑器里,添加:
float $flChange=noise(frame)-noise(frame-1);
float $flChange=noise(frame)-noise(frame-1);
float $frChange=noise(frame+100)-noise(frame+100-1);
float $blChange=noise(frame+200)-noise(frame+200-1);
float $flChange=noise(frame+300)-noise(frame+300-1);
float $randomSpeed=100;
flEmitter.randomDirection=$randomSpeed*linstep(0.1,0.5, $flChange);
frEmitter.randomDirection=$randomSpeed*linstep(0.1,0.5, $frChange);
blEmitter.randomDirection=$randomSpeed*linstep(0.1,0.5, $blChange);
brEmitter.randomDirection=$randomSpeed*linstep(0.1,0.5, $brChange)
回放时,你会看在尘土轨迹甚至有更大的随意性,一些粒子飘浮空中,其他一些粒子保持静止状态。
III、创建一个特效装备
在完成一个作品时,越多的给予使用者超越解算的控制越好,基于这种考虑,越复杂的参数设置会使使用者工作起来越困难。
你想要做的最后一件事就是:提供终端使用者一个复杂的表达式,这需要调试每个镜头。创建一个控制装备,用它驱动一个表达式的结果,你就可能给终端使用者一套控制表示式(表示式控制场景)的工具,这样,他们就不用自己编辑表达式就可以控制场景。
1、选择发射器和粒子物体,把它们编成组。
2、重新命名结果组节点为dustcontrols
3、选择组节点,并打开Add Attribute窗口
4、添加下面的属性,维持Float,Scalar属性:
rate
rateRand
randSpeed
发射的表达式:
float $rate=100;
float $rateRand=0.5
float $radomSpeed=10;
替换成
float $rate=dustControls.rate;
float $rateRand=dustControls.rateRand
float $radomSpeed=dustControls.randSpeed;
现在你可以从表达式外控制这些变量。
控制节点的通道盒应该仅仅显示相关的属性,那些对解算没有影响的属性应该被挪开。变形属性,旋转属性和缩放属性不需要用来控制解算,所以,可以用channel Control窗口将它们关掉。将它们从通道盒挪开之前,先锁定它们,这样,使用者就不会偶尔变形,旋转或缩放该组。
IV.创建尘土粒子运动
1、重新命名particle1为dustParticles
2、设置Particle Render Type为Sprites
3、设置Inherit Factor为0.2
4、点击play
粒子紧随车后,注意粒子能随在车后多长距离,那些以随意爆发速度发射的粒子是怎样漂浮远去的。粒子保存属性设置为1,意味着每帧保持100%运动。既然粒子继承了发射器20%的运动,粒子就收到初始的爆发速度。粒子绝不会丢失速度,会继续沿着那个方向运动。
1、选择dustParticles
2、设置conserve为0.9
现在回放场景,你会看见粒子最初随着汽车运动,但是它们会很快就丢失向前运动的动力并开始落后,最后停止运动。
降低conserve,你可以用场来更好地控制粒子的运动。
1、创建一个紊乱场并指派到尘土粒子
2、设置Magnitude为100
3、设置Attenuation为0
4、设置Frequency为3
5、点击play
粒子在紊乱场内继续运动并在随意方向扩展范围。紊乱场是3D Noise,就像一个三维程序上的纹理。将声音视为一个大理石质地的纹理,如果你动画纹理布置,你就会在空间运动三维声音。
选择dustControls节点,添加一个turbulenceRise属性,设置其值为0.1。
打开你一直在用于发射的表达式,在它的最后添加一行:
//Turbulence Rise
//
TurbulenceField1.ty=dustControls.turbulenceRise*frame;
当你回放场景时候,你看见尘土粒子沿Y轴向上运动,这是因为紊乱纹理随着场的变换而向上运动,粒子继续被这些纹理吸引。
依靠你正试图创建的尘土类型,不管它是一种细而轻的像粉笔一样的东西,还是更重的像被汽车踢起的泥土,在Y轴运动的紊乱场参数都会给你的粒子重力感觉:
不像气态物质,比如烟雾或者蒸汽(固体或液体变化成一种气体并升上天),尘土会保持固体状,但它是一种非常轻的固体,可以踢到空气中,并逗留在最轻的空气流上,最后落地。尘土越厚,就越重,落地越快。要获得尘土落地运动状态,做到以下两点:
1、创建一个重力场并指定给dustParticles
2、设置重力场magnitude为2
回放时候,即使紊乱场继续将粒子向上拉,粒子看起来还是更重。对于这种效果,重力场的大小与场景大小不相关。对重力场的magnitude调整,应该建立在你追求的外观基础上。
粒子现在穿透了地面,如果是一个非常细小的尘土,粒子落到地面就ok了,但是对于一个更厚重的尘土,你希望地上尘土堆积得厚重一点。
1、选择地面平面、粒子,并碰撞。
2、设置Tessenllation Factor为2000
3、设置Resilience为0.1
4、设置Friction为0.3
粒子堆积在地上,它们就像是被重力拉下来的,接着又被紊乱场拉上天。赋予紊乱,粒子就像是液体在运动。
V.创建尘土粒子外观
几个属性一起作用,以创建一个粒子模拟外观。
粒子的生命周期
粒子在模拟中,什么时候消失怎样消失,这在创建模拟形状和任何场一样重要。如果所有粒子以同样的速度消失,模拟就会看起来非常线性,非常假。体积效果就像烟雾和尘土用到sprite时,粒子的消失应该是不容易注意到的,它会在不同时间消失,而不管粒子什么时候从哪里发射出来。
为了简化,我们将要用lifespanRandom模式开始:
1、设置lifespan Mode为Lifespan Random
2、设置Lifespan Random为1.5
3、设置Lifespan为2
回放时,粒子会以随意方式消失。
Sprites-Assigning a Sprite Image Sequence
打开属性编辑器,改变粒子渲染类型属性为sprite。
1、点击Add Attributes for Current Render Type按钮
2、设置spriteScaleXPP为25
3、设置spriteScaleYPP为25
4、打开Multillster或超图窗口
5、创建一个Lambert材质
6、添加一个纹理文件到Lambert材质的色彩属性
7、将文件纹理的图像名字贴图到第一部分里你渲染过的sprite序列
8、打开Use Cache
9、打开Use Frame Extension
10、第1帧,为frame extension设置一个值为1的关键帧
11、第60帧,为frame extension设置一个值为60的关键帧(也可以是序列中的最后一幅图像#)
12、打开Use Hardware Texture Cycling
13、设置Start Cycle Extension为1
14、设置End Cycle Extension为60
15、指派Lambert材质到粒子
16、打开纹理显示模式(热帧:6)
回放时,sprite是看不见的,当用硬件纹理循环时,你需要给spritNumPP指派一个数字,数字大小在纹理循环范围内。
打开用于粒子的属性编辑器。
1、在Add Dynamic Attributes栏下点击General按钮
2、出现Add Attubute窗口,点击Particle栏
3、选择spriteNumPP
4、点击ok
5、在Attribute Editor里,右键点击挨着spritNumPP属性的文字域,并选择Create Ramp.
6、在arrayMapper1/outValuePP域,点击鼠标右键并选择Edit Array Mapper.
7、设置Min Value为1
8、设置Max Value为60
9、Ramp节点负方向,设置ramp底端值为black,顶端为white。
当你回放动画时,你会发现:直到sprites在汽车正后面的时候才显出来。为了修改这种现象,调整底端颜色入口的密度,增加它的值,直到你希望sprites出现的时候,。你也可以调整插入或者添加其他的颜色entry到ramp,以此控制粒子循环如何通过sprites images。
注意:如果sprites图像边上有一个黑色轮廓,sprites图像看起来就会像是燃烧的汽油或者是浓浓的烟雾。调整正在使用的文件纹理的Alpha Offset,设置它的值,小于0,-0.1,这样更好。另外,可以增加colorOffset,或者,也可以调整sprites的整个alpha,利用color gain或者合成包。
Sprites-调整sprite Scale和Twist
效果开始合成一起,但是还有改进的余地。当创建一个sprite基础上的效果的时候,sprites顶部每个分层都赋予它最终效果。利用不同的缩放值和扭曲值并在此基础上动画,可添加角色到模拟。
为粒子物体添加以下的动力学属性,方法和你添加spritNumPP属性一样:
spriteScaleXPP
spriteScaleYPP
spriteTwistPP
在Add Attibute窗口New栏目里,保留Float,Per Particle属性添加以下属性:
randXPP
randYPP
randTwistPP
spriteTwistMultPP
spriteScaleMultPP
给spriteTwistMultPP和spriteScaleMultPP贴上凹凸贴图,重新命名这些贴图,名字要能正确反映他们要连接的属性,可以命名为spriteTwistramp,spriteScaleRamp等等。反过来,于spriteTwistMultPP有联系的rump贴图,底端设为black,顶端设为white。
打开粒子物体需要的creation Expression并键入:
//generate random numbers for X and X
//
float $randx=rand(0.3,1.3)
float $randy=rand(0.8,1.2)
//store a random number for X and Y
//
//
randXPP=$randx
randYPP=$randY
//set spriteScaleXPP and SpriteYPP
//
spriteScaleXPP=0
spriteScaleYPP=0
//set randTwistPP
//
randTwistPP=rand(-180,180)
每个粒子X,Y,Twist的数值都是任意指派的,这些值会赋予每个粒子独特的特征,并会被用在Runtime Expression里。既然我们用rand功能生成值并且边缘功能返回结果总是不一样,那么,我们就在单粒子属性里保存这些值,以便以后使用。
用rump给spriteTwistMultPP和spriteScaleMultPP贴图,也可将它们作为增效器,并给我们一个插值,但是,能否给我们一个interpolation,那就要看粒子的年龄如何。可以用常规表达式控制扭曲和放缩值,但是在控制基于时间的属性改变上,增加一个由rump控制的乘数,会给我们更大的控制灵活性。
为什么用0值初始化spriteScaleYPP和spriteScaleYPP?因为cg/image/的一个bug,rump在Creation上没有正确估算,产生了不可预料的结果。
打开粒子物体需要的Runtime Expression并键入:
//set spriteScaleXPP and spriteScaleYPP
//
spriteScaleXPP =spriteScalex* spriteScaleMultPP*randXPP;
spriteScaleYPP=spriteXcaleY*spriteScaleMultPP*randYPP*randXPP
为sprite渲染类型创建默认属性时,cg/image/添加了一个spriteScaleX, spriteScaleY和spriteTwist属性。如果没有这些属性的单粒子版本,比如spriteScaleXPP,cg/image/就会用scalar属性代替,例如spriteScale。既然有了这些属性的单粒子版本,缩放版本就被忽略了。我不忽略它们,在全局增效器中,我习惯用他们作为表达式的一部分。用一个你众所周知的属性名字,这个名字不仅用在保存创建一个新属性阶段(作为增效器),也展示给使用者一个属性——具有相似的方式相似的功能。在通道盒里改变spriteScaleX或spriteScaleY,这会改变粒子总值。
在下面一行中:
spriteScaleXPP= spriteScaleY* spriteScaleMultPP*randYPP*randXPP;
spriteScaleYPP和 spriteScaleXPP的值大体相当,回到creation expression, randYPP,随意初始化一个值——0.8至1.2之间,这会导致sprite在x轴成矩形的——+/-20%。
添加下面几行到runtime Expression:
//spriteTwistPP
//
spriteTwistPP+= spriteTwistMultPP*sign(spriteTwistPP)* spriteTwist;
如果值是正的,用sign功能返回1;如果值是负的,用sign功能返回-1。spriteTwist属性是用用默认Sprite属性创建的,在这种情况下,我们添加它的值到当前sprite的twist上,引起sprite每帧旋转。利用spriteTwistMultPP,你可以改变每个sprite twist的速率,sprite越大,自转越慢。
此时,你可以开始回放场景,交互式地调整被当作spriteTwist, spriteScaleX和spriteSclaeY属性创建的rmaps值。该阶段有很大的扭曲空间,要得到sprites正确的缩放和扭曲值需要花点时间,但是,利用ramp贴图,就可以创建一些非常有趣的效果。
打开尘土粒子属性编辑器,在Add Dynamic Attribute栏点击Opacity按钮。
1、为透明度创建Per Object和Per Particle属性
2、点击color按钮,为色彩添加Per Particle 属性
3、点击General按钮,作为Float,Per Particle添加属性:
intensityPP
opacityOrgPP
opacityMultPP
4、用ramp贴图为opacityMulPP贴图,正确重新命名。
5、在creation 表达式中键入
//opacityPP
//
opacityOrgPP=rand(0.1,0.4)
opacityPP=0
用相对较低的值初始化透明度,该值保存在opacityOrgPP里,Runtime表达式要用到它。
既然spriteScaleXPP和spriteScaleYPP属性已经设置0,当sprite缩放到0并无法看见时,就没有必要初始化opacityPP一个值。
选择使用rgbPP
添加下面的到creation表示式:
//rgbPP
//
float $intensity=rand(0.6,1.0);
intensityPP=$intensity
对于rgbPP,我们将用一个HSV模式确定尘土的颜色,不用传统的红绿蓝模型。每个粒子有各自的值或亮度,粒子在一个简单的阴影技术基础上获得颜色,粒子是否改变颜色要看是否被阴影,并将保留一个完整的密度值。该信息被合成器用来单独扭曲粒子(从粒子密度)阴影。
添加下面东西到runtime表达式:
//opacityPP
//
opacityPP= opacityMultPP* opacityOrgPP* opacity;
利用通道盒里的透明度属性,使用者现在可以全部调整所有粒子物体的透明度,同时保持每个粒子的独特的opacityOrgPP。并修改粒子生命周期的透明度(使用连接到opacityMultPP的ramp)。
体积阴影
体积阴影是获得真实云和尘土效果的关键因素。体积阴影是通过粒子投射阴影到每个粒子身上而获得的(通过透明度)。不幸的是,这种技术只有在软件云粒子渲染中可以有效,而且耗时之多,令人难以置信。有成打的技术可以模仿这类效果,而且只花很少的时间。
你要用到的技术是我的一个同事Eyal Erez教我的,他和我一起合作制作The Kolektiv。将现在粒子所在位置和粒子“出生”的位置birthWorldPosition相比较,看现在粒子增加了多少高度,你就可以计算出一个值,粒子越低,值就越低。该技术对粒子系统来说很不错,从相对等高的高度发射的粒子不会升或者降太多(和粒子最初位置相比较)。
LEGO投射方面的“领头羊”合成器----Gary Jackamuk需要一个粒子路径,这样就可以调整颜色,以和CG背景元素的阴影及灯光匹配。通常,当软件为合成渲染一个元素时候,你可以输出一个单独的shadow pass,它可以被合成器单独调整。Gray要给粒子上多少色,这要看粒子获得的阴影数量。
我们可以提供一个给粒子上色和阴影的解决办法,使它效果更好。
在Add Dynamic Attributes栏里点击General按钮,到Particle栏。
1、创建birthWorldPosition属性
2、添加下面东西到runtime表达式:
//rgbPP
//
vector $pos=position;
vector $birthPos=birthWorldPosition;
float $hue=(240+120*smoothstep(-1,1, $pos.Y-$birthPos.y))/360;
rgbPP=hsr_to_rgb(<<$hue,1.0,intensityPP>>);
为了控制粒子颜色,我们规格化粒子所在位置和粒子产生位置之间的差数,该规格发生在-1和1之间,这意味着如果一个粒子比它产生的位置低于1个单位,我们就会得到一个0的值;如果高于1个单位,则会得到一个1的值,然后,这些值要被调整为沿着色轮----100%蓝色和100%红色之间,或者240和360之间。参考颜色选择窗口,找到其它颜色的色彩值。
粒子物体的rgbPP属性读取rgb值,而不是hsv值,所以,你需要利用hsv_to_rgb函数将hsv转换成rgb。该功能视一个矢量为输入,那也是为什么我们用<<>>来为色彩、饱和度、密度压缩这些值的原因。色彩值最好为0-1,而不是0-360,所以我们要用360来除hue值。饱和度仍为1.0,但是,你有个机会:通过修改饱和度(在你决定的值的基础上),添加路径附加消息到合成器上,最后,粒子的亮度都被考进hsv的value中。
在这一点上,仍然可以对各种各样的rumps贴图和场做大量的扭曲,以此获得你想要的外观。
打开wheeOnPath_Part6.ma文件,看看我拿出的结果。
VI.硬件渲染粒子
缓存
在硬件渲染前隐藏粒子,如果没有隐藏,运动模糊就不会产生正确的结果,pickup帧就不会和原始帧匹配。
Alpha通道
当sprites透明值少于1时,由Hardware Render Buffer生成的Alpha通道是不正确的。与彩色通道不同,考虑到当前粒子后的粒子颜色,Alpha通道会返回只显示在显示器上的最终粒子的值----这意味着,如果你有1000个粒子堆叠一起,每个粒子透明值为0.1,即使不能在三维视图里看穿粒子堆,cg/image/也将在图像最终Alpha通道里放上一个0.1的值。
用Luminance作为Alpha通道会产生不正确的结果,用粒子的亮度,你会将粒子里的所有阴影挪开。不管较黑区域在哪里,较黑区域都会比较亮区域更加透明。最终的图像看起来是平的,尘土很少纹理。
合成粒子的最好方法就是用非内嵌的Alpha通道渲染它们,背景要是100%绿色。利用简单的合成技术,这种绿屏方法,Alpha通道就会有准确的结果。如果粒子没有任何绿色信息,这种方法会更好,这也是为什么我们限制尘土粒子的色彩范围在绿色和红色之间,而不通过绿色范围。
几何体遮罩
既然大多数粒子效果倾向于带有体积的三维元素,那么,当正确分层你的效果时,一个简单的二维Alpha通道就会不充足了。体积在不同的深度有不同的密度,你需要在三维空间裁减体积,这样,元素前的体积才会保持密度。有两种方法:
打开几何体遮罩,cg/image/自动利用场景中的所有几何体作为一个三维挖剪图画,该几何体被用来挖剪粒子,但是,它在色彩和Alpha通道里是看不见的,就像在软件渲染里的useBackground材质。
特殊遮罩元素
运用几何遮罩将带来一个后果,那就是如果你用了粒子替代并且替代物是几何体,那么几何体也会被遮罩,但不会出现在色彩或者Alpha通道里。为了避免这点,你可以指定一个Lambert材质到场景中的所有做为遮罩的几何体,其色彩和incandescence都是100%绿色,也可以是其它颜色,只要以后能对它进行抠像就行。将incandescence提高到100%绿色原因是:消除任何在几何体上的硬件阴影影响。
匹配镶嵌细分Matching Tessenllation
在场景中使用NURBS几何体的时候,这一点很重要:三维视图里的镶嵌细分要和软件渲染的渲染镶嵌细分相匹配。cg/image/的NURBS物体在视口里高精度显示----Hotkey:3----这与用渲染器来渲染镶嵌细分是不一样的。如果你正在渲染一个非常厚的体积,你会看到几何体遮罩比软件渲染物体有很多的小面,这个结果导致在合成时会有令人不快的边缘围绕在物体周围。为了避免发生这样的事情,打开场景里所有NURBS物体的Display Render Tessenllation,现在,当你硬件渲染的时候,镶嵌细分会和软件渲染器相匹配。
运动模糊
模拟渲染粒子时,运动模糊就是必须的。一般说来,粒子都非常小,运动速度非常快,粒子系统的外观不仅仅指颜色、灯光和透明度,还包括运动中粒子的模糊状态。运动模糊不仅仅反映了粒子运动速度,而且反映了粒子体积大小。一股旋风不需要由100,000,000个快速自旋的点粒子组成,几百个带有运动模糊的sprite就可以产生同样的精彩结果。
硬件渲染的运动模糊和软件渲染的运动模糊结果不同,不必考虑匹配它们有多难,实际上,绝不可能100%精确,有50%精确就很幸运了。依靠物体相对于摄影机的移动速度,产生的结果可能是可接受的,也可能是完全没用的。可以用不同的合成技巧和粒子系统的从属路径来取消这些差异。
为了更好地匹配粒子的软件渲染,运动模糊长度的设置要和摄影机的快门角度相匹配,144快门角度会产生144/360或0.4的运动模糊,若用更高值时,可能会获得有趣的效果。记住以下几点很重要:
如果你正用几何体遮罩,运动模糊设置过高或过低都会引起遮罩和软件运动模糊不相匹配。
如果你的摄影机被动画,动作模糊设置高过1,你的效果将在三维空间游动,运动模糊结果将在时间线之前。
如果你有一个锁定的摄影机,且你正在用的一个作为遮罩的几何体没有运动(比如从一个烟囱或蜡烛冒出的烟),你可以抬高运动模糊设置,用完全非真实的大于1的值试验一下,你会获得非常有趣的结果。
纠正运动模糊Artifacts
如果几何遮罩引起严重Artifacts,纠正这些Artifacts的方法是非常有限的:
多数情况下,关闭运动模糊会给你一个元素并更好地适合你的软件渲染元素,当然,代价就是粒子外观会改变。
关闭特殊物体的运动模糊
这种办法就是关闭运动模糊。与软件渲染器不同的是,硬件渲染器在渲染状态下不妨碍运动模糊特征。
要关闭一个物体的运动,你需要这样做:
1、选中物体
2、烘焙所有的动画属性,这样每帧都有了关键帧。
3、关键帧插入类型为stepped
这会确保当物体在关键帧之间取样的时候,cg/image/不会插入到物体的位置上。该技术通常比较好用,而且可以写入一个mel脚本,将所有动画曲线程序自动化。
如果你看见artifacts和摄影机还处于动画状态,你也可以尝试上面提到的摄影技术。
关键帧特殊物体
修改Artifacts的另一技术就是:在合成阶段添加附加的运动模糊到Artifacts,但是,这项技术的难点在于----遮罩那些引起问题的特殊几何体,并只模糊几何体有问题的区域。要做到这一点,用一种绿色Lambert材质渲染粒子的附加路径,就像在几何体遮罩章节描述的一样。合成器现在可以为那个区域提取一个alpha通道,单独模糊图像的那个部位。
|