文档章节

D3D中的粒子系统(1)

rise-worlds
 rise-worlds
发布于 2016/06/20 13:35
字数 2168
阅读 2
收藏 0

许多自然现象是由很多小的小颗粒组成的,它们有相似的行为。(例如,雪花落下,闪烁的火焰,冲出枪管的“子弹”),粒子系统用来模拟这种现象。

14.1 粒子和点精灵(Point Sprite)

粒子是一个很小的对象,它通常用来模拟数学中的一个点。点元是用来显示粒子的很好的方案,可是点元被光栅化成一个简单的像素。这没给我们多少灵活性,因为我们想有各种大小不同的粒子,并且把整个纹理平滑映射到这些粒子上。在Direct3D 8.0以前,因为点元方法的局限性而完全不使用他们。代替的方法是程序员将使用公告板去显示粒子,一个板是一个方格,世界矩阵用它来确定方向,使它总是朝向照相机。

Direct3D 8.0引入一个特殊的点元叫点精灵,多数时候被应用在粒子系统中。与一般的点元不同的是,点精灵有纹理映射并能改变大小。与公告板不同的是,能用一个简单的点描述一个点精灵,节省内存和处理时间,因为我们只是必须保存和处理一个点,而公告板则是四个。
14.1.1 结构的格式

我们使用下面的顶点结构来描述粒子的位置和颜色:
struct sParticle
{
    D3DXVECTOR3 position;
    D3DCOLOR    color;
};

const DWORD PARTICLE_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

这个结构只保存粒子的位置和颜色,这取决于你程序的需要,你能够用同样的结构去保存一套纹理坐标。

增加一个浮点变量给Particle结构去指定粒子的大小是可能的。我们必须增加一个D3DFVF_PSIZE标记给我们的灵活的顶点格式,以反映这个变化。每个粒子维护自己的大小很有用,因为它允许我们以具体情况指定并改变粒子的大小。可是,大多数的图形卡不支持控制粒子的大小,因此我们不使用它。(检查D3DFVFCAPS_PSIZE在D3 DCAPS9结构的FVFCaps成员)代替的方法是用渲染状态(render states)去控制粒子的大小,就像你很快看到的,有尺寸成员的顶点结构的例子:
strict Particle

{

     D3DXVECTOR3 _position;

     D3DCOLOR    _color;

     float       _size;

     static const DWORD FVF;

};

const DWORD Particle::FVF = D3DFVF XYZ | D3DFVF DIFFUSE |  D3DFVF_PSIZE;

注意:通过vertex shader,能够获取每个粒子的大小,即使你的硬件不支持D3DFVFCAPS_PSIZE。
14.1.2点精灵(Point Sprite)渲染状态

点精灵的行为大部分由渲染状态(render states)来控制,现在让我们来看一下这些渲染状态:

D3DRS_POINTSPRITEENABLE—A Boolean value. The default value is false.

True表示将当前的纹理全部映射到点精灵上。

False 表示用指定的纹理坐标映射到点精灵的点(图素)上。

_device->SetRenderState(D3DRS_POINTSPRITEENABLE, true);
D3DRS_POINTSPRITEENABLE
bool value. When TRUE, texture coordinates of point primitives are set so that full textures are mapped on each point. When FALSE, the vertex texture coordinates are used for the entire point. The default value is FALSE. You can achieve DirectX 7 style single-pixel points by setting D3DRS_POINTSCALEENABLE to FALSE and D3DRS_POINTSIZE to 1.0, which are the default values.

D3DRS_POINTSCALEENABLE—A Boolean value. The default value is false.

True表示用视图空间单位来解释点的大小。视图空间单位的3D空间点在照相机中,点精灵将会自动缩放,这取决到它有多远, 像其他对象一样,离照相机近的粒子比离照相机远的粒子要大。

False 表示点的大小将用屏幕空间单位来解释。屏幕空间单位是屏幕上的像素单位。. 因此如果你指定false, 例如, 设置点精灵的尺寸为3, 则点精灵在屏幕区域中的尺寸为3×3像素。.

_device->SetRenderState(D3DRS_POINTSCALEENABLE, true);
D3DRS_POINTSCALEENABLE
bool value that controls computation of size for point primitives. When TRUE, the point size is interpreted as a camera space value and is scaled by the distance function and the frustum to viewport y-axis scaling to compute the final screen-space.

