?/TD> |
Microsoft DirectX 9.0 |
This section contains three pixel shader examples. Each example builds on the previous example by adding a piece of 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 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.
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.
?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.
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:
?img alt="Texture2" src="../../../../Art/PSsnow2.jpg">?img alt="Blending both textures" src="../../../../Art/PSEx4.jpg">