關於如何獲取深度buffer的問題,網上好多介紹使用D3DFMT_D16_LOCKABLE的方法創建深度texture,然後lock之,但是由於好多N卡不支持D3DFMT_D16_LOCKABLE,造成該方法無法使用。本文給出一種方法,通過在shader中直接計算深度信息,輸出到普通的texture上,然後就可以對該texture進行lock之類的操作。爲了簡單起見,該方法直接將深度信息寫到backbuffer的Alaph通道中,實際使用時可以創建一個通用的rt來實現。下面是對應的vs和ps:
float4x4 ViewProjMatrix;
float4 Blue = {0.0f, 0.0f, 1.0f, 1.0f};
struct VS_INPUT
{
float4 position : POSITION;
};
struct VS_OUTPUT
{
float4 position : POSITION;
float4 position1 : TEXCOORD0;
float4 diffuse : TEXCOORD1;
};
VS_OUTPUT Main(VS_INPUT input)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.position = mul(input.position, ViewProjMatrix);
output.position1 = output.position;
output.diffuse = Blue;
return output;
}
float4 ps_main(
float4 inPosition: TEXCOORD0,
float4 inDiffuse: TEXCOORD1
) : COLOR0
{
float4 outtest;
outtest.xyz = inDiffuse.xyz;
float1 ztest = inPosition.z;
float1 wtest = inPosition.w;
outtest.w = ztest/wtest;
return outtest;
}
此處在vs中將position點傳到ps中而不是在vs中直接賦值,是爲了能夠更好的得到z-buffer插值的正確性。
下圖兩幅圖是物體距離攝像機不同位置時的alpha通道的顯示效果,可以看出圖一距離攝像機更遠。可以通過在Photoshope中查看其灰度值發現圖一的灰度值比圖二的大。
圖一
圖二