用DirectX实现粒子系统(一)

简介:

引言

Point sprites,中文译成点精灵,是粒子系统的基础,本篇主要介绍point sprites的相关知识,为后续的粒子系统做准备。

Point Sprites(点精灵)

Point sprites是DirectX8中引入的一个新特性,主要是用来高效渲染粒子系统,使用point sprites做为底层数据结构,表示层配以纹理,可以呈现出任意形状的粒子。粒子系统应用十分广泛,可以用来模拟许多特殊效果,比如常见的爆炸,烟雾,火焰等,都可以用粒子系统实现。point sprites不支持固定的几何管线,只能使用可编程的顶点处理程序。

Point Primitive Rendering Controls(点的渲染控制)

DX8支持额外的参数来控制point sprites。这些参数使得点的大小是可变的并且可以进行完整的纹理映射。

Point size控制

点的大小由两个因素决定,一个是应用程序自定义的大小,另一个是点到摄像机的距离。应用程序可以通过两种方式来指定点的大小,一是逐个顶点设置,二是通过设置D3DRS_POINTSIZE,点的大小是基于camera space的,除非你使用的是post-transformed flexible vertex format(FVF)vertices。这种格式的顶点是经过变换的,所以点的大小是基于render target上的像素单位。下面的代码通常用来设置point size,由于SetRenderState接受DWORD类型的参数,所以需要一个float到DWORD的转换过程。

float  pointSize  = 1.0f  ;
m_device
-> SetRenderState( D3DRS_POINTSIZE,  * ((DWORD * ) & pointSize) );

如果D3DRS_POINTSCALEENABLE设置为TRUE,那么D3DRS_POINTSIZE中指定的值是基于word space的,如果D3DRS_POINTSCALEENABLE设置为FALSE,则D3DRS_POINTSIZE中指定的值是基于screen space的。如果用户逐个顶点指定了point size,那么D3DRS_POINTSIZE的值就不起作用了。

m_device -> SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE) ;

纹理坐标控制

D3D通过下面的方式计算点的纹理坐标,如果D3DRS_POINTSPRITEENABLE设置为TRUE,那么每个点都显示一个完整的纹理(具体的算法,稍后有述),通常,这只在点大于一个像素的时候有用。当D3DRS_POINTSPRITEENABLE设置为FALSE的时候,每个点的纹理坐标都应用于整个顶点。

Point size computation(计算点的大小)

点的大小由D3DRS_POINTSCALEENABLE决定,如果该字段设置为FALSE,就使用程序指定的大小(经过变换的)作为屏幕坐标系中的最终大小。如果该字段设置为TRUE,D3D使用下面的公式计算。

这里Si表示输入点的大小,可能是Vertex定义中指定的值,也可能是D3DRS_POINTSIZE指定的值。A,B和C分别代表D3DRS_POINTSCALE_A,D3DRS_POINTSCALE_B和D3DRS_POINTSCALE_C,Vh是Viewport的高度,De是眼睛到该点的距离(眼睛位于原点),De的计算方式如下

point size的最大值Pmax由D3DCAPS中的MaxPointSize和D3DRS_POINTSIZE_MAX这个渲染状态共同决定,取二者的最小值。最小值Pmin则由D3DRS_POINTSIZE_MIN这个渲染状态决定,所以点在屏幕坐标系中的最终大小由下面的方式决定。

Point Rendering(点的渲染)

一个屏幕坐标系中的点P = (X, Y, Z, W),若它在屏幕坐标系中的大小是S,则它被渲染成一个四边形,公式如下((X+S/2, Y+S/2, Z, W), (X+S/2, Y-S/2, Z, W), (X-S/2, Y-S/2, Z, W), (X-S/2, Y+S/2, Z, W)),这四个点的颜色是相同的,所以,点的颜色通常都是单一的。纹理的坐标是由D3DRS_POINTSPRITEENABLE这个渲染状态控制的。如果这个值被设置为FALSE,那么四个点的纹理坐标就是相同的,如果这个值设置为TRUE,则四个点的纹理坐标如下(0.F, 0.F), (0.F, 1.F), (1.F, 0.F), (1.F, 1.F)。详见下图。

如果开启了剪裁,则使用如下方式对points进行剪裁。若顶点超出了Viewport的深度范围(在D3DVIEWPORT9的MinZ及MaxZ之外),则点被剪掉,不渲染。如果point size超出了Viewport的X和Y范围,则point也被剪掉,不渲染。也有如下情况,point的位置超出了viewport的X或Y的范围,但是仍然可以部分被显示。

