像素着色器入门(龙书简单总结,DirectX 3D 9)
来源:互联网 发布:java项目开发视频云盘 编辑:程序博客网 时间:2024/06/04 08:04
一、像素着色器简介
像素着色器是在对每个像素进行光栅化处理期间运行在图形卡GPU上的一段程序。(不同于顶点着色器,Direct3D不会以软件运算方式来模拟像素着色器。)像素着色器实质上是取代固定功能流水线中的多重纹理(multitexturing)环节,而且赋予了我们直接操纵单个像素以及访问每个像素的纹理坐标的能力。这种对像素和纹理坐标直接访问的能力使得我们能够获得各种各样的特殊效果,例如多重纹理、景深(depth of field)、云彩模拟、火焰模拟以及比较复杂的阴影技术。
二、像素着色器的输入和输出
像素着色器的输入包括每个像素的颜色和纹理坐标,输出为计算所得的每个像素的颜色值。
每个像素的纹理坐标其实就是指定了纹理中将被映射到当前像素的纹理元的坐标(u , v)。在进入像素着色器之前,Direct3D先根据顶点颜色和顶点纹理坐标计算出每个像素的颜色和纹理坐标。输入像素着色器的颜色和纹理坐标对的个数由顶点着色器输出的颜色和纹理坐标对的个数决定。例如,如果一个顶点着色器输出 2 种颜色和 3 个纹理坐标对,则Direct3D将计算出每个像素的 2 种颜色值和 3 个纹理坐标对,并将这些输出结果输入像素着色器。我们需借助语义语法来将输入的颜色和纹理坐标映射为像素着色器程序中的变量。对于上述例子,我们可以写作:
struct PS_INPUT
{
vector c0 : COLOR0;
vector c1 : COLOR1;
float2 t0 : TEXCOORD0;
float2 t1 : TEXCOORD1;
float3 t2 : TEXCOORD2;
}
struct PS_OUTPUT
{
vector finalPixelColor : COLOR0;
}
三、使用像素着色器的步骤
(1)编写像素着色器程序
(2)编译像素着色器程序。
(3)创建一个LPDIRECT3DPIXELSHADER9接口对象,以表示经过编译的着色器代码的像素着色器。
(4)用SetPixelShader方法启用像素着色器。
(5)调用像素着色器的Release方法释放着色器。
接下来详细介绍每一步的具体操作:
1、编写像素着色器程序
// Globalssampler EarthTex;sampler GalaxyTex;// Structuresstruct PS_INPUT{ float2 earth : TEXCOORD0; float2 galaxy : TEXCOORD1;};struct PS_OUTPUT{ vector diffuse : COLOR0;};// MainPS_OUTPUT Main(PS_INPUT input){ // zero out members of output PS_OUTPUT output = (PS_OUTPUT)0; // sample appropriate textures vector b = tex2D(EarthTex, input.earth); vector s = tex2D(GalaxyTex, input.galaxy); // combine texel colors vector c = b * s; // increase the intensity of the pixel slightly c += 0.1f; // save the resulting pixel color output.diffuse = c; return output;}
在PS_INPUT结构体中说明输入像素着色器程序的数据格式,在PS_OUTPUT中说明像素着色器输出的数据格式,在Main方法中说明对像素进行的具体操作。
2、编译像素着色器程序
ID3DXBuffer* shader = 0;ID3DXBuffer* errorBuffer = 0;//对着色器程序进行编译HRESULT hr = D3DXCompileShaderFromFile(L"ps_multitex.txt",0, 0,"Main","ps_1_1",D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, &shader,&errorBuffer,&MultiCT);
3、获得指向IDirect3DPixelShader9接口的指针
HRESULT hr = g_pd3dDevice->CreatePixelShader((DWORD*)shader->GetBufferPointer(),&MultiPS);
4、启用像素着色器
g_pd3dDevice->SetPixelShader(MultiPS);
5、释放资源
调用Release()方法释放。
四、程序源码
程序简要说明:对一个矩形进行多重纹理贴图
像素着色器程序:
// Globalssampler EarthTex;sampler GalaxyTex;// Structuresstruct PS_INPUT{ float2 earth : TEXCOORD0; float2 galaxy : TEXCOORD1;};struct PS_OUTPUT{ vector diffuse : COLOR0;};// MainPS_OUTPUT Main(PS_INPUT input){ // zero out members of output PS_OUTPUT output = (PS_OUTPUT)0; // sample appropriate textures vector b = tex2D(EarthTex, input.earth); vector s = tex2D(GalaxyTex, input.galaxy); // combine texel colors vector c = b * s; // increase the intensity of the pixel slightly c += 0.1f; // save the resulting pixel color output.diffuse = c; return output;}
程序源码:
#include <Windows.h>#include <mmsystem.h>#include <d3dx9.h>#pragma warning( disable : 4996 ) // disable deprecated warning #include <strsafe.h>#pragma warning( default : 4996 )#include <d3dx9math.h>LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;LPDIRECT3DTEXTURE9 earthtexture = NULL;LPDIRECT3DTEXTURE9 galaxytexture = NULL;LPDIRECT3DPIXELSHADER9 MultiPS = 0;LPD3DXCONSTANTTABLE MultiCT = 0;D3DXHANDLE EatrhHandle = 0;D3DXHANDLE GalaxyHandle = 0;D3DXCONSTANT_DESC earthDesc;D3DXCONSTANT_DESC galaxyDesc;struct CUSTOMVERTEX{FLOAT x, y, z;FLOAT u0,v0;FLOAT u1,v1;};#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEX2)HRESULT InitD3D(HWND hWnd){// Create the D3D object.if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))return E_FAIL;// Set up the structure used to create the D3DDeviceD3DPRESENT_PARAMETERS d3dpp;ZeroMemory(&d3dpp, sizeof(d3dpp));d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16;// Create the D3DDeviceif (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice))){return E_FAIL;}return S_OK;}void CreateShader(){ID3DXBuffer* shader = 0;ID3DXBuffer* errorBuffer = 0;//对着色器程序进行编译HRESULT hr = D3DXCompileShaderFromFile(L"ps_multitex.txt",0, 0,"Main","ps_1_1",D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, &shader,&errorBuffer,&MultiCT);//创建像素着色器hr = g_pd3dDevice->CreatePixelShader((DWORD*)shader->GetBufferPointer(),&MultiPS);shader->Release();}void GetHandles(){EatrhHandle = MultiCT->GetConstantByName(0, "EarthTex");GalaxyHandle = MultiCT->GetConstantByName(0, "GalaxyTex");UINT count;MultiCT->GetConstantDesc(EatrhHandle, &earthDesc, &count);MultiCT->GetConstantDesc(GalaxyHandle, &galaxyDesc, &count);MultiCT->SetDefaults(g_pd3dDevice);}bool CreateTecture(){if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,L"galaxy.jpg",&galaxytexture)))return false;if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,L"earth.jpg",&earthtexture)))return false;return true;}HRESULT CreateBuffer(){CUSTOMVERTEX vertices[] = {{ -10.0f, -10.0f, 0.0f, 0,1,0,1},{ -10.0f, 10.0f, 0.0f, 0,0,0,0 },{ 10.0f, 10.0f, 0.0f, 1,0,1,0},{ 10.0f, -10.0f, 0.0f, 1,1,1,1},};// 创建顶点缓存if (FAILED(g_pd3dDevice->CreateVertexBuffer(sizeof(vertices),0, D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT, &g_pVB, NULL))){return E_FAIL;}VOID* pVertices;if (FAILED(g_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0)))return E_FAIL;memcpy(pVertices, (void*)vertices, sizeof(vertices));g_pVB->Unlock();// 创建索引缓存WORD indices[] = {0,1,2,0,2,3};if( FAILED( g_pd3dDevice->CreateIndexBuffer( sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL ) ) ){return E_FAIL;}VOID* pIndices = NULL;if(FAILED(g_pIB->Lock(0, sizeof(indices), (void**)&pIndices,0)))return E_FAIL;memcpy(pIndices,(VOID*)indices, sizeof(indices));g_pIB->Unlock();return S_OK;}VOID SetupMatrices(){D3DXVECTOR3 position( 0, 0, -20);D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);D3DXMATRIX V;D3DXMatrixLookAtLH(&V, &position, &target, &up);g_pd3dDevice->SetTransform(D3DTS_VIEW, &V);//D3DXMatrixPerspectiveFovLH()函数中的最远、最近距离为相对于视点的距离(即vEyePt中的距离)D3DXMATRIXA16 matProj;D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 1000.0f);g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);}VOID Cleanup(){if( earthtexture != NULL ) earthtexture->Release();if( galaxytexture != NULL ) galaxytexture->Release();if (g_pVB != NULL)g_pVB->Release();if(g_pIB != NULL)g_pIB->Release();if (g_pd3dDevice != NULL)g_pd3dDevice->Release();if (g_pD3D != NULL)g_pD3D->Release();if(MultiPS != NULL)MultiPS->Release();if(MultiCT != NULL)MultiCT->Release();}VOID Render(){CreateShader();GetHandles();CreateTecture();g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);// Begin the sceneif (SUCCEEDED(g_pd3dDevice->BeginScene())){SetupMatrices();g_pd3dDevice->SetPixelShader(MultiPS);g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);g_pd3dDevice->SetIndices(g_pIB);g_pd3dDevice->SetTexture(earthDesc.RegisterIndex, earthtexture);g_pd3dDevice->SetSamplerState(earthDesc.RegisterIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);g_pd3dDevice->SetSamplerState(earthDesc.RegisterIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);g_pd3dDevice->SetSamplerState(earthDesc.RegisterIndex, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);g_pd3dDevice->SetTexture(galaxyDesc.RegisterIndex, galaxytexture);g_pd3dDevice->SetSamplerState(galaxyDesc.RegisterIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);g_pd3dDevice->SetSamplerState(galaxyDesc.RegisterIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);g_pd3dDevice->SetSamplerState(galaxyDesc.RegisterIndex, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,4,0,2);g_pd3dDevice->EndScene();}g_pd3dDevice->Present(NULL, NULL, NULL, NULL);}//-----------------------------------------------------------------------------// Name: MsgProc()// Desc: The window's message handler//-----------------------------------------------------------------------------LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){switch (msg){case WM_DESTROY:Cleanup();PostQuitMessage(0);return 0;}return DefWindowProc(hWnd, msg, wParam, lParam);}//-----------------------------------------------------------------------------// Name: WinMain()// Desc: The application's entry point//-----------------------------------------------------------------------------INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT){UNREFERENCED_PARAMETER(hInst);// Register the window classWNDCLASSEX wc ={sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,GetModuleHandle(NULL), NULL, NULL, NULL, NULL,L"D3D Tutorial", NULL};RegisterClassEx(&wc);// Create the application's windowHWND hWnd = CreateWindow(L"D3D Tutorial", L"D3D Tutorial 03: MultiTexture",WS_OVERLAPPEDWINDOW, 100, 100, 700, 700,NULL, NULL, wc.hInstance, NULL);// Initialize Direct3Dif (SUCCEEDED(InitD3D(hWnd))){// Create the scene geometryif (SUCCEEDED(CreateBuffer())){// Show the windowShowWindow(hWnd, SW_SHOWDEFAULT);UpdateWindow(hWnd);// Enter the message loopMSG msg;ZeroMemory(&msg, sizeof(msg));while (msg.message != WM_QUIT){if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);}elseRender();}}}UnregisterClass(L"D3D Tutorial", wc.hInstance);return 0;}
运行效果如下:
原始图片如下:
阅读全文
0 0
- 像素着色器入门(龙书简单总结,DirectX 3D 9)
- 顶点着色器入门(龙书简单总结 DirectX 3D 9)
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(三)像素着色器
- 像素着色器入门
- DirectX 3D_基础之像素着色器 多重纹理 像素着色器的输入和输出 HLSL采样器对象
- Introduction to 3D Game Programming with DirectX 11学习笔记 6 Direct3D中的绘制(二)顶点着色器
- DirectX 3D_基础之效果框架 手法和路径 HLSL的内置对象(纹理对象 采样器对象与采样器状态 顶点着色器对象和像素着色器对象)效果文件中的设备状态
- HLSL像素着色器
- DirectX11 像素着色器
- 两天学会DirectX 3D之入门
- shader入门 《顶点着色器 与 片段(像素)着色器》概念
- DirectX.9.0.3D游戏开发总结
- DirectX 9高层着色语言介绍3——语言基础(2)
- DirectX 9高层着色语言介绍4——语言基础(3)
- DirectX 9高层着色语言介绍3 —— 语言基础(2)
- 5.11 像素着色器阶段
- OpenGL ES像素着色器
- DirectX 的入门总结
- Android PopupWindow怎么合理控制弹出位置(showAtLocation)
- 数组中出现次数超过一半的数字
- 全排列及相关扩展算法(三)——利用中介数求排列在字典序排位算法
- cocos2d-x包括3.14.1版本之后的安卓移植
- Android自定义View之popupwindow进阶封装:高仿ios “item动画弹出”效果的popupwindow。
- 像素着色器入门(龙书简单总结,DirectX 3D 9)
- 一次使用Eclipse Memory Analyzer分析Tomcat内存溢出
- 浙江中医药大学暑期训练测试赛十 英雄无敌3(2) 数学公式
- spring核心容器 spring container 详解
- PAT 乙级 1042.字符统计(20)
- eclipse/myeclipse 中,如何删除已经下载过的插件(举例:删除scala ide)
- 走进VR开发世界
- pom配置之:<distributionManagement>snapshot快照库和release发布库
- 浅谈ARM上的Ptrace