D3DRS_POINTSIZE—表示点精灵的尺寸. 这个值可以任意指定视图空间或屏幕空间的点精灵的尺寸, 取决于D3DRS_POINTSCALEENABLE状态如何设置. 下面的代码段设置点的尺寸为2.5个单位。:

_device->SetRenderState( D3DRS_POINTSIZE, float_to_dword(2.5f) );
D3DRS_POINTSIZE
A float value that specifies the size to use for point size computation in cases where point size is not specified for each vertex. This value is not used when the vertex contains point size. This value is in screen space units if D3DRS_POINTSCALEENABLE is FALSE; otherwise this value is in world space units. The default value is the value a driver returns. If a driver returns 0 or 1, the default value is 64, which allows software point size emulation. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.
m_pDevice9->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&pointSize));
DWORD float_to_dword(float f)
{
    return *((DWORD*)&f);
}

D3DRS_POINTSIZE_MIN—表示点精灵的最小尺寸。例子,将设置最小值为0.2:

_device->SetRenderState(D3DRS_POINTSIZE_MIN, float_to_dword(0.2f));
D3DRS_POINTSIZE_MIN
A float value that specifies the minimum size of point primitives. Point primitives are clamped to this size during rendering. Setting this to values smaller than 1.0 results in points dropping out when the point does not cover a pixel center and antialiasing is disabled or being rendered with reduced intensity when antialiasing is enabled. The default value is 1.0f. The range for this value is greater than or equal to 0.0f. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.
m_pDevice9->SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&pointSizeMin));

D3DRS_POINTSIZE_MAX—表示点精灵的最大尺寸。例子,将设置最大值为5.0:

_device->SetRenderState(D3DRS_POINTSIZE_MAX, float_to_dword(5.0f));
D3DRS_POINTSIZE_MAX
A float value that specifies the maximum size to which point sprites will be clamped. The value must be less than or equal to the MaxPointSize member of D3DCAPS9 and greater than or equal to D3DRS_POINTSIZE_MIN. The default value is 64.0. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.
m_pDevice9->SetRenderState(D3DRS_PONTSIZE_MAX, *((DWORD*)&pointSizeMax));

D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, D3DRS_POINTSCALE_C—这3个常量表示如何根据距离控制点精灵的尺寸—这个距离是点精灵到照相机的距离。
D3DRS_POINTSCALE_A
A float value that controls for distance-based size attenuation for point primitives. Active only when D3DRS_POINTSCALEENABLE is TRUE. The default value is 1.0f. The range for this value is greater than or equal to 0.0f. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.
m_pDevice9->SetRenderState(D3DRS_POINTSCALE_A, *((DWORD*)&pointScaleA));
D3DRS_POINTSCALE_B
A float value that controls for distance-based size attenuation for point primitives. Active only when D3DRS_POINTSCALEENABLE is TRUE. The default value is 0.0f. The range for this value is greater than or equal to 0.0f. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.
m_pDevice9->SetRenderState(D3DRS_POINTSCALE_B, *((DWORD*)&pointScaleB));
D3DRS_POINTSCALE_C
A float value that controls for distance-based size attenuation for point primitives. Active only when D3DRS_POINTSCALEENABLE is TRUE. The default value is 0.0f. The range for this value is greater than or equal to 0.0f. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.
m_pDevice9->SetRenderState(D3DRS_POINTSCALE_C, *((DWORD*)&pointScaleC));

D3D用以下的公式去计算点精灵的最终尺寸,这取决于距离和这3个常量。

其中:

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

ViewportHeight:视口的高度。

Size:分别为D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, and D3DRS_POINTSCALE_C值。
D:在视图空间中点精灵与照相机的距离。因为照相机被放置在视图空间中的原点,这个值是:,也是点精灵所在的位置。

下面代码设置点精灵的距离常量,因此远处的点精灵将变小。
_device->SetRenderState(D3DRS_POINTSCALE_A, float_to_dword(0.0f));

_device->SetRenderState(D3DRS_POINTSCALE_B, float_to_dword(0.0f));

_device->SetRenderState(D3DRS_POINTSCALE_C, float_to_dword(1.0f));

14.1.3 粒子和他们的属性

一个粒子系统是由除了位置、颜色以外的更多的属性组成,例如,一个粒子有速度。然而,这些额外的属性对于渲染粒子来说不是必须的。因此,我们在单独的结构中保存渲染粒子所必须的数据和属性。当我们创建、显示或更新粒子时,我们使用属性来工作。当我们准备渲染时,我们从sParticle(粒子)结构中COPY位置和颜色。

