Shader技术属于GPU的渲染技术,其相应语言是高级着色器语言(High Level Shader Language 简称HLSL)。HLSL主要作用为将一些复杂的图像处理快速而又有效率地在显卡上完成。
在DirectX中有两种Shader,顶点着色器Vertex Shader (vs)和像素着色器Pixel Shader (ps)。能够实现VS和PS的显卡的图形处理流水线被称作为是可编程的。VS实际代替了传统图形渲染流水线里的T&L部分,其以顶点为计算单位,负责处理世界坐标中的顶点信息,可以处理光照、阴影、坐标变换、法向量等等。PS代替了传统图形渲染流水线中的光栅化部分,比如纹理贴图等, 其以像素为计算单位,用来操纵物体表面的色彩和外观。
1.Shader基本框架
Shader文件的后缀名为.fx,可在文件里编写如下代码:
首先定义一颜色纹理变量:texture ColorMap,这是Shader与C++的接口.
定义一采样变量,例:
sampler ColorSampler = sampler_state
{
texture = (ColorMap);
MipFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
设计一顶点格式,例:
struct VSOutShadow
{
float4 vPosition : POSITION;
float2 vTexcoord : TEXCOORD0;
float diff : TEXCOORD1;
};
定义全局变量:
shared uniform float4x4 World: World //世界变换矩阵
shared uniform float4x4 View: View; //观察矩阵
shared uniform float4x4 Projection : PROJECTION; //投影矩阵
顶点着色函数,例:
VSOutShadow VS_Scene( float4 inPosition : POSITION, float2 texcoord:TEXCOORD0)
{
VSOutShadow OUT = (VSOutShadow)0;
//使用传入的参数计算顶点的相关信息
inPosition = mul( inPosition, World );//世界变换
OUT.vPosition = mul( inPosition, View );//摄像机变换
OUT.vPosition = mul( OUT.vPosition, Projection );//投影变换
。。。。。。。。。。
。。。。。。。。。。
return OUT;
}
像素着色函数,例:
float4 PS_Scene( VSOutShadow IN) : COLOR0
{
float4 color= tex2D(ColorSampler,IN.vTexcoord);
//使用传入的参数设置像素的着色
return color;
}
定义技术:
technique techScene
{
pass p0
{
VertexShader = compile vs_2_0 VS_Scene();//对应顶点着色函数
PixelShader = compile ps_2_0 PS_Scene();//对应像素着色函数
}
}
2.在C++应用shader
先设计一EffectManager类,并提供一接口,用于根据传入的.fx 文件的路径名创建一ID3DXEffect类型的指针m_pShader并使其指向该文件,函数返回m_pShader,可用m_pShader调用相应函数设置shader里的变量值,例如:
m_pShader->SetFloat("ambient",m_sight);
m_pShader->SetMatrix("World",&finalWorldMat);
其中ambient,World为shader里的变量,m_sight,finalWorldMat为c++程序里的变量,设置特定类型的变量需调用相应的函数。
设置技术:m_pShader->SetTechnique("techScene")
techScene为shader里已定义的技术。
着色,例:
UINT passnum=0;
m_pShader->Begin(&passnum,0);
for(UINT pass=0;pass<passnum;pass++)
{
m_pShader->BeginPass(pass);
_Render();//完成相关操作
m_pShader->EndPass();
}
m_pShader->End();
_Render()里需设置纹理,例:m_pShader->SetTexture("ColorMap",m_pMeshTextures[i]);
提交: m_pShader->CommitChanges();