• <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>

            永遠(yuǎn)也不完美的程序

            不斷學(xué)習(xí),不斷實(shí)踐,不斷的重構(gòu)……

            常用鏈接

            統(tǒng)計(jì)

            積分與排名

            好友鏈接

            最新評(píng)論

            HLSL初級(jí)教程(3)

            3.像素著色器

                   像素著色器是在對(duì)每個(gè)像素進(jìn)行光柵化處理期間在圖形卡的GPU上執(zhí)行的程序。(不像頂點(diǎn)著色器,Direct3D不會(huì)以軟件模擬像素著色器的功能。)它實(shí)際上替換了固定功能管線的多紋理化階段(the multitexturing stage),并賦予我們直接操縱單獨(dú)的像素和訪問(wèn)每個(gè)像素的紋理坐標(biāo)的能力。這種對(duì)像素和紋理坐標(biāo)的直接訪問(wèn)使我們可以達(dá)成各種特效,例如:多紋理化(multitexturing)、每像素光照(per pixel lighting)、景深(depth of field)、云狀物模擬(cloud simulation)、焰火模擬(fire simulation)、混雜陰影化技巧(sophisticated shadowing technique)。

                   像素著色器的編寫(xiě)、使用和頂點(diǎn)著色器大同小異,有了之前的基礎(chǔ),不用太過(guò)于詳細(xì)的介紹相信讀者也能理解,下面使用像素著色器實(shí)現(xiàn)多紋理化。


            3.1多紋理化

                   簡(jiǎn)單的說(shuō),多紋理化就是使用多個(gè)紋理貼圖混合后進(jìn)行渲染,如圖3.1,渲染過(guò)程中,從紋理1和紋理2中分別采樣,得到的顏色值依據(jù)一定規(guī)則進(jìn)行組合得到紋理3,這就是多紋理化。

            3.1



            3.2多紋理效果的像素著色器

                   下面是像素著色器的代碼,該代碼存儲(chǔ)于ps.txt中,該像素著色器根據(jù)輸入的兩套紋理坐標(biāo)對(duì)對(duì)應(yīng)的紋理貼圖進(jìn)行采樣,根據(jù)一定比例Scalar混合后輸出像素顏色。

            //全局變量

             

            //存儲(chǔ)顏色混合的比例值s,其中

            //Scalar.x = s

            //Scalar.y = 1-s

            vector Scalar;

             

            //紋理

            texture Tex0;

            texture Tex1;

             

            //紋理采樣器

            sampler Samp0 =

            sampler_state

            {

                Texture = <Tex0>;

                MipFilter = LINEAR;

                MinFilter = LINEAR;

                MagFilter = LINEAR;

            };

             

            sampler Samp1 =

            sampler_state

            {

                Texture = <Tex1>;

                MipFilter = LINEAR;

                MinFilter = LINEAR;

                MagFilter = LINEAR;

            };

             

            //輸入兩套紋理坐標(biāo)

            struct PS_INPUT

            {

                   float2 uvCoords0 : TEXCOORD0;

                   float2 uvCoords1 : TEXCOORD1;

            };

             

            //輸出像素顏色

            struct PS_OUTPUT

            {

                   float4 Color : COLOR0;

            };

             

            //入口函數(shù)

            PS_OUTPUT PS_Main(PS_INPUT input)

            {

                   PS_OUTPUT output = (PS_OUTPUT)0;

                   //分別對(duì)兩個(gè)紋理進(jìn)行采樣按照比例混合后輸出顏色值

                   output.Color = tex2D(Samp0, input.uvCoords0)*Scalar.x + tex2D(Samp1, input.uvCoords1)*Scalar.y;

                   return output;

            }

                   整個(gè)程序很容易理解,程序中涉及到著色器的紋理和采樣,是我們第一次接觸的內(nèi)容,下面給于說(shuō)明。

            3.2.1HLSL采樣器和紋理

                   vectormatrix一樣,采樣器sample和紋理texture也是HLSL語(yǔ)言的一種類型,HLSL著色器使用采樣器對(duì)指定紋理進(jìn)行采樣,得到采樣后的顏色值以供處理。

                   它們的用法如下:

                   //聲明一個(gè)紋理變量

                   texture g_texture;

             

                   //定義采樣器

                   sampler g_samp =

                   sampler_state

                   {

                          //關(guān)聯(lián)到紋理

                   Texture = <g_texture>;

                   //設(shè)置采樣器狀態(tài)

                       MipFilter = LINEAR;

                       MinFilter = LINEAR;

                       MagFilter = LINEAR;

                   };

             

                   //調(diào)用HLSL內(nèi)置函數(shù)tex2D取得顏色值,參數(shù)一為采樣器,參數(shù)二為紋理坐標(biāo)

                   vector Color = tex2D(g_samp, uvCoords);

                   更多HLSL采樣器和紋理的內(nèi)容請(qǐng)參見(jiàn)DirectX文檔。

             

                   以上是本例用到的像素著色器,在接下來(lái)的應(yīng)用程序中,我們將給三個(gè)著色器全局變量賦值:

            ²        Scalar

                          存儲(chǔ)顏色混合的比例值s,其中Scalar.x = s, Scalar.y = 1-s;

            ²        Samp0

                          第一層紋理采樣器;

            ²        Samp1

                          第二層紋理采樣器;

                   像素著色器的輸入結(jié)構(gòu)中我們?cè)O(shè)定了一個(gè)頂點(diǎn)對(duì)應(yīng)兩套紋理坐標(biāo),讀者可以留意一下應(yīng)用程序中對(duì)應(yīng)的頂點(diǎn)格式的定義。


            3.3應(yīng)用程序

                   程序中我們首先創(chuàng)建一個(gè)四邊形,然后使用像素著色器進(jìn)行紋理混合后對(duì)其進(jìn)行渲染。下面是應(yīng)用程序代碼:

            /*********************頂點(diǎn)格式定義*****************/

            struct CUSTOMVERTEX

            {

                   //定點(diǎn)位置坐標(biāo)

                   float x,y,z;

                   //兩套紋理坐標(biāo);

                   float tu0, tv0;

                   float tu1, tv1;

            };

            #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX2)

            /*********************聲明變量*****************/

            //頂點(diǎn)著色器

            LPDIRECT3DPIXELSHADER9 pixelShader   = 0;

            //常量表

            ID3DXConstantTable* pixelConstTable = 0;

             

            //常量句柄

            D3DXHANDLE ScalarHandle              = 0;

            D3DXHANDLE Samp0Handle                = 0;

            D3DXHANDLE Samp1Handle                = 0;

             

            //常量描述結(jié)構(gòu)

            D3DXCONSTANT_DESC Samp0Desc;

            D3DXCONSTANT_DESC Samp1Desc;

             

            //四邊形頂點(diǎn)緩存

            LPDIRECT3DVERTEXBUFFER9 quadVB = NULL;

            //兩個(gè)紋理

            LPDIRECT3DTEXTURE9 quadTexture0 = NULL;

            LPDIRECT3DTEXTURE9 quadTexture1 = NULL;

             

            /********************初始化應(yīng)用程序*****************/

            //創(chuàng)建四邊形頂點(diǎn)模型

            CUSTOMVERTEX quad[] =

            // x      y      z    tu0   tv0   tu1   tv1

            {{-3.0f, -3.0f, 10.0f, 0.0f, 1.0f, 0.0f, 1.0f},

            { -3.0f3.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f},

            3.0f, -3.0f, 10.0f, 1.0f, 1.0f, 1.0f, 1.0f},

            3.0f3.0f, 10.0f, 1.0f, 0.0f, 1.0f, 0.0f}};

             

            //創(chuàng)建頂點(diǎn)緩存

            void *ptr = NULL;

            g_pd3dDevice->CreateVertexBuffer(sizeof(quad),

                                                                     D3DUSAGE_WRITEONLY,

                                                                     0,

                                                                     D3DPOOL_MANAGED,

                                                                     &quadVB,

                                                                     NULL);

            quadVB->Lock(0, 0, (void**)&ptr, 0);

            memcpy((void*)ptr, (void*)quad, sizeof(quad));

            quadVB->Unlock();

             

            //創(chuàng)建紋理

            D3DXCreateTextureFromFile(g_pd3dDevice, "porpcart.jpg", &quadTexture0);

            D3DXCreateTextureFromFile(g_pd3dDevice, "luoqi.jpg", &quadTexture1);

             

            //檢測(cè)系統(tǒng)是否支持像素著色器

            D3DCAPS9 caps;

            g_pd3dDevice->GetDeviceCaps(&caps);

            if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1))

            {

                   MessageBox(0, "NotSupport Pixel Shader - FAILED", 0, 0);

                   exit(0);

            }

             

            //創(chuàng)建像素著色器

            ID3DXBuffer* codeBuffer        = 0;

            ID3DXBuffer* errorBuffer       = 0;

             

            HRESULT hr = D3DXCompileShaderFromFile("ps.txt",

                                                                              0,

                                                                              0,

                                                                              "PS_Main", // entry point function name

                                                                              "ps_1_1",

                                                                              D3DXSHADER_DEBUG,

                                                                              &codeBuffer,

                                                                              &errorBuffer,

                                                                              &pixelConstTable);

             

            // output any error messages

            if(errorBuffer)

            {

                   MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);

                   ReleaseCOM(errorBuffer);

            }

             

            if(FAILED(hr))

            {

                   MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0);

                   return false;

            }

             

             

            hr = g_pd3dDevice->CreatePixelShader((DWORD*)codeBuffer->GetBufferPointer(), &pixelShader);

             

            if(FAILED(hr))

            {

                   MessageBox(0, "CreatePixelShader - FAILED", 0, 0);

                   return false;

            }

             

            ReleaseCOM(codeBuffer);

            ReleaseCOM(errorBuffer);

             

            //得到各常量句柄

            ScalarHandle = pixelConstTable->GetConstantByName(0, "Scalar");

            Samp0Handle = pixelConstTable->GetConstantByName(0, "Samp0");

            Samp1Handle = pixelConstTable->GetConstantByName(0, "Samp1");

             

            //得到對(duì)著色器變量Samp0Samp0的描述

            UINT count;

            pixelConstTable->GetConstantDesc(Samp0Handle, & Samp0Desc, &count);

            pixelConstTable->GetConstantDesc(Samp1Handle, & Samp1Desc, &count);

             

            //設(shè)定各著色器變量為初始值

            pixelConstTable->SetDefaults(g_pd3dDevice);

            /********************渲染*****************/

            g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(153,153,153), 1.0f, 0 );

            g_pd3dDevice->BeginScene();

             

            //為著色器全局變量Scalar賦值

            D3DXVECTOR4 scalar(0.5f, 0.5f, 0.0f, 1.0f);

            pixelConstTable->SetVector(g_pd3dDevice, ScalarHandle, &scalar);

             

            //設(shè)置像素著色器

            g_pd3dDevice->SetPixelShader(pixelShader);

             

            //設(shè)置定點(diǎn)格式、綁定數(shù)據(jù)流

            g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);

            g_pd3dDevice->SetStreamSource(0, quadVB, 0, sizeof(CUSTOMVERTEX));

             

            //設(shè)置第一、二層紋理

            g_pd3dDevice->SetTexture(Samp0Desc.RegisterIndex, quadTexture0);

            g_pd3dDevice->SetTexture(Samp1Desc.RegisterIndex, quadTexture1);

             

            //繪制圖形

            g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

             

            g_pd3dDevice->EndScene();

            g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

             

                   程序中像素著色器的使用和之前頂點(diǎn)著色器的使用無(wú)二,只是設(shè)置著色器中紋理采樣器變量Samp0Samp1和設(shè)定著色器其他變量稍有不同:

                1. 首先通過(guò)變量名稱得到變量句柄:

                          Tex0Handle = pixelConstTable->GetConstantByName(0, " Samp0");

                          Tex1Handle = pixelConstTable->GetConstantByName(0, " Samp1");

                2. 然后通過(guò)句柄得到對(duì)變量的描述:

                          UINT count;

                          pixelConstTable->GetConstantDesc(Samp0Handle, & Samp0Desc, &count);

                          pixelConstTable->GetConstantDesc(Samp1Handle, & Samp1Desc, &count);

                3.最后通過(guò)SetTexture配合所得到的描述信息設(shè)置紋理:

                          g_pd3dDevice->SetTexture(Samp0Desc.RegisterIndex, quadTexture0);

                          g_pd3dDevice->SetTexture(Samp1Desc.RegisterIndex, quadTexture1);

             

                   編譯運(yùn)行程序,運(yùn)行效果如圖3.2,這里我們將顏色混合比例設(shè)置為0.5,如果讀者在渲染過(guò)程中不斷變換對(duì)著色器變量Scalar的賦值,你將會(huì)得到一個(gè)混合度不斷變換的多紋理效果。

                   D3DXVECTOR4 scalar(0.5f, 0.5f, 0.0f, 1.0f); //讀者可以嘗試改變混合采用的比例值

                   pixelConstTable->SetVector(g_pd3dDevice, ScalarHandle, &scalar);

             

             

            紋理一

            紋理二

            混合后紋理三

            3.2


            posted on 2008-08-04 15:56 狂爛球 閱讀(2624) 評(píng)論(0)  編輯 收藏 引用


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


            久久精品国产亚洲精品2020 | 国产精品免费久久久久电影网| 亚洲国产另类久久久精品 | 久久综合成人网| 日本五月天婷久久网站| 色偷偷偷久久伊人大杳蕉| 国产高潮国产高潮久久久| 久久精品国产只有精品2020| 久久久久久国产a免费观看不卡| 麻豆久久久9性大片| 国产精品久久久久AV福利动漫| 国内精品伊人久久久久妇| 久久久久国产精品麻豆AR影院 | 久久久久免费精品国产| 久久国产精品二国产精品| 亚洲∧v久久久无码精品| 老男人久久青草av高清| 欧美国产成人久久精品| 久久国产亚洲精品| 久久久久久精品免费看SSS| 亚洲国产精久久久久久久| 久久伊人精品一区二区三区| 欧美亚洲国产精品久久| 国产成人久久精品一区二区三区| 欧美一区二区精品久久| AA级片免费看视频久久| 久久久久99精品成人片三人毛片| 久久天天躁狠狠躁夜夜2020| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 久久中文精品无码中文字幕| 久久精品国产一区二区| 亚洲欧美久久久久9999| 亚洲精品午夜国产va久久| 欧美一级久久久久久久大片| av国内精品久久久久影院| 无码国产69精品久久久久网站| 97久久天天综合色天天综合色hd | 欧美激情精品久久久久久| 久久久国产视频| 99久久99久久| 日韩亚洲国产综合久久久|