对于我们模拟的具体粒子系统,粒子的属性也是不同的。因此我们能够归纳一些通用的属性,大多数系统用不上这么多,一些系统需要的属性这里可能还没有。
struct sParticleAttribute
{
    sParticleAttribute()
    {
        life_time = 0.0f;
        age          = 0.0f;
        is_alive  = true;
    }

    D3DXVECTOR3 position;
    D3DXVECTOR3 velocity;
    D3DXVECTOR3 acceleration;
    float        life_time;        // how long the particle lives for before dying
    float        age;            // current age of the particle
    D3DXCOLOR    color;            // current color of the particle
    D3DXCOLOR    color_fade;        // how the color fades with respect to time
    bool        is_alive;
};

position—粒子在世界空间中的位置

velocity—粒子的速度,每秒多少个单位。

acceleration—粒子的加速度, 每秒多少个单位。

life_time—粒子的生命周期. 例如,当一个时间段后,我们可以杀死一个激光柱的粒子.

age—粒子的当前年龄。

color—粒子的颜色。

color_fade—粒子随时间的变化而褪去的颜色。

is_alive—True 表示粒子活着;false 表示粒子死了。

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/04/04/1137667.html

rise-worlds

rise-worlds

粉丝 2
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
盈趣上海众多游戏技术岗位火热招募中

职位一:C/C++客户端开发工程师 工作职责: 1.负责MTK平台游戏客户端主要模块的开发 2.负责游戏客户端与服务器端的交互 3.负责客户端代码的整合及优化 职位要求: 1. 1年以上MTK平台游戏开发...

yuer150
2011/04/26
371
3
盈趣信息技术上海有限公司众多技术岗位招募中

职位一:C/C++客户端开发工程师 工作职责: 1.负责MTK平台游戏客户端主要模块的开发 2.负责游戏客户端与服务器端的交互 3.负责客户端代码的整合及优化 职位要求: 1. 1年以上MTK平台游戏开发经验...

yuer150
2011/05/02
1K
0
Unreal中的烟雾火焰流体模拟

版权声明:本文所有文章均为原创,原文链接:blog.uwa4d.com,如需转载请联系support@uwa4d.com https://blog.csdn.net/UWA4D/article/details/86649505 【博物纳新】是UWA旨在为开发者推荐新...

UWA
01/29
0
0
3D游戏引擎--Irrlicht

Irrlicht是一个3D游戏引擎。它具有高效,实时等特点,是个完全跨平台的引擎,使用D3D、OpenGL和它的自己的渲染程序。支持动态的阴影,粒子系统,角色动画,室内和室外技术以及碰撞检测等。 更多...

匿名
2008/12/06
41.5K
0
Loon 3D游戏引擎 开发心得 1

本人一直想着自己开发一个比较高质量游戏引擎出来。虽然总被别人说怎么可能事情,一个人是不可能。但我心里暗暗的笑着,怎么不可能呢!好吧,心动不如行动。借助xna框架下开发3d引擎不是很难...

单条裤
2013/03/15
463
0

没有更多内容

加载失败,请刷新页面

加载更多

Taro 兼容 h5 踩坑指南

最近一周在做 Taro 适配 h5 端,过程中改改补补,好不酸爽。 本文记录📝遇到的问题,希望为有相同需求的哥们👬节约点时间。 Taro 版本:1.3.9。 解决跨域问题 h5 发请求会报跨域问题,需...

dkvirus
56分钟前
4
0
Spring boot 静态资源访问

0. 两个配置 spring.mvc.static-path-patternspring.resources.static-locations 1. application中需要先行的两个配置项 1.1 spring.mvc.static-path-pattern 这个配置项是告诉springboo......

moon888
今天
3
0
hash slot(虚拟桶)

在分布式集群中,如何保证相同请求落到相同的机器上,并且后面的集群机器可以尽可能的均分请求,并且当扩容或down机的情况下能对原有集群影响最小。 round robin算法:是把数据mod后直接映射...

李朝强
今天
4
0
Kafka 原理和实战

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语班)。先后从事过电子商务、开放平...

vivo互联网技术
今天
19
0
java数据类型

基本类型: 整型:Byte,short,int,long 浮点型:float,double 字符型:char 布尔型:boolean 引用类型: 类类型: 接口类型: 数组类型: Byte 1字节 八位 -128 -------- 127 short 2字节...

audience_1
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部