您的位置:首页 > 其它

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

2009-04-23 18:49 211 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: