0

我一直在使用 Direct3D 开发自己的 3D 引擎。这非常好,直到我遇到了世界视图和投影矩阵的问题。我正在使用我以前工作过的项目中的代码,但项目中没有。所以我决定使用 Direct3D 函数 D3DXMatrixLookAtLH 和 D3DXMatrixPerspectiveFovLH。

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

屏幕中间的立方体看起来很正常: 普通立方体

但如果我把它移到一边,它就会开始伸展: 拉伸立方体

这是我在这种情况下得到的视图矩阵:

-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 

项目:

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

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

更新2:用新信息完成重写

Update3:我遇到了视图矩阵和投影的问题。世界矩阵工作正常。

更新4:

在更改了更多代码之后,我现在有了一些似乎可以工作的东西!我现在唯一的问题是向侧面伸展。

4

2 回答 2

0

请注意,如果对象的前部更靠近相机,则垂直拉伸可能不会超过我的预期。你确定这个输出不正确吗?

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

于 2012-06-23T20:36:07.153 回答
0

您是否确保考虑乘以翻译矩阵的顺序?我的意思是,如果你先平移,然后缩放,结果将是一个拉伸的网格。您必须确保按顺序执行它们。如果您希望网格围绕自己的轴旋转,您需要先旋转然后平移。如果您希望网格围绕某物“绕行”,您首先需要将其平移到绕物体绕行的距离,然后旋转,然后将其平移到该物体的位置。

无论如何,你提到了拉伸,所以我猜这可能是因为你先翻译然后缩放:

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

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

唯一要先平移的时间是当您不进行缩放,并且您希望对象围绕另一个对象“运行”时

于 2012-06-12T07:21:10.430 回答