返回列表 回复 发帖

[原创]使用Flash实现Bump Mapping的效果

--使用Flash实现Bump Mapping的效果--


1.  下面先来简单的介绍一下什么叫作Bump Mapping。
Bump Mapping又叫做凹凸贴图,在现在的图形处理以及游戏当中非常流行(大家应该都玩过Halflife-2或者Doom吧?)。
凹凸贴图与普通贴图最大的区别是,凹凸贴图中的每个象素不仅代表着点的颜色,还代表着这个点凹凸的程度。 所以凹凸贴图(Bump Mapping)也经常被用来渲染一些看上去比较复杂的材质,比如凹凸不平的路面、生锈的铁罐、人类的皮肤还有剥落的墙面等等。
下面是一张凹凸贴图的效果图, 它是由一张Bump Map(凹凸图)和一张普通的Texture (纹理)外加少许光照组成的

凹凸贴图的Texture

gLogo_1 copy.JPG
2007-1-30 16:45
+

凹凸贴图的Height Map

gLogo_bump_1 copy.JPG
2007-1-30 16:45
=

凹凸贴图效果图

screenshot.JPG
2007-1-30 16:34



凹凸贴图中的Height Map代表着一张凹凸贴图(Bump Mapping)中的每个象素突出品面的程度,一般由这个Height Map像素的亮度来代表,区间一般是0-255。
凹凸贴图中的Texture则代表着这个像素自身为什么颜色。


2.  接下来在稍微讲一下这么玄的效果大致是怎么运算出来的。

先来看一下一张普通的用亮度表示的Bump Map(凹凸图) 。
bumpmap6.gif
2007-1-30 16:37

如果要求出这个点的颜色首先求出它的法向量,之后再于灯光以及材质进行运算后,这个点的最终颜色就求出来了。
x_gradient = pixel(x-1, y) - pixel(x+1, y)
y_gradient = pixel(x, y-1) - pixel(x, y+1)

bumpmap7.gif
2007-1-30 16:37

使用这个公式可以很容易的求出每个点的斜度,然后使用这个斜度外加光线的位置就可以求出这个点的明暗,然后再将求出的明暗和材质进行运算后就可以的出最终的颜色啦!
最后再将每个点显示出来,我们的效果就出现了!

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后确定

linking

BumpedMap_a20linking_scr.JPG
2007-1-30 20:57

4. 将你喜欢的灯光位图导入库中,然后新建一个元件并命名为light,然后将灯光位图放入这个元件的正中间。
5  将你希望用作为凹凸图的位图导入库中并将位图命名为bumpMap。
7. 进入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/

[ 本帖最后由 guruqu 于 2007-2-8 15:06 编辑 ]

guRu Bumper.rar (735.15 KB)

源代码

guRu Bumper_v2.rar (703 KB)

源文件 版本2

G_Star.swf (321.61 KB)

Binary V1

G_Star2.swf (468.71 KB)

Binary V2

附件文件不存在或无法读入,请与管理员联系。
我有一个建议,可以设置一个缓冲系数,让光线有滞留现象,形成浮光效果,你可以试下.
实际上真正displace的是light,而且light是一个MovieClip,我想那个浮光的效果可以在Light MovieClip里面实现。
:L SORRY,分加错位置了..不过人对上号了..
感谢分享~
此人中科院高级潜水院院士,诺贝尔长期掉线奖得主,奥斯卡终身隐身奖得主.
好,有收获:victory:
这就是为什么用MovieClip作为灯光贴图的好处,可以充分利用Flash的特长。
下面是我对灯光MC作了修改后的效果,有一种灯光滞留的效果,实现也比较简单。

[ 本帖最后由 guruqu 于 2007-2-1 12:10 编辑 ]
..强 。。效果很好 。。
PF 。。
http://www.xietong.org/design/
再给你几个建议吧
1,在已有的光线滞留的基础上,结合粒子效果,制作出仿真火焰效果.哦,就是不断复制出一个个光源点,让它们分散或升腾.起机理实际就是把一个光源变成若干个光源.
当然可能遇到运行效率的瓶颈,不过应该可以优化,比如,优化光源范围,或者减小计算的频率(5帧计算一次,然后让所有点的计算分散开,比如100个光源点,每帧只有20个在计算),计算时想办法避免乘除法和循环.

关于粒子,我有个老帖里有公开的代码.希望能帮助到你.
http://space.flash8.net/bbs/view ... 4957&highlight=

2,PHOTOSHOP的有关滤镜都可以想办法利用到,比如位移运算,用一个中心白边缘黑的位图就可以模拟出比较真实的放大镜效果.其他的类似.

3,做成组件吧.


发现连接都失效了,我贴一下

[ 本帖最后由 boom1979010 于 2007-2-1 17:27 编辑 ]

粒子系统.rar (403.57 KB)

现在有一个问题,就是做displaceMapping的时候她需要使用一张Bitmap来作为Displace的位移量。 麻烦的地方是什么呢?就是当你旋转或者放大缩小这个MovieClip的时候,Filter里面的那个Bitmap是不会跟着缩放和旋转的,最后的出来的结果就可想而知了。所以这个问题没解决前就不用做成组建了,赫赫。 至于做成焰火效果,那是个好建议,但是不确定在Bump Mapping里面使用多个光源反而可能让BumpMapping的效果不是非常明显,具体也没有用flash实现过,不过opengl的例子倒是很多,等有空了再去试验一下吧,Flash真的还是蛮有意思的,非常期待As3.0出现阿~~ 3.0我看了一下api要比2.0清晰多了~~~ 期待期待!!
Matrix对象应该可以帮的到你

我不是很确定,你查查帮助吧.

[ 本帖最后由 boom1979010 于 2007-2-1 17:34 编辑 ]
恩,确实可以,但是每侦都要传一个matrix过去是在太累了~~ 感觉不干净~
现在这个样子是因为他把一个MovieClip节点全部Transform好了之后才进行Filter的,不知道有什么办法让他Filter好之后再Transform,因为这样的话Filter始终就会保持和MovieClip在一个空间里面而不必关心其它的Transform的事情了~~ 哎,郁闷拉~

还有感谢楼上的提供的那个压缩包哦~~ 真是有意思的东西~

[ 本帖最后由 guruqu 于 2007-2-1 20:56 编辑 ]
还有斑竹什么时候把这个放到教材里面阿~~~ 我很期待我的第一个教材发表阿~~~
不错啊,顶楼猪!
LZ太帅了,效果非常的棒!
期待你更多的好东西!
不错的构想..

不错啊!楼主我顶了。

楼主真厉害,这样也能做出来,我顶,沙发.

支持楼主!

原帖由 guruqu 于 2007-2-1 23:42 发表
还有斑竹什么时候把这个放到教材里面阿~~~ 我很期待我的第一个教材发表阿~~~
呵呵...好东西自然要大家一起分享,支持楼主!(已经收藏到教程里)
欢迎大家到OICQ群18824576群内一起讨论。
返回列表