Microsoft DirectX 8.1 (C++) |
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.
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 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.
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 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.
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 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: