粒子系统

来源:互联网 发布:日本红外光谱数据库 编辑:程序博客网 时间:2024/04/28 20:23

粒子系统

一、         粒子和点精灵

粒子是一种微小的物体,数学上通常用点来表示其模型。所以显示粒子时,使用点图元(由D3DPRIMITIVETYPE类型的D3DPT_POINTLIST枚举常量表示)是一个很好的选择。但是,光栅化时,点图元将被映射为一个单个像素。这样就无法为我们提供很大的灵活性,因为实际应用中我们很可能需要各种尺寸的粒子甚至希望能够对这些粒子进行纹理映射。

Direct3D8.0引入了一种特别的点图元——点精灵(Point Sprite),该图元极适合应用于粒子系统中。与普通的点图元不同,点精灵可进行纹理映射且尺寸可变。点精灵也不同于广告牌,描述点精灵时仅需要一个单点(single point)即可。由于我们只需要存储和处理一个顶点而非4个(广告牌要用4个顶点描述),这样就节省了内存和宝贵的运算时间。

1.        结构格式

我们用如下顶点结构来描述粒子的位置和颜色。

该结构金存储了粒子的位置和颜色信息,也可以根据需要为该结构添加一对纹理坐标。

有时我们可能需要为Particle结构添加一个浮点类型的变量来表示其尺寸。为了放映该变化,我们必须为灵活顶点格式FVF增加D3DFVF_PSIZE标记。让每个粒子对象维护其自身的尺寸十分有用,因为这就允许我们单独指定或改变某个粒子的尺寸。但由于大多数图形卡都不支持按照这种方式控制粒子的尺寸,所以我们就不采用这种做法。(可检查结构D3DCAPS9中的成员FVFCaps中的D3DFVFCAPS_PSIZE位来验证。)我们可通过绘制状态来控制粒子的尺寸。下面就是一个顶点格式中含有尺寸成员的例子。

 

注意,即使硬件不支持D3DFVFCAPS_PSIZE,借助像素着色器我们也有可能控制每个粒子的尺寸。

2.        点精灵的绘制状态

点精灵的行为很大程度上是由绘制状态来控制的。我们来回顾一下这些绘制状态。

l         D3DRS_POINTSPRITEENABLE        一个布尔值。默认值为false

u       若指定为true,则规定整个当前纹理被映射到点精灵上。

u       若指定为false,则规定点精灵(如果其顶点结构中含纹理坐标的话)的纹理坐标所指定的纹理元被映射到点精灵上。

l         D3DRS_POINTSCALEENABLE          一个布尔值。默认值为false

u       若指定为true,则规定点的尺寸将用观察坐标系的单位来度量。观察坐标系的单位是仅用来描述摄像机坐标系中的3D点。点精灵的尺寸将依据近大远小的原则进行相应的比例变换。

u       若指定为false,则规定点的尺寸将用屏幕坐标系的单位(即像素)来度量。如果将该绘制状态指定为false,而且想将点精灵的尺寸设为3,则点精灵将变为屏幕上一个3 * 3的像素区域。

l         D3DRS_POINTSIZE     用于指定点经历了的尺寸。该值可被解释为观察坐标系中的点精灵尺寸,也可被解释为屏幕坐标系中的点精灵尺寸,这主要取决于绘制状态D3DRS_POINTSCALEENABLE的设置。

l         D3DRS_POINTSIZE_MIN          指定点精灵可取的最小尺寸。

l         D3DRS_POINTSIZE_MAX         指定点精灵可取的最大尺寸。

l         D3DRS_POINTSCALL_AD3DRS_POINTSCALL_BD3DRS_POINTSCALL_C      3个常量控制了点精灵的尺寸如何随距离发生变化,这里的距离是指点精灵到摄像机的距离。给定距离和这些常量时,Direct3D使用如下公式计算点精灵的最终尺寸:

 

 

 

其中:

²        FianlSize         计算出距离后,点精灵的最终尺寸。

²        ViewportHeight      视口高度。

²        Size        对应于由绘制状态D3DRS_POINT_SIZE所指定的值。

²        ABC 分别对应于绘制状态D3DRS_POINTSCALE_AD3DRS_POINTSCALE_BD3DRS_POINTSCALE_C所指定的值。

²        D            在观察坐标系中点精灵到摄像机的距离。由于在观察坐标系中,摄像机位于坐标原点,所以 ,其中(x, y, z)是点精灵在观察坐标系中的位置。

3.        粒子及其属性

一个粒子除了位置和颜色外往往还具有许多其他的属性。例如,例子可具有一定的速度。但是,绘制粒子时并不需要这些附加属性。所以,我们将用于绘制粒子的数据与粒子的属性分别存储在两个不同的结构中。当我们要创建、销毁或更新例子时,需要涉及粒子的属性;当我们准备绘制粒子时,可将粒子的位置和颜色信息复制到Particle结构中。

粒子的属性与我们所要模拟的例子系统的特定类型息息相关。但是,我们通过指定一些常用属性可以使这些属性结构变得通用一些。

二、         粒子系统的组成

粒子系统是众多粒子的集合,并负责对这些粒子进行维护和显示。粒子系统跟踪系统中影响所有例子状态的全局属性,例如粒子的尺寸、粒子的粒子源、将要映射到粒子的纹理等。按照功能来说,粒子系统主要负责更新、显示、杀死以及创建粒子。

1.        绘制一个粒子系统

由于粒子系统是动态的,我们需要在每帧中更新系统中的粒子。一种直观但是缺乏效率的粒子系统绘制方法是:创建一个足够容纳最大数目个粒子的顶点缓存。

对于每一帧进行的操作如下:

1)        更新所有粒子。

2)        将所有处于活动状态的粒子复制到顶点缓存中。

3)        绘制顶点缓存中的粒子。

该方法是可行的,但效率不是最高的。原因之一是该顶点缓存必须足够大以容纳系统中的所有粒子。但更重要的原因是,当我们将粒子从列表复制到顶点缓存的这个过程中,图形卡一直处于空闲状态。

一种更好的方法(即SDK中的例程Point Sprite所使用的方法)是:创建一个容量合理的顶点缓存(能够容纳2000个粒子)。然后我们将该顶点缓存划分为若干片断。例如,我们将每个片断的尺寸指定为可容纳500个粒子。然后创建全局变量i = 0, 用该变量来跟踪当前片断。

 

对每一帧的操作如下。

1)        更新所有粒子。

2)        将全部活动粒子被绘制。

Ø         若顶点缓存未满则:

ü         用标记D3DLOCK_NOOVERWRITE锁定片断i

ü         500个粒子复制到锁定片断i中。

Ø         若顶点缓存已满,则:

ü         用自顶点缓存的起始位置开始i=0

ü         将用标记D3DLOCK_DISCARD锁定片断i

ü         500个粒子复制到锁定片断i中。

3)        绘制片断i中的粒子。

4)        下一片断:i++

2.        随机性

系统中的粒子都具有某种随机性。

原创粉丝点击