分享
 
 
 

让你领会真实火焰效果模拟再现

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

游戏制作离不开各种各样的特效,火焰效果更是这些特效当中最常用的一种。在网上有很多的这方面的例子,但似乎都不太理想。下面我主要介绍几种有效的火焰模拟算法。

在讲述火焰算法之前,我想先介绍一个经典的Blur算法,这将为我们后面的文章提供很好的技术基础,因为这是模拟火焰的关键所在。^_^

对于不同的效果我们要采取不同的模糊(Blur)算法,在这里我只介绍最简单的一种。

其实Blur算法相当简单,并不像很多人想象的那么神秘,只要一句话就可以解释清楚。我们所要做的不过是把屏幕上的每一个点用它周围的四个点的平均值代替即可。即:

好了,下面我们进入主题,Let' s get in …… FIRE ! ! !

总的来说,模拟一个火焰效果需要以下这三个步骤:放置热源、火焰上升、减掉衰减因子。

1.放置热源:

放置热源很好理解,也很好实现,我们只需要在屏幕的适当位置(想升起火焰的地方)放上一些亮点就可以了,比如:

for (int i=0; i

putpixel (i, 199, rand()%256);

2.火焰上升:

我们已经有了热源,那么如何使火焰升起来呢?这就要用到我们刚才讲到的Blur了。由于火焰是要向上升的,所以我们不能简单的选择待处理pixel的上、下 、左、右四个相临pixel,而是要选择它本身和它下面的三个pixel。具体实现的pseudo-code如下:

for (int y=0; y

{

for (int x=0; x

{

pixel(x,y)=(pixel(x,y)+

pixel(x-1,y+1)+

pixel(x,y+1)+

pixel(x+1,y+1))/4;

//……

putpixel (x,y,bright);

}

}

3.减衰减因子:

看到上面的 "//……" 了么?对了,那儿就是我们要添加如下这段代码的地方。为什么要减掉一个衰减因子呢?让我们通过两副图的对比来说明它的重要性吧:

图1. 减掉了衰减因子 (Fire.exe)

图2. 没有衰减(不可取!)

具体实现的pseudo-code如下:

if (--bright

bright = 0;//衰减且保证bright=0

记住:千万不要忘了检验不要让bright小于0,否则……自己试试就知道了,嘿嘿~~~~~~

也许读者会发现我们现在的火焰有些死板,所以我们不妨试着在火焰上加入一些spark(火星),这可以使我们的火焰更加有戏剧性虽然它在一定程度上削弱了火焰的真实性。其效果图如下:

图3. 添加了火星的效果 (FireWithSpark.exe)

看过Seumas McNally(我很崇拜的大师,呵呵)的ParticleFire(粒子火焰,见ParticleFire.exe)的朋友可能会知道,他在他的火焰处理上就用这个算法以使他的火焰更富戏剧性。

到此为止,我已经完整地介绍了模拟一个火焰效果地全部算法。但是这样模拟出来的火焰始终过于死板、不够逼真(当然,最为逼真的效果莫过于通过基于Alpha通道的伪粒子系统的实现,在这里我们不作讨论)。如何才能解决这个问题呢?一个很好的办法是把我们的热源放置在一个运动的物体上(Hugo就曾使用feed back和warp的技术逼真地模拟了火焰的效果,中国的程序员也有用与Hugo完全相同的算法真实模拟了这个效果),而不是放在屏幕底部,这样通过物体的运动再加上一些放缩、模糊技巧就可以使我们的火焰产生出意想不到的效果了!^_^。

具体运行效果如图4所示:

图4. 通过Rotate产生的火焰效果 (CoolFire.exe)

下面我就对这个算法的具体步骤进行简要地分析,并在适当的地方给出相应的代码、伪码。

这个算法主要也分成四个步骤:放置热源、移动物体、放缩、模糊。

1.放置热源:

这个步骤和上面步骤完全一样,不过就是画出一个物体。

2.移动物体:

在我的程序中我用了一系列的矩阵变换以完成物体的运动,当然也可以像Hugo一样,用feed back的技巧(只不过就是在一个平面上而不是3维空间中旋转物体)。具体实现见CoolFire.cpp,关于矩阵运算的具体实现见我的《走进3D的世界--C++中用运算符重载实现矩阵运算》一文,有关矩阵的运算请参考计算几何的有关书籍,在这里不作过多讨论。

Obj=rotX(thetaX)*rotY(thetaY)*rotZ(thetaZ);

3.放缩:

在程序中我的放缩采用了这样一个算法:先任取一定点(x,y),然后依次把屏幕上的每一个点与这个点比较,用它们之间的距离乘上一个放缩因子在加到(x,y)上,这个值便是放缩的索引值,以下便是实现的代码(未优化):

long Offset=0;

for

(y=0;y

{

for (x=0;x

{

IndexX=sx+(x-sx)*ScaleX;

IndexY=sy+(y-sy)*ScaleY;

lpVideoBuffer[Offset++]=lpSrcBuffer[IndexY*320+IndexX];

}

}

为了便于理解,我没有对代码进行优化,读者在编写程序时必须对以上代码进行有效地优化,具体方法是:先在一次循环中算出IndexX和IndexY的值并保存在数组中,待进行放缩操作时直接用它们作索引放缩,而不是像上面的代码一样边计算边操作放缩。

4.模糊:现在全国人民都知道Blur了吧,那我就不再罗嗦了。

好了,我想,对于火焰的算法我已经很清晰地展示在您地面前了,有效地运用这些算法一定会为您地游戏开发带来很大地便利。

文章中的所有实例(除了ParticleFire以外)均在Watcom C++中调试成功,读者在运行的时候必须保证您的运行目录里有dos4gw.exe,这是一个开启保护模式的程序,如果没有程序将无法运行。

(作者:周军)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有