?/TD>
Microsoft DirectX 9.0

Pixel Shader Examples


This section contains three pixel shader examples. Each example builds on the previous example by adding a piece of pixel shader functionality.

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 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 9.0
//   media from the SDK download.
TCHAR        strTexturePath[512];
DXUtil_FindMediaFileCb( strTexturePath, sizeof(strTexturePath), 
                        _T("DX5_Logo.bmp") );

LPDIRECT3DTEXTURE9      m_pTexture0;
D3DUtil_CreateTexture( m_pd3dDevice, strTexturePath, 
                       &m_pTexture0, D3DFMT_R5G6B5 );

// Create the pixel shader.
TCHAR        strShaderPath[512];
DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath), 
                        _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.

LPD3DXBUFFER pCode;                  // buffer with the assembled shader code
LPD3DXBUFFER pErrorMsgs;             // buffer with error messages
LPDIRECT3DPIXELSHADER9 m_pPixelShader;
D3DXAssembleShaderFromFile( strShaderPath, 0, NULL, &pCode, NULL );
m_pd3dDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(),
                                          &m_pPixelShader );
m_pd3dDevice->SetPixelShader( m_pPixelShader );

// Load the texture and render the output pixels.
m_pd3dDevice->SetTexture( 0, m_pTexture0 );	
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );

// Contents of the file "PixelShader2.txt"
// Applies a texture map to object vertices.
ps_1_1      // Version instruction must be first in the file.
tex t0      // Declare texture register t0
            // which is loaded from stage 0.
mov r0, t0  // Move the texture register data(t0) to the 
            // output register(r0).

The resulting image is shown in the following example.

Texture map 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 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 9.0 media 
//   from the SDK download.
// Create a texture. This file is in the DirectX 9.0
//   media from the SDK download.
TCHAR        strTexturePath[512];
DXUtil_FindMediaFileCb( strTexturePath, sizeof(strTexturePath), 
                        _T("DX5_Logo.bmp") );

LPDIRECT3DTEXTURE9      m_pTexture0;
D3DUtil_CreateTexture( m_pd3dDevice, strTexturePath, 
                       &m_pTexture0, D3DFMT_R5G6B5 );

// Create the pixel shader.
TCHAR        strShaderPath[512];
DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath), 
                        _T("PixelShader3.txt") );

LPD3DXBUFFER pCode;                  // buffer with the assembled shader code
LPD3DXBUFFER pErrorMsgs;             // buffer with error messages
LPDIRECT3DPIXELSHADER9 m_pPixelShader;
D3DXAssembleShaderFromFile( strShaderPath, 0, NULL, &pCode, NULL );
m_pd3dDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(),
                                          &m_pPixelShader );
m_pd3dDevice->SetPixelShader( m_pPixelShader );

// Load the texture and render the output pixels.
m_pd3dDevice->SetTexture( 0, m_pTexture0 );
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );

// Contents of the file "PixelShader3.txt"
ps_1_1          // version instruction
tex t0          // declare texture register t0, 
                // to 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.

vertex colors?img alt="Texture" src="../../../../Art/PSEx2.jpg">

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.

Blended vertex colors and texture

Blend Two Textures Using a Color Value

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:

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 texture. This file is in DirectX 9.0 media from 
//   the SDK download.
TCHAR        strTexturePath[512];
LPDIRECT3DTEXTURE9      m_pTexture0, m_pTexture1;

DXUtil_FindMediaFileCb( strTexturePath, sizeof(strTexturePath), 
                        _T("DX5_Logo.bmp") );
D3DUtil_CreateTexture( m_pd3dDevice, strTexturePath, 
                       &m_pTexture0, D3DFMT_R5G6B5 );

DXUtil_FindMediaFileCb( strTexturePath, sizeof(strTexturePath), 
                        _T("snow2.jpg") );
D3DUtil_CreateTexture( m_pd3dDevice, strTexturePath, 
                       &m_pTexture0, D3DFMT_R5G6B5 );

					   
// Create the pixel shader.
TCHAR        strShaderPath[512];
DXUtil_FindMediaFileCb( strShaderPath, sizeof(strShaderPath), 
                        _T("PixelShader4.txt") );

LPD3DXBUFFER pCode;                  // buffer with the assembled shader code
LPD3DXBUFFER pErrorMsgs;             // buffer with error messages
LPDIRECT3DPIXELSHADER9 m_pPixelShader;
D3DXAssembleShaderFromFile( strShaderPath, 0, NULL, &pCode, NULL );
m_pd3dDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(),
                                          &m_pPixelShader );
m_pd3dDevice->SetPixelShader( m_pPixelShader );

// Load the textures stages.
m_pd3dDevice->SetTexture( 0, m_pTexture0 );
m_pd3dDevice->SetTexture( 1, m_pTexture1 );  // Use a second stage.

m_pd3dDevice->SetStreamSource( 0, m_pQuadVB, sizeof(CUSTOMVERTEX) );
m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
m_pd3dDevice->SetPixelShader( m_pPixelShader );
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );

// Contents of the file "PixelShader4.txt"
ps_1_1              // Pixel shader version.
tex t0              // Texture register t0 is loaded from stage 0.
tex t1              // Texture register t1 is loaded from stage 1.
mov r1, t1          // Move texture t1 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:

Texture1?img alt="Texture2" src="../../../../Art/PSsnow2.jpg">?img alt="Blending both textures" src="../../../../Art/PSEx4.jpg">



© 2002 Microsoft Corporation. All rights reserved.