之前看到了国外有人写了个:闪电效果,真的棒极了;
于是下载了源码看看:
在线效果
源码下载
看源码时,发现,BitmapData中,有一个挺有趣的方法:perlinNoise();
BitmapData.perlineNoise()方法让BitmapData画布可以生成很多杂点;
而且调整参数让杂点之间的颜色间隔过度相对圆滑很多;
这样一来,如果BitmapData画布是N * 1或是 1 * N大小;
因为横向、纵向(宽、高)为1的大小;
所以可以理解该画布的形状,就是一条线,而且这条线的每个点之间的颜色alpha差值都是有一定的规律,
就像给该线填充的渐变填充一样;只不过,渐变的过度设置好多个点;
如图:
上图我是把这条线放大了:800%的效果;
如果把:长度定为x,alpha定为y,那就可以形成一个x,y对应关系图,就像是波浪线一样;(关键是:起伏不定的,而且起伏之间不是垂直,或是直线的起伏)
如图:
像这种不规则起伏波动的一组数值;
在很多情况下都可以使用到;
如:
1)、水面的起伏;
2)、火焰不同火尖的起伏;
3)、闪电的节点之间的起伏;
4)、还有,鱼的游戏动方向、速度、转向速度数值的起伏;
或是一些游戏中,模拟一些怪物原地徘徊的时的移动方向、距离、速度的起伏;
关于PerlinNoise算法详细解说
WIKI解说
PerlinNoise中的波长、振幅简单解说
我自己随手写了个:
测试项目;只是把Lighting类中的一部分逻辑copy出来;
方法大家理解
测试项目下载(带有Lighting.as在里面)
测试代码:
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.geom.Point; /** * [description] * @author Jave.Lin * @date 2013-9-27 **/ [SWF(width="1000", height="600")] public class BmdPerlinNoiseTestingProject extends Sprite { private var sbdBmp:Bitmap; private var sbd:BitmapData; private var bbdBmp:Bitmap; private var bbd:BitmapData; private var seed1:int = Math.random()*100; private var soffs:Array = [new Point(), new Point()]; private var seed2:int = Math.random()*100; private var boffs:Array = [new Point()]; private var steps:int = 100; private var num:int = 1; private var speed:Number = .7; private var wavelength:Number = .3; private var calculatedWavelength:Number; private var calculatedSpeed:Number; public function BmdPerlinNoiseTestingProject() { stage.color = 0x888888; stage.frameRate = 60; stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; sbdBmp = new Bitmap(); sbd = new BitmapData(1000, 1, true, 0); sbdBmp.bitmapData = sbd; addChild(sbdBmp); sbdBmp.height = 80; bbdBmp = new Bitmap(); bbd = new BitmapData(1000, 1, true, 0); bbdBmp.bitmapData = bbd; addChild(bbdBmp); bbdBmp.y = sbdBmp.y + sbdBmp.height + 10; bbdBmp.height = 400; addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(e:Event):void { soffs[0].x += (steps/100)*speed; soffs[0].y += (steps/100)*speed; sbd.perlinNoise( steps/20, steps/20, num, seed1, false, true, 7,// | BitmapDataChannel.BLUE | BitmapDataChannel.GREEN | BitmapDataChannel.RED, true, [soffs]); calculatedWavelength=steps*wavelength; calculatedSpeed=(calculatedWavelength*.1)*speed; boffs[0].x-=calculatedSpeed; boffs[0].y+=calculatedSpeed; bbd.perlinNoise(calculatedWavelength, calculatedWavelength, 1, seed2, false, true, 7, true, boffs); } } }
最后带上另一个例子:
使用了:PerlinNoise方法 + DisplacementMapFilter;制作火焰效果;
代码非常少
火焰效果下载(里面有两个.as,copy到FB调整一个namespace,运行Main.as即可看到效果,当然,图片资源别忘记Copy了)
运行效果图:
扩展阅读:DisplacementMapFilter
该滤镜中,主要是通过该公司生成新的扭曲后的像素信息来再次呈现:
公式:dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256,
y + ((componentY(x, y) - 128) * scaleY) / 256)]
Starling中的主要代码:
if (mComponentX == BitmapDataChannel.RED) columnX = 0; else if (mComponentX == BitmapDataChannel.GREEN) columnX = 1; else if (mComponentX == BitmapDataChannel.BLUE) columnX = 2; else columnX = 3; if (mComponentY == BitmapDataChannel.RED) columnY = 0; else if (mComponentY == BitmapDataChannel.GREEN) columnY = 1; else if (mComponentY == BitmapDataChannel.BLUE) columnY = 2; else columnY = 3; sMatrixData[int(columnX * 4 )] = mScaleX * scale / textureWidth; sMatrixData[int(columnY * 4 + 1)] = mScaleY * scale / textureHeight; sMatrix.copyRawDataFrom(sMatrixData); // vertex buffer: (containing map texture coordinates) // The size of input texture and map texture may be different. We need to calculate // the right values for the texture coordinates at the filter vertices. var mapX:Number = mMapPoint.x / mapTexture.nativeWidth; var mapY:Number = mMapPoint.y / mapTexture.nativeHeight; var maxU:Number = textureWidth / mapTexture.nativeWidth; var maxV:Number = textureHeight / mapTexture.nativeHeight; sMapTexCoords[0] = -mapX; sMapTexCoords[1] = -mapY;//设置当前纹理坐标信息:UV sMapTexCoords[2] = -mapX + maxU; sMapTexCoords[3] = -mapY; sMapTexCoords[4] = -mapX; sMapTexCoords[5] = -mapY + maxV; sMapTexCoords[6] = -mapX + maxU; sMapTexCoords[7] = -mapY + maxV;
参考:Starling中的DisplacementMapFilter源码+注释
中文介绍