在基于shader的D3D程序中实现2D面板

1623 篇文章 23 订阅
1277 篇文章 12 订阅
3D游戏中,很多东西都需要以2D的形式展现,比如人物的状态栏,物品栏等,那么如何才能在3D场景中放置它们呢?我在这里介绍一种通过简化变换过程而实现的方法.

    大家知道,一个模型顶点在显示到屏幕上,一共要经过4次变换,分别是世界变换,摄象机变换,投影变换以及视口变换.在世界变换中,我们通过一个仿射矩阵把这个顶点放置到世界的相应位置;在摄象机变换中,我们以摄象机作为原点把顶点放置到相应位置;而在投影变换中,若我们选择z = 1作为投影面,我们相当于把z = z的平面上的点映射到了z = 1上,比如点( x, y, z, z )就投影为( x / z, y / z, 1 );最后,我们又利用视口变换,把这个点映射到屏幕象素坐标上,如( 0, 0 )映射为( screenX / 2, screenY / 2 ).

    我说了这么多,无非就是想告诉大家,我们在把顶点传递后,会经过前三次变换映射到( -1, -1,  0 )以及( 1, 1, 1 )的立方体内( 视口变换暂时不去考虑 ),也就是说D3D的近截面从0开始.

    一张前景图,必然是遮挡所有3D实体与环境的东东,那么我们就可以知道在三次变换后的顶点的坐标设为( x, y , 0 ),注意-1<x,y<1,那么,如果我们不去执行三次变换,将模型坐标设为这样直接传给光栅器,就可以得到一个伪装的完成3次变换的顶点映射后的象素了.

    例如:我定义:

   //前景图的四个顶点以及相应索引
   VERTEX v1( D3DXVECTOR3( 0, 0, 0 ), D3DXVECTOR2( 0 ,1 ) );

   VERTEX v2( D3DXVECTOR3( 0, 0.6, 0 ), D3DXVECTOR2( 0 ,0 ) );
   VERTEX v3( D3DXVECTOR3( 0.4, 0, 0 ), D3DXVECTOR2( 1 ,1 ) );
   VERTEX v4( D3DXVECTOR3( 0.4, 0.6, 0 ), D3DXVECTOR2( 1 ,0 ) );
   那么如果不进行前三次变换,这个矩形的就会直接被映射到屏幕上变成一个正方形,为什么是正方形呢?这是因为如果在800*600的分辨率下,必须设置水平与垂直缩放值,他们的比值为4 : 3.

   本方法经测试有效,似乎在D3D中还有一种方法是通过把顶点位置声明设置为已变换,但是我想既然其他3D实体的顶点都需要进行变换的洗礼,那我还是如乡随俗吧... 

   在shader中,可以直接如下:

   void VS(float3 Pos : POSITION, float4 Color : COLOR, float3 normal : NORMAL, float2 texCoord : TEXCOORD0,
        out float4 oPosition : POSITION, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0,
        out float oFogExponent : TEXCOORD1 )
{
                     

   
    oPosition =float4( Pos, 1 );   //直接使用,不需要变换
    //oPosition = mul( float4( Pos, 1 ), matWorldViewProj );   


    float4 P = mul( float4( Pos, 1 ), matWorld );
    float3 No = normalize( mul( normal, matWorld ) );
  
    ComputeFogExponent( P.xyz, eyePos.xyz, oFogExponent );
  
    oColor = float4( 1, 0, 0, 1 );
   
    oTexCoord = texCoord;
   
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值