AS3 BitmapData.perlinNoise()方法的用途

47 篇文章 0 订阅

之前看到了国外有人写了个:闪电效果,真的棒极了;

于是下载了源码看看:

在线效果

源码下载


看源码时,发现,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源码+注释

中文介绍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值