DirectX 3D_基础之粒子系统 广告牌技术 粒子和点精灵 点精灵的结构 点精灵的绘制状态 粒子及其属性

                 每日一语:

 

                 写了一段时间的技术博客后,现在回到家里,打开电脑,不写点东西,好像浑身不自在一样。可能已经形成了习惯. 之前在一本书中看过,称为21天现象。就是说,如果你做一件事情,连续保持21天都在做这件事情,到22天的时候,你就会潜意识记住做这件事情,如果不做,就会浑身不自在。如果你不信,可以试试吐舌头。我不希望在DIRECTX学习这件事上,只有开始,没有结尾,又成为一个烂尾工程。既然选择做了,就应该做出点东西出来,做出点成绩出来。

 

                 正文:

      
                  粒子系统:


                  许多自然现象都包含了大量行为相似的微小粒子(例如飘落的雪花,焰火的火星以及未来武器所发射的子弹等).粒子系统通常来模拟此现象。
     
                  粒子和点精灵:


                  粒子是一种微小的物体,在数学上通常用点来表示其模型。所以显示粒子时,使用点图元(由D3DPRIMITIVETYPE类型的D3DPT_POINTLIST枚举常量表示)是一个好的选择。但是,光栅化时,点图元将被映射为一个单个像素。这样就无法为我们提供很大的灵活性,因为实际应用中我们可能需要各种尺寸的粒子甚至希望能够对这些粒子进行纹理映射。在Direct3D 8.0之前,一般是使用广告牌技术来显示一个粒子。广告牌就是一个四边形,通过其自身世界变换矩阵的控制,使其总是面对摄像机。


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


                   我们用如下顶点格式来描述粒子的位置和颜色。
     
                             struct Particle
                             {
                                      D3DXVECTOR3 _position;
                                      D3DCOLOR _color;
                                      static const DWORD FVF;
                             }


                             const DWORD Particle::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

 

                  该结构存储了粒子的位置和颜色信息。也可以根据应用程序的需求来为该结构添加一对纹理坐标。

 

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

 

                          const DWORD Particle::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_PSIZE;


    
                请注意,即使硬件不支持D3DFVF_PSIZE,借助像素着色器(vertex shader)我们也有可能控制每个粒子的大小。

                点精灵的绘制状态:


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


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


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


 

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

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


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


 

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


                               _device->SetRenderState(D3DRS_POINTSCALEENABLE,true);

 

                D3DRS_POINTSIZE 用于指定点精灵的尺寸。该值可被解释为观察坐标系中的点精灵尺寸,也可被解释为屏幕坐标系中的点精灵尺寸,这主要取决于绘制状态D3DRS_POINTSCALEENABLE的设置。下面的代码将点的尺寸设为2.5个单位。
                               _device->SetRenderState(D3DRS_POINTSIZE,d3d::FtoDw(2.5f));

 

                d3d:FtoDW是我们在d3dUtility.h/CPP文件中新添加的参数,其功能是将float型变量强制转换为DWORD类型。我们必须这样做,因为IDirect3DDevice9::SetRenderState函数要求传入DWORD类型值而非float型。
    
                D3DRS_POINTSIZE_MIN 指定点精灵可取的最小尺寸。下面的例子将点的尺寸的最小值设置为0.2.


                            _device->SetRenderState(D3DRS_POINTSIZE_MIN,d3d::FtoDw(0.2f));

 

                 D3DRS_POINTSIZE_MAX 指定点精灵可取的最小尺寸。下面的例子将点的尺寸的最大值设置为0.2.


                           _device->SetRenderState(D3DRS_POINTSIZE_MAX,d3d::FtoDw(5.0f));  

 

                 D3DRS_POINTSCALE_A,D3DRS_POINTSCALE_B,D3DRS_POINTSCALE_C 这3个常量控制了点精灵的尺寸如何随距离发生变化,这里的距离是指点精灵到摄像机的距离。


                  给定距离和这些常量时,Direct3D使用如下公式计算点精灵的最终尺寸:
  
                         FinalSize = ViewportHeight.Size. √ 1 / (A + B(D) + C(D2);

 

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


 

                         ViewportHeight 视口高度。


 

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

 

                         A,B,C 分别对应于绘制状态D3DRS_POINTSCALE_A,D3DRS_POINTSCALE_B,D3DRS_POINTSCALE_C所指定的值。


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


                下面的代码对点精灵的距离常量进行了设置,这样点精灵就会随这距离的增大而边小。

 

                       _device->SetRenderState(D3DRS_POINTSCALE_A,d3d::FtoDw(0.0f));


                       _device->SetRenderState(D3DRS_POINTSCALE_B,d3d::FtoDw(0.0f));


 

                       _device->SetRenderState(D3DRS_POINTSCALE_C,d3d::FtoDw(0.1f));

 

                粒子及其属性:


                一个粒子除了位置和颜色外往往还有其它的属性。例如,粒子可具有一定的速度。但是,绘制粒子时并不需要这些附加属性。所以,我们将用于绘制粒子的数据于粒子的属性分别存储在两个不同的结构中。当我们要创建,销毁或更新粒子时,需要涉及粒子的属性;当我们准备绘制粒子时,可将粒子的位置和颜色信息复制到Particle结构中。
    
                粒子的属性与我们所要模拟的粒子系统的特定类型息息相关。但是,我们通过指定一些常用属性可以使这些属性结构变得通用一些。下面是一个包含了一些通用的粒子属性的结构。大多数系统并不需要如此众多的属性,但是有些系统可能还需要附加一些其他属性。


                      struct Attribute
                      {
                              D3DVECTOR3 _position;
                              D3DVECTOR3 _velocity;
                              D3DVECTOR3 _acceleration;
                              float _lifeTime;
                              float _age;
                              D3DXCOLOR _color;
                              D3DXCOLOR _colorFade;
                              bool _isAlive;
                      }

                     

                      下面就其参数进行说明:


                      _position 粒子在世界坐标系中的位置。


                      _velocity 粒子的速度。


 

                     _acceleration 粒子的加速度。


 

                      _lifeTime 粒子的自诞生到消亡所需的时间。例如,我们可能会在一段时间后,杀死一段光束粒子。


 

                      _age 粒子的当前年龄。

 

                      _color 粒子的颜色。


 

                      _colorFade 粒子颜色如何随时间渐弱。


                      _isAlive 若为true,表明粒子处于活动状态,否则表明粒子处于死亡状态。
 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值