Pixel Shader Examples

DirectX8

Microsoft DirectX 8.1 (C++)

Pixel Shader Examples

The topic Create a Pixel Shader provides an example of how to use a pixel shader to apply a single diffuse color. The following are examples of other pixel shader functions. Each example builds on the previous example by adding a piece of additional pixel shader functionality.

  • Apply a Texture Map
  • Blend a Diffuse Vertex Color with a Texture
  • Blend Two Textures Using a Constant Color
  • Apply a Texture Map

    This example applies a texture map to a plane. The differences between this example and the previous example are as follows:

    • The vertex data structure and the Flexible Vertex Format (FVF) macro include texture coordinates. The vertex data includes u,v data. The vertex data no longer needs diffuse color because the pixel colors will come from the texture map.
    • The texture is linked to texture stage 0 with SetTexture. Because the previous example did not use a texture, there was no SetTexture method used.
    • The shader uses the t0 texture register instead of the v0 diffuse color register.

     

    The sample code follows:

    // Define vertex data structure.
    struct CUSTOMVERTEX
    {
        FLOAT x, y, z;
        FLOAT u1, v1;
    };
    
    // Define corresponding FVF macro. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX|D3DFVF_TEXCOORDSIZE2(0)) // Create vertex data with position and texture coordinates. static CUSTOMVERTEX g_Vertices[]= { // x y z u1 v1 { -1.0f, -1.0f, 0.0f, 0, 1, }, { 1.0f, -1.0f, 0.0f, 1, 1, }, { 1.0f, 1.0f, 0.0f, 1, 0, }, { -1.0f, 1.0f, 0.0f, 0, 0, }, // v1 is flipped to meet the top down convention in Windows // the upper left texture coordinate is (0,0) // the lower right texture coordinate is (1,1). }; // Create a texture. This file is in the DirectX 8.1 media from the SDK download. TCHAR strPath[512]; DXUtil_FindMediaFile( strPath, _T("DX5_Logo.bmp")); LPDIRECT3DTEXTURE8 m_pTexture0; D3DUtil_CreateTexture( m_pd3dDevice, strPath, &m;_pTexture0, D3DFMT_R5G6B5 ); // Create the pixel shader. DXUtil_FindMediaFile( strPShaderPath, _T("PixelShader2.txt") );

    This function is a helper function used by the Sample Framework. The sample framework is the foundation on which many of the samples are built.

    D3DXAssembleShaderFromFile( strPShaderPath, 0, NULL, &pCode;, NULL );
    m_pd3dDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(),&m;_hPixelShader );
    
    // Load the texture and render the output pixels.
    m_pd3dDevice->SetTexture( 0, m_pTexture0 );		// load TSS0 from the texture
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
    
    Contents of the file "PixelShader2.txt"
    // Applies a texture map to object vertices.
    ps.1.0                 // Version instruction must be first in the file.
    tex t0                 // Declare texture register t0, which will be loaded from Texture Stage 0. 
    mov r0, t0             // Move the contents of the texture register (t0) to the output register (r0).
    

    The resulting image is shown in the following example.



    Blend a Diffuse Vertex Color with a Texture

    This example blends or modulates the colors in a texture map with the vertex colors. The differences between this example and the previous example are as follows:

    • The vertex data structure, the FVF macro, and the vertex data include diffuse color.
    • The shader file uses the multiply instruction (mul) to blend or modulate the texture colors with the vertex diffuse color.

    The texture create and load code is the same. It is included here for completeness.

    struct CUSTOMVERTEX
    {
        FLOAT x, y, z;
        DWORD color1;
        FLOAT tu1, tv1;
    };
    
    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE2(0))
    
    static CUSTOMVERTEX g_Vertices[]=
    {
        //  x      y     z     diffuse     u1    v1
        { -1.0f, -1.0f, 0.0f, 0xffff0000, 0, 1, }, // red
        {  1.0f, -1.0f, 0.0f, 0xff00ff00, 1, 1, }, // green
        {  1.0f,  1.0f, 0.0f, 0xff0000ff, 1, 0, }, // blue
        { -1.0f,  1.0f, 0.0f, 0xffffffff, 0, 0, }, // white
        // v1 is flipped to meet the top down convention in Windows
        // the upper left texture coordinate is (0,0)
        // the lower right texture coordinate is (1,1). 
    };
    
    // Create a texture. This file is in the DirectX 8.1 media from the SDK download.
    TCHAR  strPath[512];
    DXUtil_FindMediaFile( strPath, _T("DX5_Logo.bmp"));
    LPDIRECT3DTEXTURE8      m_pTexture0;
    D3DUtil_CreateTexture( m_pd3dDevice, strPath, &m;_pTexture0, D3DFMT_R5G6B5 );
    
    // Create the pixel shader.
    DXUtil_FindMediaFile( strPShaderPath, _T("PixelShader3.txt") );
    D3DXAssembleShaderFromFile( strPShaderPath, 0, NULL, &pCode;, NULL );
    m_pd3dDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(),&m;_hPixelShader );
    
    // Load the texture and render the output pixels.
    m_pd3dDevice->SetTexture( 0, m_pTexture0 );		// load TSS0 from the texture
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
    
    Contents of the file "PixelShader3.txt"
    ps.1.0          // version instruction
    tex t0          // declare texture register t0 which will be loaded from Texture Stage 0 
    mul r0, v0, t0  // v0*t0, then move to r0
    

    The inputs to the shader are shown in the following example. The first image shows the vertex colors. The second image shows the texture map.

    The resulting image is shown in the following example. It shows the output, which is a blend of the vertex color and the texture image.



    Blend Two Textures Using a Constant Color

    This example blends two texture maps, using the vertex color, to determine how much of each texture map color to use. The differences between this example and the previous example are as follows:

    • The vertex data structure, the FVF macro, and the vertex data include a second set of texture coordinates because there is a second texture. SetTexture is also called twice, using two texture stage states.
    • The shader file declares two texture registers and uses the linear interpolate (lrp) instruction to blend the two textures. The values of the diffuse colors determine the ratio of texture0 to texture1 in the output color.

    Here is the sample code.

    struct CUSTOMVERTEX
    {
        FLOAT x, y, z;
    	DWORD color;
        FLOAT tu1, tv1;
        FLOAT tu2, tv2;             // a second set of texture coordinates
    };
    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3D_FVF_DIFFUSE|D3DFVF_TEX2|D3DFVF_TEXCOORDSIZE4(0))
    
    static CUSTOMVERTEX g_Vertices[]=
    {
        //  x      y     z     color       u1    v1    u2    v2
        { -1.0f, -1.0f, 0.0f, 0xff0000ff, 1.0f, 1.0f, 1.0f, 1.0f },
        { +1.0f, -1.0f, 0.0f, 0xffff0000, 0.0f, 1.0f, 0.0f, 1.0f },
        { +1.0f, +1.0f, 0.0f, 0xffffff00, 0.0f, 0.0f, 0.0f, 0.0f },
        { -1.0f, +1.0f, 0.0f, 0xffffffff, 1.0f, 0.0f, 1.0f, 0.0f },
    };
    
    // Create a texture. This file is in the DirectX 8.1 media from the SDK download.
    TCHAR  strPath[512];
    LPDIRECT3DTEXTURE8      m_pTexture0, m_pTexture1;
    DXUtil_FindMediaFile( strPath, _T("DX5_Logo.bmp"));
    D3DUtil_CreateTexture( m_pd3dDevice, strPath, &m;_pTexture0, D3DFMT_R5G6B5 );
    DXUtil_FindMediaFile( strPath, _T("snow2.jpg"));
    D3DUtil_CreateTexture( m_pd3dDevice, strPath, &m;_pTexture1, D3DFMT_R5G6B5 );
    
    // Load the textures stages.
    m_pd3dDevice->SetTexture( 0, m_pTexture0 );
    m_pd3dDevice->SetTexture( 1, m_pTexture1 );        // Use a second texture stage.
    
    m_pd3dDevice->SetStreamSource( 0, m_pQuadVB, sizeof(CUSTOMVERTEX) );
    m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
    m_pd3dDevice->SetPixelShader( m_hPixelShader );
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
    
    Contents of the file "PixelShader5.txt"
    ps.1.0              // pixel shader version
    tex t0              // texture register t0 is loaded from texture stage 0
    tex t1              // texture register t1 is loaded from texture stage 1
    mov r1, t1          // move texture register1 into output register r1
    lrp r0, v0, t0, r1  // linearly interpolate between t0 and r1 by a proportion 
                        // specified in v0 
    

    The resulting output is as follows: