创造火焰,Bit地图Data

创造火焰,BitmapData




http://www.ryan-liu.com/demo/bitmapdata/perlin_fire.html

做这样一个效果不需要很复杂的代码,但涉及的技术点却不少。复制粘贴一段代码很容易,但想做到灵活运用,你一定要将这些技术点熟练于心。

主要技术点一共三个:perlinNoise柏林噪声,displacementMapFilter偏移滤镜和paletteMap调色映射。perlinNoise和paletteMap是BitmapData的方法,displacementMapFilter是一个特殊滤镜。这两个方法和一个滤镜有一个共同点——参数特别多。几个参数多的方法搭配在一起使用,变数就更多了。你可以在这个例子里分别通过调整各个参数看看不同的结果,比直接看Help来的更直观。次要的技术点在我之前的帖子里都提过。你要了解用BitmapData做动画的逻辑,理解通道的概念,并了解简单的调色方法。本例中perlinNoise和DisplacementMapFilter配合生成火焰纹理和动画,paletteMap用于调整火的颜色。

perlinNoise是一个非常有用的方法,它可以模拟自然界的噪声现象。比如物体的纹理,如石纹,木纹,金属纹理。再比如物体的运动,如模拟流体,模拟群体(蚂蚁)的随机运动。最常见的应用就是模拟云和火的纹理。

perlinNoise(baseX:Number, baseY:Number, numOctaves:uint, randomSeed:int, stitch:Boolean, fractalNoise:Boolean, channelOptions:uint = 7, grayScale:Boolean = false, offsets:Array = null)

参数的详细解释请看官方文档。

简单的解释几个。baseX和baseY值越小,生成的噪声就越细碎(生成频率高了嘛),越大则反之。numOctaves可以理解为噪声的“层”数,每多加一个octave,看起来就像是噪声多叠加了一层。最后一个参数offset就用来控制每一层的偏移,offset是一个值为Point的数组。通过增减每个Point的x和y可以控制一个噪声层的位移。本例中我们也移动噪声来模拟气流或风对火焰的影响。其他参数都较容易理解。例子中的柏林噪声生成的是这样一张图。

创造火焰,Bit地图Data
 

这里我生成了红绿两个通道的噪声,分别控制火焰图像在x和y轴的偏移。如何来实现偏移呢,我们用DisplacementMapFilter偏移滤镜。photoshop里也有这个滤镜,你可以顺手去ps里也玩玩。

DisplacementMapFilter(mapBitmap:BitmapData = null, mapPoint创造火焰,Bit地图Dataoint = null, componentX:uint = 0, componentY:uint = 0, scaleX:Number = 0.0, scaleY:Number = 0.0, mode:String = "wrap", color:uint = 0, alpha:Number = 0.0)

官方文档看这里。偏移滤镜的参数更容易理解。mapBitmap是映射图像,本例中就用perlinNoise生成的噪声图。componentX和componentY指定通道来控制x和y轴的偏移,我刚在柏林噪声里生成了红绿通道,那么本例中componentX应该为1(红色通道),componentY应该为2(绿色通道)。scaleX和scaleY控制在x和y轴上偏移量的大小。如何从映射图像的颜色产生偏移量,很难简单的描述清楚,请参看官方文档里的公式。以后有时间我专开一贴说说。

看到这里你应该大致明白了perlinNoise和DisplacementMapFilter能怎样的配合使用。本例中我们给一个色块施加偏移来模拟火焰,你也可以给一张普通图片施加偏移来模拟风吹或者水波效果。用别的映射图使用偏移滤镜,可以模拟哈哈镜和Power Goo的效果。

另外,在每个enterFrame里再用BitmapData.scroll来向上滚动图像,使火焰向上“飘”。到此为止,我们实现了这样的效果。已经有了火焰的形态。接下来我们要让火焰有更真实的颜色。

创造火焰,Bit地图Data
 

给BitmapData调色,我们可以用ColorTransform和ColorMatrixFilter。除这两个之外,最常用的调色方法就只剩下paletteMap。

paletteMap(sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint创造火焰,Bit地图Dataoint, redArray:Array = null, greenArray:Array = null, blueArray:Array = null, alphaArray:Array = null)

帮助文档看这里。paletteMap调色的逻辑很直观,用新的颜色来替换原通道中的颜色。原通道中0-255的颜色值被数组中第0-第255个值一一对应替换。强调一下文档里的要点。此方法支持跨通道效果。也就是说redArray里的值也带有绿色和蓝色通道,并以此来替换原红色通道的颜色。如果你给每个通道都传了一个数组,那么最终的颜色是几个数组值相加的结果。这一点一定要注意,否则计算不当,几个数组相加的值就爆掉了(大于0xFFFFFF)。

本例中我直接画了一段渐变色,然后从上面取得256个值,再替换红色通道,就完成了调色。我前面的过程都只用红色,在最后调色时就十分方便了~

PaletteMap可以从调好的颜色上取值,因此调色比较直观。但分通道操作比较复杂,不是所有情况下都好用。一般都先把原始图像先调为单通道色,再执行颜色置换。


创造火焰,Bit地图Data
 
 

掌握了本例中的技术点,相信你会感觉到你的Flash世界又扩展出一块广阔的空间。到此我也将BitmapData主要的内容基本介绍完毕