Direct3D中的Shader是這樣的:
1. ASM Shader是最元老的也是DX8主要使用Shader
2. fxc編譯器可以同時編譯ASM,HLSL和fx腳本,其中HLSL和fx可以查看編譯后的GPU匯編代碼
3. D3D9中,fx是HLSL的一種渲染腳本,簡化了HLSL設(shè)置及常量綁定,并且附帶RenderStateBlock及設(shè)置
但只能用于制作簡單的Shader
4. DirectXSDK中有一個概念混淆:C++例子中的BasicHLSL使用的其實還是fx,HLSLwithoutEffects例子才是真正的純HLSL
5.fx與HLSL程序鑒別:
使用fx程序必定含有:D3DXCreateEffectXXX 系列函數(shù), ID3DXEffect對象,渲染中能看到SetTechnique,BeginPass,EndPass之類的字眼
使用純HLSL程序含有:D3DXCompileShader,ID3DXConstantTable對象,GetConstantByName,GetConstantDesc之類的字眼
6. 在fx中包含有 VertexShader,PixelShader代碼及profile,entry,RenderState設(shè)置及簡單的繪制過程(pass)。一次編譯后,VS,PS,Texture,Sampler及常量都是在ID3DXEffect對象中自動完成,無需手動設(shè)置。
7. HLSL可以將VS及PS代碼寫入1個.hlsl文件。注意,以下這種代碼可以在HLSL中編譯過,但實際沒有任何效果
1: sampler_state
2: {
3: Texture = <tex>;
4: MipFilter = LINEAR;
5: MinFilter = LINEAR;
6: MagFilter = LINEAR;
7: };
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
這點可以參考AMD RenderMonkey中只在shader中使用sampler而忽略texture。
8. fx中往shader設(shè)置紋理使用的是ID3DXBaseEffect::SetTexture下的這個函數(shù)
1: HRESULT SetTexture(
2: D3DXHANDLE hParameter,
3: LPDIRECT3DBASETEXTURE9 pTexture
4: );
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
但是在HLSL中,這點就變得很麻煩,需要手動設(shè)置,可以參考這篇文章
Shader代碼片段:
1: sampler Samp0 = sampler_state
2: {
3: Texture = <Tex0>;
4: MipFilter = LINEAR;
5: MinFilter = LINEAR;
6: MagFilter = LINEAR;
7: };
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
編譯HLSL代碼后得到ConstantTable,然后取出句柄:
1: ScalarHandle = pixelConstTable->GetConstantByName(0, "Scalar");
2:
3: Samp0Handle = pixelConstTable->GetConstantByName(0, "Samp0");
4:
5: Samp1Handle = pixelConstTable->GetConstantByName(0, "Samp1");
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
再從句柄取出symbol的描述:
1: UINT count;
2:
3: pixelConstTable->GetConstantDesc(Samp0Handle, & Samp0Desc, &count);
4:
5: pixelConstTable->GetConstantDesc(Samp1Handle, & Samp1Desc, &count);
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
通過上面的描述,將紋理變量的寄存器偏移作為紋理的stage
8. 優(yōu)化常量設(shè)置速度的方法一般就是根據(jù)字符串取出句柄,以后每次渲染時,只通過句柄設(shè)置。但I(xiàn)D3DXConstantTable最后還是通過
IDirect3DDevice9::SetPixelShaderConstantX 系列函數(shù)來實現(xiàn)的
1: HRESULT SetPixelShaderConstantF(
2: UINT StartRegister,
3: CONST float * pConstantData,
4: UINT Vector4fCount
5: );
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
9. HLSL將一段包含VS和PS代碼編譯完成后,將得到VS和PS兩個單獨的ID3DXConstantTable