posts - 225, comments - 62, trackbacks - 0, articles - 0
   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

使用4个顶点+CubeMap渲染天空盒

Posted on 2010-10-20 23:18 魔のkyo 阅读(1231) 评论(0)  编辑 收藏 引用
以前我的理解天空盒是一个盒子形状的模型(8个顶点,6个面),当然确实也可以这么做,不过今天自己实现了一个天空盒,发现只用4个顶点(1个面)也是可以的
///天空盒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);
}

//创建顶点声明
    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(0sizeof(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
只有注册用户登录后才能发表评论。