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

            天行健 君子當自強而不息

            像素著色器入門(2)

            新建網頁 1

            18.4 HLSL采樣器對象

            在像素著色器中使用HLSL的內建函數tex*XXXX給紋理采樣。注意:采樣時引用紋理上圖素的坐標索引和采樣器狀態來生成像素。

            通常這些函數需要我們做2件事:

            使用紋理中的索引建立(u, v)紋理坐標。

            給特定的紋理中編入索引。

            將紋理坐標(u, v)輸入到像素著色器,在一個指定的HLSL對象中的像素著色器中,我們想編入索引的紋理是在像素著色器中被定義過的,在HLSL中叫作采樣器。(The particular texture that we want to index into is identified in the pixel shader by a special HLSL object called a sampler.),我們可以把采樣器對象想象成定義紋理和采樣器階段的對象。例如:假如我們使用3張紋理,這意味著我們需要在像素著色器里能夠引用3個階段中的每個一個。在像素著色器中我們這樣寫:

                            
                    

                    sampler FirstTex;

                    

                    sampler SecondTex;

                    

                    sampler ThirdTex;

            Direct3D將給每個采樣器對象連接一個唯一的紋理級別(stage),在應用程序中我們找出與采樣器對象相關聯的階段,并設置相應的紋理和采樣器狀態給該階段。下列代碼將舉例說明如何在應用程序中設置紋理并把采樣器狀態設置為FirstTex

                   
                

                    //         創建

                    IDirect3DTexture9* Tex;

                    D3DXCreateTextureFromFile(Device, "tex.bmp", &Tex);

                    

                    … …

                    

                    //         取得常量FirstTex的句柄

                    FirstTexHandle = MultiTexCT->GetConstantByName(0, "FirstTex");

                            

                    //         取得常量的描述

                    D3DXCONSTANT_DESC FirstTexDesc;

                    

                    UINT         count;

                    MultiTexCT->GetConstantDesc(FirstTexHandle, &FirstTexDesc, &count);

                    

                     … …

                    

                    //         FirstTex設置紋理和采樣器狀態.        

                    

                    // We identify the stage FirstTex is associated with from the           D3DXCONSTANT_DESC::RegisterIndex member:

                    

                    Device->SetTexture(FirstTexDesc.RegisterIndex, Tex);

                    

                    Device->SetSamplerState(FirstTexDesc.RegisterIndex,  D3DSAMP_MAGFILTER,      D3DTEXF_LINEAR);

                    

                    Device->SetSamplerState(FirstTexDesc.RegisterIndex,  D3DSAMP_MINFILTER,       D3DTEXF_LINEAR);

                    

                    Device->SetSamplerState(FirstTexDesc.RegisterIndex,  D3DSAMP_MIPFILTER,       D3DTEXF_LINEAR);

            注意:作為選擇,替換使用采樣器類型,你可以使用更多特殊的、強大的類型,如:sampler1D,sampler2Dsampler3D,和samplerCube類型,這些類型更安全并且它們只使用tex*函數。例如:一個sampler2D對象只使用tex2D*函數,同樣一個sampler3D對象只使用tex3D*函數。

             

             

            18.5例子程序:Multitexturing in a Pixel Shader

            這章中的例子演示了在像素著色器中使用多紋理,這個例子渲染的目標是一個木箱紋理,一個聚光燈紋理,和一個包含字符串的紋理。這就是例子程序:Pixel Shader。

             

            這個例子可以不使用像素著色器來實現,但實現這個程序是簡單直接,它允許我們示范如何編寫,創建,而且使用像素著色器實現一些特效不必使用那些復雜的算法。

            雖然在這個例子中一次只使用3張紋理,檢查采樣器對象的成員以確定每個像素著色器能夠使用的版本,這是值得的。換句話說,我們一次能使用多少紋理,這依賴于使用的像素著色器的版本:

            像素著色器的版本ps_1_1 ps_1_3支持4個紋理采樣器。

            像素著色器的版本ps_1_4支持6個紋理采樣器。

            像素著色器的版本ps_2_0 ps_3_0支持16個紋理采樣器。

             

                 /******************************************************************************
                  Pixel shader that does multi texturing.
                 ******************************************************************************/

                
                sampler g_base_texture;
                sampler g_spotlight_texture;
                sampler g_string_texture;
                
                
            struct sPixelInput
                {
                    float2 
            base         : TEXCOORD0;
                    float2 spotlight : TEXCOORD1;
                    float2 text         : TEXCOORD2;
                };
                
                
            struct sPixelOutput
                {
                    vector diffuse : COLOR0;
                };
                
                
                /////////////////////////////////////////////////////////////////////////////////
                

                sPixelOutput main(sPixelInput input)
                {
                    sPixelOutput output = (sPixelOutput) 0;
                
                    
            // sample appropriate textures
                
                    vector base_color       = tex2D(g_base_texture,        input.base);
                    vector spotlight_color = tex2D(g_spotlight_texture, input.spotlight);
                    vector text_color       = tex2D(g_string_texture,    input.text);
                
                    
            // combine texel colors
                
                    vector color = base_color * spotlight_color + text_color;
                
                    
            // increase the intensity of the pixel slightly
                
                color += 0.1f;
                
                    
            // save the resulting pixel color
                
                output.diffuse = color;
                
                    
            return output;
                }

            tex2D的函數使用說明如下:

            There are two overloaded tex2D texture lookup functions:

            • 2D texture lookup
            •     
            • 2D texture lookup with partial derivatives     

            2D texture lookup

            This function performs a 2D texture lookup.

            Syntax

                             
            ret tex2D(s, t)

            Where:

                                                                                                                                                                                                                                  
            NameIn/OutTemplate TypeComponent TypeSize
            sinobjectsampler2D1
            tinvectorfloat2
            retoutvectorfloat4

            2D texture lookup with partial derivatives

            This function performs a 2D texture lookup also, but also uses the partial derivatives to help pick the LOD.

            Syntax

                             
            ret tex2D(s, t, ddx, ddy)

            Where:

                                                                                                                                                                                                                                                                                                                                                
            NameIn/OutTemplate TypeComponent TypeSize
            sinobjectsampler2D1
            tinvectorfloat2
            ddxinvectorfloat2
            ddyinvectorfloat2
            retoutvectorfloat4

             

            首先像素著色器定義了3sampler對象,要渲染的每個紋理,接下來定義是inputoutput結構。注意:我們沒有將任何的顏色值輸入到像素著色器中,這是因為我們使用紋理自己的顏色和光照;即BaseTex保存表面的顏色,SpotLightTex是光照圖。像素著色器輸出只一個簡顏色值,指定了我們計算過的這個特定像素的顏色。

            Main函數使用tex2D函數采樣3個紋理,即它取得每個紋理的圖素,計算映射到的像素,這通常依賴于指定的紋理坐標和采樣器對象。然后我們混合圖素的顏色用公式:c = b * s + t。接下來我們讓全部的像素變亮一個bit,給每個部分增加0.1f。最后我們保存結果像素顏色并返回它。

            執行程序:

                 /**************************************************************************************************
                  Deomstrates multi-texturing using a pixel shader.  You will have to switch to the REF 
                  device to run this sample if your hardware doesn't support pixel shaders.
                 **************************************************************************************************/

                
                #include "d3dUtility.h"
                
                #pragma warning(disable : 4100)
                
                
            struct sMultiTextureVertex
                {
                    sMultiTextureVertex(
            float x, float y, float z,
                                        
            float u0, float v0,
                                        
            float u1, float v1,
                                        
            float u2, float v2)
                    {
                        _x =  x;  _y =  y; _z = z;
                        _u0 = u0; _v0 = v0; 
                        _u1 = u1; _v1 = v1;
                        _u2 = u2, _v2 = v2;
                    }
                
                    
            float _x, _y, _z;
                    
            float _u0, _v0;
                    
            float _u1, _v1;
                    
            float _u2, _v2;
                };
                
                
            const DWORD MULTI_TEXTURE_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_TEX3; 
                
                
                /////////////////////////////////////////////////////////////////////////////////////////////
                

                
            const int WIDTH  = 640;
                
            const int HEIGHT = 480;
                
                IDirect3DDevice9*        g_device;
                IDirect3DPixelShader9*    g_pixel_shader;
                ID3DXConstantTable*        g_constant_table;
                IDirect3DVertexBuffer9*    g_vertex_buffer;
                
                IDirect3DTexture9*        g_base_texture;
                IDirect3DTexture9*        g_spotlight_texture;
                IDirect3DTexture9*        g_string_texture;
                
                D3DXHANDLE                g_base_texture_handle;
                D3DXHANDLE                g_spotlight_texture_handle;
                D3DXHANDLE                g_string_texture_handle;
                
                D3DXCONSTANT_DESC        g_base_texture_desc;
                D3DXCONSTANT_DESC        g_spotlight_texture_desc;
                D3DXCONSTANT_DESC        g_string_texture_desc;
                
                
                ////////////////////////////////////////////////////////////////////////////////////////////////////
                

                
            bool setup()
                {    
                    
            // create geometry
                

                    g_device->CreateVertexBuffer(6 * 
            sizeof(sMultiTextureVertex), D3DUSAGE_WRITEONLY,
                        MULTI_TEXTURE_VERTEX_FVF, D3DPOOL_MANAGED, &g_vertex_buffer, NULL);
                
                    sMultiTextureVertex* v;
                
                    g_vertex_buffer->Lock(0, 0, (
            void**)&v, 0);
                
                    v[0] = sMultiTextureVertex(-10.0f, -10.0f, 5.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
                    v[1] = sMultiTextureVertex(-10.0f,  10.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
                    v[2] = sMultiTextureVertex( 10.0f,  10.0f, 5.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
                
                    v[3] = sMultiTextureVertex(-10.0f, -10.0f, 5.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
                    v[4] = sMultiTextureVertex( 10.0f,  10.0f, 5.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
                    v[5] = sMultiTextureVertex( 10.0f, -10.0f, 5.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
                
                    g_vertex_buffer->Unlock();
                
                    
            // compile shader
                

                    ID3DXBuffer*    shader_buffer;
                    ID3DXBuffer*    error_buffer;
                
                    HRESULT hr = D3DXCompileShaderFromFile("MultiTextureShader.cxx", NULL, NULL, "main", "ps_2_0", D3DXSHADER_DEBUG,
                                                           &shader_buffer, &error_buffer, &g_constant_table);
                
                    
            // output any error messages
                
                if(error_buffer)
                    {
                        MessageBox(NULL, (
            char*) error_buffer->GetBufferPointer(), "ERROR", MB_OK);
                        safe_release<ID3DXBuffer*>(error_buffer);
                    }
                
                    
            if(FAILED(hr))
                    {
                        MessageBox(NULL, "D3DXCompileShaderFromFile() - FAILED", "ERROR", MB_OK);
                        
            return false;
                    }
                
                    hr = g_device->CreatePixelShader((DWORD*) shader_buffer->GetBufferPointer(), &g_pixel_shader);
                
                    
            if(FAILED(hr))
                    {
                        MessageBox(NULL, "CreatePixelShader - FAILED", "ERROR", MB_OK);
                        
            return false;
                    }
                
                    safe_release<ID3DXBuffer*>(shader_buffer);
                
                    
            // load textures
                
                    D3DXCreateTextureFromFile(g_device, "crate.bmp",     &g_base_texture);
                    D3DXCreateTextureFromFile(g_device, "spotlight.bmp", &g_spotlight_texture);
                    D3DXCreateTextureFromFile(g_device, "text.bmp",         &g_string_texture);
                
                    
            // get handles
                
                    g_base_texture_handle        = g_constant_table->GetConstantByName(NULL, "g_base_texture");
                    g_spotlight_texture_handle    = g_constant_table->GetConstantByName(NULL, "g_spotlight_texture");
                    g_string_texture_handle        = g_constant_table->GetConstantByName(NULL, "g_string_texture");
                
                    
            // set constant descriptions
                

                    UINT count;
                
                    g_constant_table->GetConstantDesc(g_base_texture_handle,      &g_base_texture_desc,         &count);
                    g_constant_table->GetConstantDesc(g_spotlight_texture_handle, &g_spotlight_texture_desc, &count);
                    g_constant_table->GetConstantDesc(g_string_texture_handle,      &g_string_texture_desc,     &count);    
                
                    g_constant_table->SetDefaults(g_device);
                
                    
            // set the projection matrix
                
                D3DXMATRIX proj;
                    D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI/4.0f, (
            float)WIDTH/HEIGHT, 1.0f, 1000.0f);
                    g_device->SetTransform(D3DTS_PROJECTION, &proj);
                    
                    
            //g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
                
                
                    
            return true;
                }
                
                
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
                

                
            void cleanup()
                {    
                    safe_release<IDirect3DVertexBuffer9*>(g_vertex_buffer);
                
                    safe_release<IDirect3DTexture9*>(g_base_texture);
                    safe_release<IDirect3DTexture9*>(g_spotlight_texture);
                    safe_release<IDirect3DTexture9*>(g_string_texture);
                    
                    safe_release<IDirect3DPixelShader9*>(g_pixel_shader);
                    safe_release<ID3DXConstantTable*>(g_constant_table);
                }
                
                
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
                

                
            bool display(float time_delta)
                {    
                    
            // update the scene: allow user to rotate around scene.
                

                    
            static float angle  = (3.0f * D3DX_PI) / 2.0f;
                    
            static float radius = 20.0f;
                
                    
            if(GetAsyncKeyState(VK_LEFT) & 0x8000f)
                        angle -= 0.5f * time_delta;
                
                    
            if(GetAsyncKeyState(VK_RIGHT) & 0x8000f)
                        angle += 0.5f * time_delta;
                
                    
            if(GetAsyncKeyState(VK_UP) & 0x8000f)
                        radius -= 2.0f * time_delta;
                
                    
            if(GetAsyncKeyState(VK_DOWN) & 0x8000f)
                        radius += 2.0f * time_delta;
                
                    D3DXVECTOR3 position(cosf(angle) * radius, 0.0f, sinf(angle) * radius);
                    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
                    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
                
                    D3DXMATRIX view_matrix;
                    D3DXMatrixLookAtLH(&view_matrix, &position, &target, &up);
                    g_device->SetTransform(D3DTS_VIEW, &view_matrix);
                        
                    
            // render now
                

                    g_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 1.0f, 0);
                
                    g_device->BeginScene();
                
                    g_device->SetPixelShader(g_pixel_shader);
                
                    g_device->SetFVF(MULTI_TEXTURE_VERTEX_FVF);
                    g_device->SetStreamSource(0, g_vertex_buffer, 0, 
            sizeof(sMultiTextureVertex));
                
                    
            // base texture
                
                    g_device->SetTexture(g_base_texture_desc.RegisterIndex, g_base_texture);
                    g_device->SetSamplerState(g_base_texture_desc.RegisterIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                    g_device->SetSamplerState(g_base_texture_desc.RegisterIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
                    g_device->SetSamplerState(g_base_texture_desc.RegisterIndex, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
                
                    
            // spotlight texture
                
                    g_device->SetTexture(g_spotlight_texture_desc.RegisterIndex, g_spotlight_texture);
                    g_device->SetSamplerState(g_spotlight_texture_desc.RegisterIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                    g_device->SetSamplerState(g_spotlight_texture_desc.RegisterIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
                    g_device->SetSamplerState(g_spotlight_texture_desc.RegisterIndex, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
                
                    
            // string texture
                
                    g_device->SetTexture(g_string_texture_desc.RegisterIndex, g_string_texture);
                    g_device->SetSamplerState(g_string_texture_desc.RegisterIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                    g_device->SetSamplerState(g_string_texture_desc.RegisterIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
                    g_device->SetSamplerState(g_string_texture_desc.RegisterIndex, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
                
                    g_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
                    
                    g_device->EndScene();
                
                    g_device->Present(NULL, NULL, NULL, NULL);
                
                    
            return true;
                }
                
                
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
                

                LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
                {
                    
            switch(msg)
                    {
                    
            case WM_DESTROY:
                        PostQuitMessage(0);
                        
            break;
                
                    
            case WM_KEYDOWN:
                        
            if(word_param == VK_ESCAPE)
                            DestroyWindow(hwnd);
                
                        
            break;
                    }
                
                    
            return DefWindowProc(hwnd, msg, word_param, long_param);
                }
                
                
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
                

                
            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
                {
                    
            if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_device))
                    {
                        MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
                        
            return 0;
                    }
                
                    
            if(! setup())
                    {
                        MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
                        
            return 0;
                    }
                
                    enter_msg_loop(display);
                
                    cleanup();
                    g_device->Release();
                
                    
            return 0;
                }

            setup函數執行下列功能:

            填充方形的頂點緩存

            編譯著像素色器

            創建像素色器

            讀取紋理

            設置投影矩陣,不使用光照

            取得采樣器(sampler)對象的句柄

            取得采樣器對象的描述


            display函數設置像素著色器,使用2個紋理,并且在渲染方格前設置他們對應的采樣器狀態。


            運行截圖:

             

            下載源程序


            posted on 2008-04-11 13:07 lovedday 閱讀(2762) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久久久国产日韩精品网站| 久久亚洲国产中v天仙www| 久久人人爽人人澡人人高潮AV | 69国产成人综合久久精品| 日本免费一区二区久久人人澡| 国产高清美女一级a毛片久久w | 麻豆一区二区99久久久久| 成人久久精品一区二区三区| 色综合合久久天天给综看| 久久精品国产亚洲av麻豆色欲| 99久久综合国产精品二区| 婷婷国产天堂久久综合五月| 72种姿势欧美久久久久大黄蕉| 亚洲精品无码久久毛片| 久久这里只有精品久久| 日韩精品久久久肉伦网站| 久久久久一本毛久久久| 精品免费tv久久久久久久| 国内精品久久久久影院亚洲| 国产成人精品久久亚洲| 久久久久亚洲精品无码蜜桃 | 曰曰摸天天摸人人看久久久| 色综合久久久久无码专区| 亚洲国产综合久久天堂| 久久精品免费网站网| 久久99国产精品一区二区| 色88久久久久高潮综合影院| 国产精品乱码久久久久久软件| 国产—久久香蕉国产线看观看| 99999久久久久久亚洲| 色综合久久久久综合体桃花网| 一级做a爰片久久毛片免费陪| 久久99久久成人免费播放| 国产精品成人无码久久久久久| a高清免费毛片久久| 久久精品国产亚洲av日韩| 欧美黑人激情性久久| 久久久噜噜噜www成人网| 国产精品免费福利久久| 国产精品久久久久影院嫩草| 精品无码久久久久久午夜|