对于用户自定义的剪裁平面来说,point不一定会被正确的剪裁,如果D3DCAPS中PrimitiveMiscCaps字段的值不是D3DPMISCCAPS_CLIPPLANESCALEDPOINTS,则point使用用户定义的剪裁平面进行剪裁,这时仅仅使用顶点的位置,而忽略点的大小。在这种情况下,经过缩放的点将完全被显示(如果顶点位置位于剪裁平面内),硬件顶点处理可能支持point size,也可能不支持,比如,如果使用D3DCREATE_HARDWARE_VERTEXPROCESSING在HAL设备(D3DDEVTYPE_HAL)上来创建设备,并且D3DCAPS中的MaxPointSize被设置为1.0或0.0,则所有的point都只对应一个像素,如果想渲染size小于1.0的point,只能使用FVF(flexible vertex format)TL(transformed and lit)顶点格式或者软件顶点处理(D3DCREATE_SOFTWARE_VERTEXPROCESSING),在这种情况下D3D会模拟点精灵的渲染。

对于支持顶点处理和点精灵渲染的硬件设备来说,如果MaxPointSize设置为大于1.0f,那么对于为转换的point sprites,需要为每个顶点计算大小,对于转换过的顶点,需要为每个顶点计算D3DRS_POINTSIZE。


本文转自zdd博客园博客,原文链接http://www.cnblogs.com/graphics/archive/2012/06/25/2046106.html,如需转载请自行联系原作者

相关文章
|
索引
Directx11教程36 纹理映射(6)
本章主要是整理代码,做以下两件事情: 1、把世界坐标矩阵的计算,放在GraphicsClass的渲染函数中,之前放在D3DClass中,而且只是返回一个单位矩阵,没任何作用。如果要使其起作用,就要对每个model类都单独设置,很麻烦,比如我要画两个颜色立方体,岂不是要建立两个model类,而只是世界坐标矩阵不同。
829 0
Directx11教程41 纹理映射(11)
1、第一副图我们采用各性异性的滤波方式,并设置最大各性异性值为8.     samplerDesc.Filter =  D3D11_FILTER_ANISOTROPIC;     samplerDesc.MaxAnisotropy = 8;      第二副图我们用了常用的3线性差值滤波方式   samplerDesc.Filter =  D3D11_FILTER_MIN_MAG_MIP_LINEAR;         按道理说,对于远处的纹理贴图,第一副图要好些,但我看起来,似乎这两个效果差不多,第二副效果也还可以,对于远处的贴图,我并没有发现模糊的效果。
924 0
|
图形学
Directx11教程40 纹理映射(10)
本章尝试使用纹理行列式,或者说纹理数组,在ps中,使用2个纹理,最终的像素颜色,是光照颜色*纹理1采样颜色*纹理2采样颜色,主要是想达到如下的效果:    把这两个图像以及光照产生的颜色融合生成以下图像:   为此我们新建一个lighttex2.
1056 0
|
存储 索引
Directx11教程39 纹理映射(9)
在myTutorialD3D11_32中,我们在PlaneModelClass中增加一个纹理TextureClass* m_Texture;读入一个grass的纹理,程序执行后的效果如下: 完整的代码请参考: 工程文件myTutorialD3D11_32 代码下载: http://files.
919 0
Directx11教程38 纹理映射(8)
上篇日志中,我们用纹理和光照颜色调制的方式得到最终颜色,本章我们尝试用纹理采样的颜色,直接做为材质的漫反射系数Kd,并用它来做光照计算,最后再做个gamma校正,如果不做的话,效果会偏亮。      lighttex.
841 0
Directx教程(28) 简单的光照模型(7)
现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱。本节中我们在前面光公式的基础上,再给漫反射和高光加上一个衰减因子。       光源随着距离衰减并不是纯线性的,常用的公式是: d 是光源到着色点的距离。
951 0
|
存储
Directx教程(29) 简单的光照模型(8)
现在我们新建一个工程myTutorialD3D_23,在这个工程中,对前面一章的代码进行一些整理: 1、我们在顶点属性中增加材质的的漫反射系数和高光系数,前面我们放在一个光照材质结构中,这样我们能够比较灵活的定义不同顶点的材质属性,当然这也增加了顶点缓冲的大小。
786 0
Directx11教程(34) 纹理映射(4)
本篇教程中,我们尝试在myTutorialD3D_27中改变采样状态描述符的各种设置,看纹理贴图的方式有什么变化。 原始的代码是:     // 创建纹理采样描述符 samplerDesc.
879 0