在之前的两篇文章中我们介绍了PerlinNoise的两种用途:创建云雾等自然效果以及用作随机数提供源。那么在这一章中,贫道将隆重介绍一位perlinNoise的好基友:DisplacementMapFilter

神马是DisplacementMapFilter

DisplacementMapFilter是一种滤镜,使用它可以让一张BitmapData的像素发生偏移,产生出一种类似于扭曲的效果。山羊书(《Foundation  Actionscript3.0 Image Effect》)中,在第四章Advanced Bitmap Manipulation中的Displace pixels这一节中对此滤镜有着详细的介绍,下面先引用其一张截图:

从上图中我们可以看到,以左边这张图作为滤镜的像素提供源产生一个DisplacementMapFilter后应用于右侧的一张格子图上面,会出现一个圆形的像素偏移区域。那么DisplacementMapFilter这个滤镜的工作原理是怎么样的呢?我们应该如何使用它?

在山羊书中对DisplacementMapFilter滤镜工作原理做了非常详细的剖析,但是你现在在看我的文章,不可能还拿出山羊书来翻一翻先,好吧,下面我简单地翻译并概括一下山羊书中对其的解释。首先我们来看DisplacementMapFilter滤镜的参数设置:

public function DisplacementMapFilter(mapBitmap:BitmapData = null, mapPoint:Point = 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:BitmapData (default = null) — 包含置换映射数据的 BitmapData 对象。

mapPoint:Point (default = null) — 一个值,它包含目标显示对象的左上角相对于映射图像左上角的偏移量。

componentX、Y:uint (default = 0) — 说明在映射图像中使用哪个颜色通道来置换 x ,y 结果。 可能的值为 BitmapDataChannel 常数。

scaleX、Y:Number (default = 0.0) — 用于缩放映射计算的 x , y 置换结果的乘数。

mode:String (default = "wrap") — 滤镜模式。 可能的值为 DisplacementMapFilterMode 常数。

color:uint (default = 0) — 指定对于超出范围的替换应用什么颜色。 置换的有效范围是 0.0 到 1.0。如果 mode 设置为 DisplacementMapFilterMode.COLOR,则使用此参数。

alpha:Number (default = 0.0) — 指定对于超出范围的替换应用什么 Alpha 值。 它被指定为 0.0 到 1.0 之间的标准值。例如,.25 设置透明度值为 25%。 如果 mode 设置为 DisplacementMapFilterMode.COLOR,则使用此参数。

当你传入一个BitmapData对象作为DisplacementMapFilter的第一个参数mapBitmap的话,该BitmapData对象实际上就成了一个像素提供源,DisplacementMapFilter内部会根据一个公式来计算出滤镜应用结果的像素值,该公式可以表示为:

dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256, y + ((componentY(x, y) - 128) *scaleY) / 256)

设dstPixel[x, y]为滤镜应用结果于(x,y)位置处的像素值,该像素值应与像素提供源srcPixle于(x + ((componentX(x, y) - 128) * scaleX) / 256, y + ((componentY(x, y) - 128) *scaleY) / 256)位置的像素值一致。componentX、Y指某一个颜色通道。

下面我们一起来算一次。假设我传入DisplacementMapFilter中的componentX参数为BitmapDataChannel.RED,scaleX值为10, 而像素源mapBitmap于(0,0)位置的红色值恰好为0x80(转换为十进制是128),那么x + ((componentX(x, y) - 128) * scaleX) / 256 = 0 + ((componentX(x, y)  - 128) * 10) / 256 = 0 + ( (128 - 128) * 10  ) / 256 = 0

再假设我同样使用了红色通道作为componenY , scaleY 值为10, 那么后面那个算式y + ((componentY(x, y) - 128) *scaleY) / 256得出的计算结果也一样是0.

