• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當(dāng)自強(qiáng)而不息

            D3D中的粒子系統(tǒng)(1)

            許多自然現(xiàn)象是由很多小的小顆粒組成的,它們有相似的行為。(例如,雪花落下,閃爍的火焰,沖出槍管的“子彈”),粒子系統(tǒng)用來模擬這種現(xiàn)象。


            14.1 粒子和點(diǎn)精靈(Point Sprite)

            粒子是一個(gè)很小的對(duì)象,它通常用來模擬數(shù)學(xué)中的一個(gè)點(diǎn)。點(diǎn)元是用來顯示粒子的很好的方案,可是點(diǎn)元被光柵化成一個(gè)簡單的像素。這沒給我們多少靈活性,因?yàn)槲覀兿胗懈鞣N大小不同的粒子,并且把整個(gè)紋理平滑映射到這些粒子上。在Direct3D 8.0以前,因?yàn)辄c(diǎn)元方法的局限性而完全不使用他們。代替的方法是程序員將使用公告板去顯示粒子,一個(gè)板是一個(gè)方格,世界矩陣用它來確定方向,使它總是朝向照相機(jī)。

            Direct3D 8.0引入一個(gè)特殊的點(diǎn)元叫點(diǎn)精靈,多數(shù)時(shí)候被應(yīng)用在粒子系統(tǒng)中。與一般的點(diǎn)元不同的是,點(diǎn)精靈有紋理映射并能改變大小。與公告板不同的是,能用一個(gè)簡單的點(diǎn)描述一個(gè)點(diǎn)精靈,節(jié)省內(nèi)存和處理時(shí)間,因?yàn)槲覀冎皇潜仨毐4婧吞幚硪粋€(gè)點(diǎn),而公告板則是四個(gè)。

            14.1.1 結(jié)構(gòu)的格式

            我們使用下面的頂點(diǎn)結(jié)構(gòu)來描述粒子的位置和顏色:

            struct sParticle
            {
                D3DXVECTOR3 position;
                D3DCOLOR    color;
            };

            const DWORD PARTICLE_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

             

            這個(gè)結(jié)構(gòu)只保存粒子的位置和顏色,這取決于你程序的需要,你能夠用同樣的結(jié)構(gòu)去保存一套紋理坐標(biāo)。

            增加一個(gè)浮點(diǎn)變量給Particle結(jié)構(gòu)去指定粒子的大小是可能的。我們必須增加一個(gè)D3DFVF_PSIZE標(biāo)記給我們的靈活的頂點(diǎn)格式,以反映這個(gè)變化。每個(gè)粒子維護(hù)自己的大小很有用,因?yàn)樗试S我們以具體情況指定并改變粒子的大小。可是,大多數(shù)的圖形卡不支持控制粒子的大小,因此我們不使用它。(檢查D3DFVFCAPS_PSIZE在D3 DCAPS9結(jié)構(gòu)的FVFCaps成員)代替的方法是用渲染狀態(tài)(render states)去控制粒子的大小,就像你很快看到的,有尺寸成員的頂點(diǎn)結(jié)構(gòu)的例子:

            strict Particle

            {

                 D3DXVECTOR3 _position;

                 D3DCOLOR    _color;

                 float       _size;

                 static const DWORD FVF;

            };

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

            注意:通過vertex shader,能夠獲取每個(gè)粒子的大小,即使你的硬件不支持D3DFVFCAPS_PSIZE。

            14.1.2點(diǎn)精靈(Point Sprite)渲染狀態(tài)

            點(diǎn)精靈的行為大部分由渲染狀態(tài)(render states)來控制,現(xiàn)在讓我們來看一下這些渲染狀態(tài):

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

            True表示將當(dāng)前的紋理全部映射到點(diǎn)精靈上。

            False 表示用指定的紋理坐標(biāo)映射到點(diǎn)精靈的點(diǎn)(圖素)上。

            _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表示用視圖空間單位來解釋點(diǎn)的大小。視圖空間單位的3D空間點(diǎn)在照相機(jī)中,點(diǎn)精靈將會(huì)自動(dòng)縮放,這取決到它有多遠(yuǎn), 像其他對(duì)象一樣,離照相機(jī)近的粒子比離照相機(jī)遠(yuǎn)的粒子要大。

            False 表示點(diǎn)的大小將用屏幕空間單位來解釋。屏幕空間單位是屏幕上的像素單位。. 因此如果你指定false, 例如, 設(shè)置點(diǎn)精靈的尺寸為3, 則點(diǎn)精靈在屏幕區(qū)域中的尺寸為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—表示點(diǎn)精靈的尺寸. 這個(gè)值可以任意指定視圖空間或屏幕空間的點(diǎn)精靈的尺寸, 取決于D3DRS_POINTSCALEENABLE狀態(tài)如何設(shè)置. 下面的代碼段設(shè)置點(diǎn)的尺寸為2.5個(gè)單位。:

            _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—表示點(diǎn)精靈的最小尺寸。例子,將設(shè)置最小值為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—表示點(diǎn)精靈的最大尺寸。例子,將設(shè)置最大值為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個(gè)常量表示如何根據(jù)距離控制點(diǎn)精靈的尺寸—這個(gè)距離是點(diǎn)精靈到照相機(jī)的距離。

            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用以下的公式去計(jì)算點(diǎn)精靈的最終尺寸,這取決于距離和這3個(gè)常量。

            其中:

            FinalSize:距離計(jì)算后,點(diǎn)精靈的最后尺寸。

            ViewportHeight:視口的高度。

            Size:分別為D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, and D3DRS_POINTSCALE_C值。

            D:在視圖空間中點(diǎn)精靈與照相機(jī)的距離。因?yàn)檎障鄼C(jī)被放置在視圖空間中的原點(diǎn),這個(gè)值是:,也是點(diǎn)精靈所在的位置。

            下面代碼設(shè)置點(diǎn)精靈的距離常量,因此遠(yuǎn)處的點(diǎn)精靈將變小。

            _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 粒子和他們的屬性

             一個(gè)粒子系統(tǒng)是由除了位置、顏色以外的更多的屬性組成,例如,一個(gè)粒子有速度。然而,這些額外的屬性對(duì)于渲染粒子來說不是必須的。因此,我們?cè)趩为?dú)的結(jié)構(gòu)中保存渲染粒子所必須的數(shù)據(jù)和屬性。當(dāng)我們創(chuàng)建、顯示或更新粒子時(shí),我們使用屬性來工作。當(dāng)我們準(zhǔn)備渲染時(shí),我們從sParticle(粒子)結(jié)構(gòu)中COPY位置和顏色。

            對(duì)于我們模擬的具體粒子系統(tǒng),粒子的屬性也是不同的。因此我們能夠歸納一些通用的屬性,大多數(shù)系統(tǒng)用不上這么多,一些系統(tǒng)需要的屬性這里可能還沒有。

            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—粒子的速度,每秒多少個(gè)單位。

            acceleration—粒子的加速度, 每秒多少個(gè)單位。

            life_time—粒子的生命周期. 例如,當(dāng)一個(gè)時(shí)間段后,我們可以殺死一個(gè)激光柱的粒子.

            age—粒子的當(dāng)前年齡。

            color—粒子的顏色。

            color_fade—粒子隨時(shí)間的變化而褪去的顏色。

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


            posted on 2008-04-03 16:55 lovedday 閱讀(3188) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            国产免费久久久久久无码| 久久国语露脸国产精品电影| 久久国语露脸国产精品电影| 久久久久久国产精品无码下载| 亚洲一级Av无码毛片久久精品| 日韩欧美亚洲综合久久| 无码人妻久久一区二区三区免费 | 久久99热这里只频精品6| 精品国产日韩久久亚洲| 国产精品对白刺激久久久| 久久精品成人| 国内精品伊人久久久久av一坑| 精品久久久久久久中文字幕| 久久人人爽人人爽人人片AV不 | 久久久无码精品亚洲日韩京东传媒| 亚洲乱码精品久久久久..| 99久久精品久久久久久清纯| 久久久久久久精品成人热色戒| 国产成人精品久久亚洲高清不卡 | 久久久久国产精品嫩草影院| 久久久久久久综合综合狠狠| 成人国内精品久久久久一区| 久久久久久久97| 久久久久国产日韩精品网站| 狠狠狠色丁香婷婷综合久久五月| 久久久久久久波多野结衣高潮 | 激情久久久久久久久久| 77777亚洲午夜久久多喷| 超级碰碰碰碰97久久久久| 久久久久亚洲AV无码专区网站| 国产精品久久久久久| 久久久噜噜噜久久熟女AA片| 久久久亚洲裙底偷窥综合| 蜜桃麻豆WWW久久囤产精品| 久久人人爽人爽人人爽av| 99久久精品国产综合一区| 久久国产热这里只有精品| 国产精品美女久久久免费| 国产女人aaa级久久久级| 国产成人无码精品久久久久免费| 久久综合狠狠色综合伊人|