• <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)而不息

            頂點(diǎn)著色器入門(1)

            頂點(diǎn)著色器(vertex shader)是一個(gè)在圖形卡的GPU上執(zhí)行的程序,它替換了固定功能管線(fixed function pipeline)中的變換(transformation)和光照(lighting)階段。(這不是百分之百的正確,因?yàn)轫旤c(diǎn)著色器可以被Direct3D運(yùn)行時(shí)(Direct3D runtime)以軟件模擬,如果硬件不支持頂點(diǎn)著色器的話)。圖17.1說明了管線中頂點(diǎn)著色器替換的部件。

            從圖17.1,我們知道,頂點(diǎn)以局部坐標(biāo)輸入到頂點(diǎn)著色器,并且必須輸出齊次剪裁空間的有顏色的頂點(diǎn)。(經(jīng)投影矩陣變換頂點(diǎn)后的空間稱作齊次剪裁空間(homogeneous clip space)。因此,要把一個(gè)頂點(diǎn)從局部空間變換到齊次坐標(biāo)空間,我們必須應(yīng)用下列變換序列:世界變換(world transformation),視圖變換(view transformation)和投影變換(projection transformation),它們分別由世界矩陣,視圖矩陣和投影矩陣來完成。)對(duì)于點(diǎn)元(point primitive),頂點(diǎn)著色器也被用于操作每個(gè)頂點(diǎn)的頂點(diǎn)大小。

             由于頂點(diǎn)著色器是我們(在HLSL中)寫的一個(gè)自定義程序,因此我們?cè)趫D形效果方面獲得了極大的自由性。我們不再受限于Direct3D的固定光照算法。此外,應(yīng)用程序操縱頂點(diǎn)位置的能力也有了多樣性,例如:cloth simulation,粒子系統(tǒng)的點(diǎn)大小操縱,還有頂點(diǎn)混合/morphing。此外,我們的頂點(diǎn)數(shù)據(jù)結(jié)構(gòu)更自由了,并且可以在可編程管線中包含比在固定功能管線中多得多的數(shù)據(jù)。

             頂點(diǎn)著色器仍然是相對(duì)新的特性,并且許多圖形卡不支持它們,特別是隨DirectX 9發(fā)布的較新版本的頂點(diǎn)著色器。通過檢查D3DCAPS9結(jié)構(gòu)的VertexShaderVersion成員,可以測(cè)試頂點(diǎn)著色器的版本。下列代碼段展示了這一點(diǎn):

            // If the device's supported version is less than version 2.0

            if( caps.VertexShaderVersion < D3DVS VERSION(2, 0) )

                 // Then vertex shader version 2.0 is not supported on this device.

            我們看到D3D_VERSION的兩個(gè)參數(shù)分別接收主和次版本號(hào)。現(xiàn)在,D3DXCompileShaderFromFile函數(shù)支持頂點(diǎn)著色器版本1.1和2.0。

             

            17.1頂點(diǎn)聲明

            我們已經(jīng)使用自由頂點(diǎn)格式(flexible vertex format,F(xiàn)VF)來描述頂點(diǎn)結(jié)構(gòu)中的各分量。但是,在可編程管線中,頂點(diǎn)數(shù)據(jù)包含的數(shù)據(jù)比用FVF所能表達(dá)的多很多。因此,我們通常使用更具表達(dá)性并且更強(qiáng)大的頂點(diǎn)聲明(vertex declaration)。注意:如果FVF能夠描述我們的頂點(diǎn)格式 我們?nèi)匀豢梢栽诳删幊坦芫€中使用它。不管用何種方法,只是為了方便,同樣FVF會(huì)在內(nèi)部被轉(zhuǎn)換為一個(gè)頂點(diǎn)聲明。

            17.1.1 描述頂點(diǎn)聲明

            我們將一個(gè)頂點(diǎn)聲明描述為一個(gè)D3DVERTEXELEMENT9結(jié)構(gòu)的數(shù)組。D3DVERTEXELEMENT9數(shù)組中的每個(gè)成員描述了一個(gè)頂點(diǎn)的分量。所以,如果你的頂點(diǎn)結(jié)構(gòu)有三個(gè)分量(例如:位置、法線、顏色),那么其相應(yīng)的頂點(diǎn)聲明將描述3個(gè)D3DVERTEXELEMENT9結(jié)構(gòu)的數(shù)組。這個(gè)D3DVERTEXELEMENT9結(jié)構(gòu)定義如下:

            typedef struct _D3DVERTEXELEMENT9 {

                 BYTE Stream;

                 BYTE Offset;

                 BYTE Type;

                 BYTE Method;

                 BYTE Usage;

                 BYTE UsageIndex;

            } D3DVERTEXELEMENT9;

             
            Stream——指定與頂點(diǎn)分量相關(guān)聯(lián)的流

            ffset——偏移,按字節(jié),相對(duì)于頂點(diǎn)結(jié)構(gòu)成員的頂點(diǎn)分量的開始。例如,如果頂點(diǎn)結(jié)構(gòu)是:

            struct Vertex

            {

                 D3DXVECTOR3 pos;

                 D3DXVECTOR3 normal;

            };

            ……pos分量的偏移是0,因?yàn)樗堑谝粋€(gè)分量;normal分量的偏移是12,因?yàn)閟izeof(pos) = 12。換句話說,normal分量以Vertex的第12個(gè)字節(jié)為開始。

            Type——指定數(shù)據(jù)類型。它可以是D3DDECLTYPE枚舉類型的任意成員;完整列表請(qǐng)參見文檔。常用類型如下:

                    D3DDECLTYPE_FLOAT1——浮點(diǎn)數(shù)值

                    D3DDECLTYPE_FLOAT2——2D浮點(diǎn)向量

                    D3DDECLTYPE_FLOAT3——3D浮點(diǎn)向量

                    D3DDECLTYPE_FLOAT4——4D浮點(diǎn)向量

                    D3DDECLTYPE_D3DCOLOR—D3DCOLOR類型,它擴(kuò)展為RGBA浮點(diǎn)顏色向量(r g b a),其每一分量都是歸一化到區(qū)間[0, 1]了的。

            Method——指定網(wǎng)格化方法。我們認(rèn)為這個(gè)參數(shù)是高級(jí)的,因此我們使用默認(rèn)值,標(biāo)識(shí)為D3DDECLMETHOD_DEFAULT.。

            Usage——指定已計(jì)劃的對(duì)頂點(diǎn)分量的使用。例如,它是否準(zhǔn)備用于一個(gè)位置向量、法線向量、紋理坐標(biāo)等?有效的用途標(biāo)識(shí)符(usage identifier)是D3DDECLUSAGE枚舉類型的:

            typedef enum _D3DDECLUSAGE {

                 D3DDECLUSAGE_POSITION     = 0,  // Position.

                 D3DDECLUSAGE_BLENDWEIGHTS = 1,  // Blending weights.

                 D3DDECLUSAGE_BLENDINDICES = 2,  // Blending indices.

                 D3DDECLUSAGE_NORMAL       = 3,  // Normal vector.

                 D3DDECLUSAGE_PSIZE        = 4,  // Vertex point size.

                 D3DDECLUSAGE_TEXCOORD     = 5,  // Texture coordinates.

                 D3DDECLUSAGE_TANGENT      = 6,  // Tangent vector.

                 D3DDECLUSAGE_BINORMAL     = 7,  // Binormal vector.

                 D3DDECLUSAGE_TESSFACTOR   = 8,  // Tessellation factor.

                 D3DDECLUSAGE_POSITIONT    = 9,  // Transformed position.

                 D3DDECLUSAGE_COLOR        = 10, // Color.

                 D3DDECLUSAGE_FOG          = 11, // Fog blend value.

                 D3DDECLUSAGE_DEPTH        = 12, // Depth value.

                 D3DDECLUSAGE_SAMPLE       = 13  // Sampler data.

            } D3DDECLUSAGE;

             

            D3DDECLUSAGE_PSIZE類型用于指定一個(gè)頂點(diǎn)的大小。它用于點(diǎn)精靈,因此我們可以基于每個(gè)頂點(diǎn)控制其大小。一個(gè)D3DDECLUSAGE_POSITION成員的頂點(diǎn)聲明意味著這個(gè)頂點(diǎn)已經(jīng)被變換,它通知圖形卡不要把這個(gè)頂點(diǎn)送到頂點(diǎn)處理階段(變形和光照)。

            UsageIndex——用于標(biāo)識(shí)多個(gè)相同用途的頂點(diǎn)分量。這個(gè)用途索引是位于區(qū)間[0, 15]間的一個(gè)整數(shù)。例如,假設(shè)我們有三個(gè)用途為D3DDECLUSAGE_NORMAL的頂點(diǎn)分量。我們可以為第一個(gè)指定用途索引為0,為第二個(gè)指定用途索引為1,并且為第三個(gè)指定用途索引為2。按這種方式,我們可以通過其用途索引標(biāo)識(shí)每個(gè)特定的法線。

            頂點(diǎn)描述聲明的例子:假設(shè)我們想要描述的頂點(diǎn)格式由位置向量和三個(gè)法線向量組成。頂點(diǎn)聲明可以指定如下:

            D3DVERTEXELEMENT9 decl[] =

            {

            {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},

            {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},

            {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1},

            {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 2},

            D3DDECL_END()

            };

            D3DDECL_END宏用于初始化D3DVERTEXELEMENT9數(shù)組的最后一個(gè)頂點(diǎn)元素。同樣的,注意法向量的用途索引標(biāo)簽。

             

            17.1.2 創(chuàng)建頂點(diǎn)聲明

            一旦你描述了一個(gè)頂點(diǎn)聲明為D3DVERTEXELEMENT9數(shù)組,我們就可以使用下面的方法獲得一個(gè)IDirect3DVertexDeclaration9接口指針:

            HRESULT IDirect3DDevice9::CreateVertexDeclaration(

                 CONST D3DVERTEXELEMENT9* pVertexElements,

                 IDirect3DVertexDeclaration9** ppDecl

            );

            pVertexElements——D3DVERTEXELEMENT9結(jié)構(gòu)數(shù)組,它描述我們想要?jiǎng)?chuàng)建的頂點(diǎn)聲明。

            ppDecl——用于返回創(chuàng)建的IDirect3DVertexDeclaration9接口指針

            例子調(diào)用,其中decl是一個(gè)D3DVERTEXELEMENT9數(shù)組:

            IDirect3DVertexDeclaration9* _decl = 0;

            hr = _device->CreateVertexDeclaration(decl, &_decl);

             

            17.1.3 使用一個(gè)頂點(diǎn)聲明

            回憶一下:自由頂點(diǎn)格式是一個(gè)方便的特性并且在內(nèi)部轉(zhuǎn)換成了頂點(diǎn)聲明。因此,當(dāng)直接使用頂點(diǎn)聲明,我們不再需要調(diào)用:Device->SetFVF( fvf );

            相反,我們調(diào)用:Device->SetVertexDeclaration( _decl );

            其中,_decl是一個(gè)IDirect3DVertexDeclaration9接口指針。

             

            17.2頂點(diǎn)數(shù)據(jù)用途

            考慮這個(gè)頂點(diǎn)聲明:

            D3DVERTEXELEMENT9 decl[] =

            {

            {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,  0},

            {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},

            {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   1},

            {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   2},

            D3DDECL_END()

            };

             

            我們需要一種方式,來定義一個(gè)頂點(diǎn)聲明的元素到頂點(diǎn)著色器的Input結(jié)構(gòu)的數(shù)據(jù)成員的映射。我們?cè)贗nput結(jié)構(gòu)中通過指定每個(gè)數(shù)據(jù)成員的語義(: usage-type [usage-index])定義這個(gè)映射。語義通過元素的用途類型和用途索引標(biāo)識(shí)頂點(diǎn)聲明中的一個(gè)元素。由數(shù)據(jù)成員的語義標(biāo)識(shí)的頂點(diǎn)元素是得以映射到數(shù)據(jù)成員的元素。例如,對(duì)應(yīng)于前面的頂點(diǎn)聲明的輸入結(jié)構(gòu)是:

            struct VS_INPUT

            {

                 vector position    : POSITION;

                 vector normal     : NORMAL0;

                 vector faceNormal1 : NORMAL1;

                 vector faceNormal2 : NORMAL2;

            };

            注意:如果我們遺漏了用途索引,就意味著用途索引為零。例如,POSITION和POSITION0是同一樣?xùn)|西。

            這里decl中的元素0,由用途POSITION和用途索引0標(biāo)識(shí),它映射到position。decl中的元素1,由用途NORMAL和用途索引0標(biāo)識(shí),它映射到normal。decl中的元素2,由NORMAL和用途索引1標(biāo)識(shí),它映射到faceNormal1。decl中的元素3,由用途NORMAL和用途索引2標(biāo)識(shí),它映射到faceNormal2。

            受支持的頂點(diǎn)著色器輸入用途(input usage)是:

            POSITION [n]——位置

            BLENDWEIGHTS [n]——混合權(quán)重

            BLENDINDICES [n]——混合索引

            NORMAL [n]——法線向量

            PSIZE[n]——頂點(diǎn)大小

            DIFFUSE [n]——散射顏色

            SPECULAR [n]——鏡面顏色

            TEXCOORD [n]——紋理坐標(biāo)

            其中,n是一個(gè)位于區(qū)間[0, 15]的可選整數(shù)。

            此外,對(duì)于輸出結(jié)構(gòu),我們必須指定每個(gè)成員是用來做什么的。例如,數(shù)據(jù)成員應(yīng)該被作為位置向量、顏色、紋理坐標(biāo)等對(duì)待嗎?圖形卡沒主意,除非你強(qiáng)制的告訴它。這也需要通過語法的語義來完成:

            struct VS_OUTPUT

            {

                 vector position  : POSITION;

                 vector diffuse   : COLOR0;

                 vector specular  : COLOR1;

            };

            受支持的頂點(diǎn)著色器輸出用途是:

            POSITION—位置

            PSIZE—頂點(diǎn)大小

            FOG—霧混合值

            COLOR [n]—頂點(diǎn)顏色。注意:可以有多個(gè)頂點(diǎn)顏色被輸出,并且這些顏色可以被混合在一起以產(chǎn)生最終的顏色。

            TEXCOORD [n]—頂點(diǎn)紋理坐標(biāo)。注意:多個(gè)頂點(diǎn)紋理坐標(biāo)可以被輸出。

            其中,n是一個(gè)位于區(qū)間[0, 15]的可選整數(shù)。


            posted on 2008-04-06 14:00 lovedday 閱讀(3802) 評(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久久av盛宴av| 亚洲va久久久噜噜噜久久天堂| 国产精品久久久久久吹潮| 老司机午夜网站国内精品久久久久久久久| 久久久久99精品成人片三人毛片| 色播久久人人爽人人爽人人片aV| 无码AV波多野结衣久久| yellow中文字幕久久网| 一本色综合网久久| 久久国产一片免费观看| 久久99精品久久久久久久不卡| 武侠古典久久婷婷狼人伊人| 久久久久久夜精品精品免费啦| 欧洲国产伦久久久久久久 | 久久精品中文字幕大胸| 综合网日日天干夜夜久久| 久久久国产精华液| 久久久精品午夜免费不卡| 中文精品久久久久人妻不卡| 久久无码一区二区三区少妇| 久久美女人爽女人爽| 伊人色综合久久天天人手人婷| 精品视频久久久久| 亚洲国产精品久久| 99热成人精品免费久久| 狠狠狠色丁香婷婷综合久久俺| 性高湖久久久久久久久| 久久只这里是精品66| 香蕉99久久国产综合精品宅男自 | 国产精品内射久久久久欢欢| 国产综合久久久久久鬼色| 亚洲精品高清国产一线久久| 久久夜色撩人精品国产小说| 久久久久无码精品| 青青草原综合久久大伊人导航| 久久人人爽人人爽人人片AV东京热| 人人狠狠综合久久亚洲婷婷| 欧美伊香蕉久久综合类网站| 一本一道久久精品综合 |