这意味着什么呢?这意味着此时滤镜应用结果在(0,0)位置上的颜色是取自像素提供源(0,0)位置上的颜色的。若像素源mapBitmap于(0,0)位置的红色值为0xFF(转换为十进制为255)的话,计算结果将变成(5,5),这意味着此时滤镜应用结果在(0,0)位置上的颜色是取自像素提供源(5,5)位置上的颜色。那若是像素源mapBitmap于(0,0)位置的红色值为0x00(转换为十进制为0)的话,计算结果将变成(-5,-5),这时候怎么办呢?DisplacementMapFilter会根据其mode参数来决定如何取(-5,-5)这个超出边界的像素。下面是四种可选的mode介绍:

  • DisplacementMapFilterMode.WRAP -- 将置换值折返到源图像的另一侧。
  • DisplacementMapFilterMode.CLAMP -- 将置换值锁定在源图像的边缘。
  • DisplacementMapFilterMode.IGNORE -- 如果置换值超出了范围,则忽略置换并使用源像素。
    • DisplacementMapFilterMode.COLOR -- 如果置换值在图像之外,则替换 color 和 alpha 属性中的值。

扭起来吧少年

介绍完了好基友DisplacementMapFilter童鞋,接下来就应该看看它能怎样配合perlinNoise来产生“扭扭更健康”的目标。先看一个水波纹的例子,该例子出自

http://www.thetechlabs.com/tech-tutorials/flash/create-real-water-effects-with-flash-cs4-actionscript-30/

当然,这个例子也是纯英文的,英文不好的童鞋只需要看看它的成果演示就够了。我这里只对它头一个例子做一些解释,若是打不开上面给的地址,可以看这里(点击图片浏览):

至于实现原理,说简单也简单:生成不规则的波纹靠的是perlinNoise,让波纹产生扭曲则靠的是之前介绍的DisplacementMapFilter,最后让波纹不停地滚动,就得靠不停地滚动使用perlinNoise生成的杂点图像并不停地为目标图片更新滤镜了。在上面给出的文章地址中,老外作者使用了每帧改变perlinNoise的offsets参数来实现滚动:

var bm:BitmapData=new BitmapData(backImg1.width, backImg1.height);
var disp:DisplacementMapFilter = new DisplacementMapFilter(bm,new Point(0,0),1,2,10,60);
var pt1:Point = new Point(0,0);
var pt2:Point = new Point(0,0);
var perlinOffset:Array = [pt1, pt2]; addEventListener(Event.ENTER_FRAME, onFrame);
function onFrame(evt:Event):void {
perlinOffset[0].x +=1;
perlinOffset[1].y +=0.1;
bm.perlinNoise(45,9,2,50,true,false, 7,true,perlinOffset);
backImg1.filters=[disp];
}

这样写固然简单,但是在之前的噪声的魅力(上)这篇文章中我们提到过,使用这种改变offests参数的方式来滚动柏林杂点图效率低下,因为它每帧都要调用perlinNoise方法来生成新图。那么更加高效的方式之前也在云飘动的例子中提到过,就是使用一种类似传送带的方法(也可以叫做卡马克卷轴算法)来做到。这里就不多解释了,我直接把水波纹的特效做成了一个单独组件SWaterWaveEffect,并收录在了我的SComponent系列中,列位可以去置顶的帖子里下载源码进行查看。

