2012-05-28 61 views
0

我一直在使用Direct3D开发自己的3D引擎。这很好,直到我遇到世界观和投影矩阵的问题。我使用的是我曾工作过的项目中的代码,但不在项目中。 所以我决定使用Direct3D的功能D3DXMatrixLookAtLH和D3DXMatrixPerspectiveFovLH。Direct3D WVP拉伸问题

这给出了一个工作矩阵,但是如果通过旋转或平移相机,我将几何图形移动到靠近屏幕边缘的位置,它会在水平轴上延伸整个对象,现在我不确定这是否正确或不。

Cube在屏幕的中间看起来正常: Normal Cube

但如果我把它移动到一边,它开始伸展: Stretched cube

这是视矩阵,我在这样一个得到case:

-0.81964797 -0.017183444 -0.57260966 0.00000000 
0.00000000 0.99954993 -0.029995499 0.00000000 
0.57286739 -0.024585750 -0.81927919 0.00000000 
-1.1457349 0.049171507  1.6385586 1.0000000 

我还注意到,在应用程序中的WVP矩阵和着色器接收到的矩阵之间会发生转置。我使用memcpy来获取它在CBuffer,所以这应该不是问题) 这不是一个大问题,我只是在它发送之前转置它,但我想知道这是否是常见的。

这是我的着色器:

cbuffer WVP :cb0 
{ 
    float4x4 WVP; 
}; 


struct VOut 
{ 
    float4 position : SV_POSITION; 
    float4 color : COLOR; 
}; 

VOut VShader(float3 position : POSITION, float4 color : COLOR) 
{ 
    VOut output; 

    output.position = mul(float4(position, 1.0f), WVP); 

    output.color = color; 

    return output; 
} 


float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET 
{ 
    return color; 
} 

这是代码在发生的每帧根据输入更新视矩阵:

// reset the vectors so the changes don't stack 
vcPos.Set(x, y, z); 
vcDir.Set(0.0f, 0.0f, -1.0f); 

// Rotate the dir vector 
Matrix3D m; 
m.Rota(Looky/100, 0.0f, Lookx/100); 
vcDir.RotateWith(m); 

// add the pos to the dir vector so it points to in a direction rather then a point in the world 
vcDir += vcPos; 

// Set and get the View matrix 
g_pDevice->SetViewMatrix(vcRight, vcUp, vcDir, vcPos); 
g_pDevice->GetViewProjMatrix(&g_mView, NULL); 

// Multiply them 
g_mWVP = g_mWorld * g_mView * g_mProj; 

// Transpose them so the shader tranposes them back. 
Transpose(&g_mWVP); 

而这背后的幕后部分它:

查看:

D3DXMatrixLookAtLH(&m_mView, &D3DXVECTOR3(vcPos.x, vcPos.y, vcPos.z), 
        &D3DXVECTOR3(vcDir.x, vcDir.y, vcDir.z), &D3DXVECTOR3(vcUp.x, vcUp.y, vcUp.z)); // The .x/.y/.z has to do with some compatability stuff 

PROJ:

D3DXMatrixPerspectiveFovLH(&m_mProj, FOV, Aspect, m_fNear, m_fFar); // Straight 
forward 

D3DXMatrixPerspectiveFovLH(&m_mProj, 90.0, Aspect, 0.1f, 100.0f); // With values 

UPDATE2:新的信息全部重新编写

UPDATE3:我在与视矩阵,也许是投影的问题。世界矩阵工作正常。

UPDATE4:

改变一些更多的代码后,我现在拥有的东西,似乎是工作! 我现在唯一的问题是拉伸到一边。

+0

我认为设置和修改您的模型/世界,视图和投影矩阵的代码可能与您的像素着色器代码更相关 – Necrolis

+0

@Necrolis添加了代码,我为最终矩阵添加了着色器代码得到转置 – Stardidi

回答

0

您是否确定要将翻译矩阵乘以翻译矩阵的顺序?我的意思是,如果你先翻译,然后缩放,结果将是一个拉伸的网格。你必须确保按顺序进行。如果你想要一个网格围绕自己的轴旋转,你首先要旋转然后翻译。如果你想让网格在物体周围“轨道化”,首先需要将它转化为物体周围轨道的距离,然后旋转,然后将其转换为物体位置。

反正你提到的拉伸,所以我猜这可能是因为你先翻译然后缩放:

worldMatrix = translate * scale; // This will cause your mesh to stretch 

worldMatrix = scale * translate; // this will cause your mesh to scale correctly 

要翻译第一的唯一情况是,当你不结垢,和你希望你的物体在另一个物体周围“轨道”

+0

那么世界矩阵正常工作。翻译和旋转(尚未测试/使用缩放比例) 我现在正试图让View矩阵起作用。所以相机翻译和旋转。这是我的问题。 – Stardidi

+0

此外,我使用Direct3D的功能,所以我不指望这是一个问题。 – Stardidi

0

请注意,如果物体的正面靠近相机,垂直方向的拉伸可能不会超过我的预期。你确定这个输出是不正确的吗?

但更重要的是,我会考虑调整FoV参数。为什么你正在转换它?如果您使用D3DXMATRIX,那么矩阵已经按照正确的顺序发送给GPU,并且不需要转置。

+0

我不觉得你真的看到我的问题:( 我转置它,否则我得到真正奇怪的结果,这样最终的WVP是着色器接收的矩阵,就像我说的,矩阵变换在我的最终转置和着色器中的计算之间的某处 我也没有使用D3DXMATRIX,因为我想让我的引擎独立于API,我的FOV是90.0f,并且改变了它给出了预期的结果(放大/缩小) – Stardidi