1. 下面先来简单的介绍一下什么叫作Bump Mapping。
Bump Mapping又叫做凹凸贴图,在现在的图形处理以及游戏当中非常流行(大家应该都玩过Halflife-2或者Doom吧?)。凹凸贴图与普通贴图最大的区别是,凹凸贴图中的每个象素不仅代表着点的颜色,还代表着这个点凹凸的程度。 所以凹凸贴图(Bump Mapping)也经常被用来渲染一些看上去比较复杂的材质,比如凹凸不平的路面、生锈的铁罐、人类的皮肤还有剥落的墙面等等。下面是一张凹凸贴图的效果图, 它是由一张Bump Map(凹凸图)和一张普通的Texture (纹理)外加少许光照组成的。
+
=
凹凸贴图中的Height Map代表着一张凹凸贴图(Bump Mapping)中的每个象素突出品面的程度,一般由这个Height Map像素的亮度来代表,区间一般是0-255。凹凸贴图中的Texture则代表着这个像素自身为什么颜色。
2. 接下来在稍微讲一下这么玄的效果大致是怎么运算出来的。先来看一下一张普通的用亮度表示的Bump Map(凹凸图) 。
如果要求出这个点的颜色首先求出它的法向量,之后再于灯光以及材质进行运算后,这个点的最终颜色就求出来了。
x_gradient = pixel(x-1, y) - pixel(x+1, y)
y_gradient = pixel(x, y-1) - pixel(x, y+1)
使用这个公式可以很容易的求出每个点的斜度,然后使用这个斜度外加光线的位置就可以求出这个点的明暗,然后再将求出的明暗和材质进行运算后就可以的出最终的颜色啦!最后再将每个点显示出来,我们的效果就出现了!
3. 下面我们开始用Flash 8.0 ActionScript 2.0来实现这个效果的运算吧。
我的代码包里面有两个文件,一个是BumpMapper.as另一个是BumpingClip.as。BumpMapper.as 主要就是实现了一个BumpMapping的滤镜,基本上代码都在这里面。BumpingClip.as 则是一个MovieClip的子类,用来将Bump Mapping搬到台面上面来的。
这次我们将使用Flash 8.0里面新增的两个Filter(滤镜)。
flash.filters.ConvolutionFilter;flash.filters.DisplacementMapFilter。
第一个ConvolutionFilter使用一个3x3的矩阵对于图像每个象素周围的8个象素以及自己进行权加然后的到的值写入该像素。 他的公式如下:
dst (x, y) = ((src (x-1, y-1) * a0 + src(x, y-1) * a1.... src(x, y+1) * a7 + src (x+1,y+1) * a8) / divisor) + bias
我们熟悉的模糊效果就是这么的出来的~~ 当然我们今天不准备拿它作模糊效果。而是借助它能够进行使用临近像素运算的功能来运算出每个象素的斜度。
第二个DisplacementMapFilter则是使用一个MapBitmap来将源位图某位置上的像素影射到目标位图上,通常来实现扭曲效果,当然我们今天将用它来进行凹凸贴图(Bump Map)之后的灯光的映射。
下面我们来亲手制作一个凹凸贴图效果吧。
0. 首先下载源代码并将解压缩后的org目录放置在与你新建的文件同一个目录中,不然Flash可能找不到外部需要使用的Action Script的位置。
1. 将你喜欢的图片也就是Texture拖上来,然后将其转化成元件并命名为textureMap(在将位图放到元件中记住一定要将位图放在左上角,也就是0,0位置,不然会有意想不到的事情发生)。
2. 将舞台上的元件也命名为texture,并且再转化成元件命名为bumpped Map。
3. 在库里面找到bumpped Map右键然后单击链接在action 2.0类 里面输入 org.guRuSoft.Bumper.BumpingClip后确定。
4. 将你喜欢的灯光位图导入库中,然后新建一个元件并命名为light,然后将灯光位图放入这个元件的正中间。
5 将你希望用作为凹凸图的位图导入库中并将位图命名为bumpMap。
6. 进入Bumpped Map元件,并在第一帧里面写入:
import flash.display.BitmapData;
this.textureMap=textureMap; //告诉这个BumppingClip我们使用舞台上的texture来作为这个Bump Map的纹理
this.bumpMap = BitmapData.loadBitmap("bumpMap"); //在库中读取bumpMap位图并且教给BumppingClip作为Height Map
this.lightMap = "light"; //告诉Bumpping Clip我们使用库中名字为light的MovieClip来作为灯光
this.startRender(); //告诉Bumpping Clip全都弄好了,可以开始渲染了。
这样一切就都好了,如果你希望在舞台上使用鼠标来控制灯光的话,可以在前面的script后面加上:
function onEnterFrame(){
this.lightClip._x=textureMap._xmouse;//lightClip属性可以从Bumpping Clip中读出使用中的灯光元件(MovieClip)
this.lightClip._y=textureMap._ymouse;
}
有问题可以+我QQ:29858901 。
这个文章的很大的灵感是从UnitZeroOne的到的,大家也可以去看看哈。
http://www.unitzeroone.com/blog/
G_Star 效果:
G_Star2 效果:
附件: guRu Bumper.rar
guRu Bumper_v2.rar