【AS3 Coder】任务四:噪音的魅力(下)的更多相关文章

  1. 【AS3 Coder】任务七:初涉PureMVC——天气预报功能实现

    转自:http://www.iamsevent.com/post/36.html AS3 Coder]任务七:初涉PureMVC——天气预报功能实现 使用框架:AS3任务描述:了解PureMVC框架使 ...

  2. 【AS3 Coder】任务九:游戏新手引导的制作原理(上)

    使用框架:AS3任务描述:了解游戏中新手的制作原理及流程 难度:3 本章源码下载:http://www.iamsevent.com/zb_users/UPLOAD/GuideManager/Test1 ...

  3. 【AS3 Coder】任务五:Flash 2D游戏的第二春(中)

    在上一节中,我们介绍了如何构建我们小小的90度角RPG游戏的背景,在这一节中我将为列位带来重头戏部分,隆重介绍我们的主角及NPC登场,噔噔噔噔……掌声在哪里?! 额,没听到掌声,罢了,直接开场吧. 本 ...

  4. 【AS3 Coder】任务四:噪音的魅力(上)

    使用框架:AS3任务描述:使用AS3中BitmapData的noise方法以及perlinNoise方法构建自然景观效果以及其他一些比较cool的效果难度系数:2 本文章源码下载:www.iamsev ...

  5. 【AS3 Coder】任务四:噪音的魅力(中)

    如果把Math.random方法作为一个生成随机数字的办法,那么bitmapData.perlinNoise就是一个生成随机颜色的办法.在这一部分的对于噪声的应用介绍文章中我们一起来看看使用柏林噪声的 ...

  6. 【AS3 Coder】任务九:游戏新手引导的制作原理(下)

    在上一篇教程中,我们了解了一套我自创的新手引导管理框架的使用原理,那么在本篇教程中,我们将考虑新手引导制作中可能遇到的一些棘手问题及探讨其解决方案.Are you ready my baby? Let ...

  7. 【AS3 Coder】任务五:Flash 2D游戏的第二春(下)

    在上一节中,我们基本上已经讲完了游戏中最主要的逻辑部分,不过为了更加全面地运用Starling中的一些特性,在本节中我们将一起来看看如何实现多面板切换以及粒子效果,这两个玩意儿可是比较频繁会出现于St ...

  8. 【AS3 Coder】任务八:没剧情还玩毛RPG

    使用框架:AS3任务描述:了解RPG游戏中剧情播放器的制作原理及流程难度系数:3(了解原理,能根据XML文件播放剧情) / 5(会制作剧情编辑器) 本章源码下载:http://www.iamseven ...

  9. 【AS3 Coder】任务六:人物换装(纸娃娃)系统的制作

    使用框架:AS3(Flash Professional CS5.0及更高版本 + Flash Buider)任务描述:了解人物换装系统的制作原理难度系数:2 本章源码下载:http://www.iam ...

随机推荐

  1. LeetCode 192:Reverse Bits

    Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...

  2. AngularJS 入门教程

    1. 简介:AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了.所以我做了一些工作(你也可以觉得是 ...

  3. QPS、TPS、PV等网站业务关键字释义

    QPS:Query Per Second TPS:Transaction Per Second PV:Page View RT:Response Time UV:Unique Visitor DAU: ...

  4. KVM(七)使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照

    本文将梳理 QEMU/KVM 快照相关的知识,以及在 OpenStack Nova 中使用 libvirt 来对 QEMU/KVM 虚机做快照的过程. 1. QEMU/KVM 快照 1.1 概念 QE ...

  5. PO/POJO/BO/DTO/VO的区别(转)

    PO :persistent object持久对象 1 .有时也被称为Data对象,对应数据库中的entity,可以简单认为一个PO对应数据库中的一条记录. 2 .在hibernate持久化框架中与i ...

  6. [BZOJ1475]方格取数 网络流 最小割

    1475: 方格取数 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 512[Submit][Status][Discuss] ...

  7. 在阿里云“专有网络”网络类型中配置vsftpd

    原文地址:传送门 环境:云服务器ECS,网络类型为“专有网络”,创建ECS绑定公网IP:系统镜像为Debian 8  现象:FTP客户端可以连接FTP服务端,但“读取目录列表失败”.       原因 ...

  8. 最小生成树的Prim算法

       构造最小生成树的Prim算法    假设G=(V,E)为一连通网,其中V为网中所有顶点的集合,E为网中所有带权边的集合.设置两个新的集合U和T,其中集合U用于存放G的最小生成树的顶点,集合T用于 ...

  9. 安装Team Services Agent Win7

    现状:项目现时使用的是Team Services,使用Team Services可以控制其中的一台Build Server,从Github提取代码,并在Build Server进入编译打包处理(son ...

  10. 让你的apache支持ipv6

    如果你使用的linux系统已经获取到了ipv6地址,你就可以让你的apache htpd 等也支持ipv6. 1.检查linux监听的端口,如果有:::port ,而且获取到了ipv6地址,则可以确定 ...