struct VS_INPUT
{
// We only need 2d screen position, that's all.
float2 pos : POSITION;
};
struct VS_OUTPUT
{
float4 pos : POSITION;
float3 texCoord : TEXCOORD0;
};
VS_OUTPUT VS_Sky(VS_INPUT In)
{
VS_OUTPUT Out;
Out.pos = float4(In.pos.xy, 0, 1);
// Also negate xy because the cube map is for MDX (left handed)
// and is upside down
Out.texCoord = mul(float4(-In.pos, scale, 0), viewInverse).xyz;
// And fix rotation too (we use better x, y ground plane system)
Out.texCoord = float3( -Out.texCoord.x*1.0f, -Out.texCoord.z*0.815f, -Out.texCoord.y*1.0f);
return Out;
}
// VS_TSky(..)
float4 PS_Sky(VS_OUTPUT In) : COLOR
{
float4 texCol = ambientColor * texCUBE(diffuseTextureSampler, In.texCoord);
return texCol;
}
// PS_SkyCubeMap(.)
technique TSky
{
pass P0
{
ZEnable = false;
VertexShader = compile vs_1_1 VS_Sky();
PixelShader = compile ps_1_1 PS_Sky();
}
// pass P0
} // technique
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->///天空盒VS////////////////////////////////////////
struct VS_IN
{
float3 ObjPos : POSITION;
};
struct VS_OUT
{
float4 ProjPos : POSITION;
float3 texCoord : TEXCOORD0;
};
float4x4 matView : register(c64);
float4x4 matProj : register(c68);
VS_OUT main( VS_IN In )
{
// 如果視“天空盒”爲一個模型,本應該對其進行matView*matProj變換
// 現在對texCoord(即用於採樣的方向向量)進行matView的反向旋轉,效果等同於對所謂“天空盒”模型進行matView變換
VS_OUT Out;
float4 vPosition = float4(In.ObjPos,1.0f); //不乘View矩陣,讓4個頂點的位置總是保持和攝像機的相對位置不變
Out.ProjPos = mul( vPosition, matProj); //得到投影后的頂點位置
Out.texCoord = mul(matView, float4(In.ObjPos,0.0f)).xyz; //用matView的逆對In.ObjPos進行變換,起到旋轉天空盒的效果
return Out;
}
///天空盒PS////////////////////////////////////////
struct PS_IN
{
float3 texCoord : TEXCOORD0;
};
samplerCUBE g_SkyBox : register(s0);
float4 main( PS_IN In ) : COLOR
{
return texCUBE(g_SkyBox, In.texCoord);
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->{ //創建頂點聲明
D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
D3DDECL_END()
};
GetD3DDevice()->CreateVertexDeclaration( decl, &m_pVertexDeclaration );
}
{ //加載VertexBuffer
GetD3DDevice()->CreateVertexBuffer( sizeof(Vertex)*4, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL);
float lx = 50.0f; // lx應>=lz*tg(FOVX/2)=lz*tg(FOVY/2)*Aspect
float ly = 50.0f; // ly應>=lz*tg(FOVY/2)
float lz = 50.0f; // lz應在Zn到Zf之間
Vertex vertex[4] = {
{{-lx, -ly, lz}},
{{-lx, ly, lz}},
{{ lx, -ly, lz}},
{{ lx, ly, lz}},
};
void* pData = NULL;
m_pVertexBuffer->Lock(0, sizeof(Vertex)*4, &pData, D3DLOCK_NOOVERWRITE);
if(pData)
{
for(int i=0;i<4;i++)
{
((Vertex*)pData)[i] = vertex[i];
}
m_pVertexBuffer->Unlock();
}
}
其實如果你願意只用3個頂點也可以只要那個三角形能擋住攝像機(截穿視域體)就夠了,至於頂點的數據也可以設置成投影空間的,這樣就不用預先知道關於投影的參數,在VS中乘以matProj的逆反算得到vPosition,再乘以matView的逆得到texCoord