0

DirectX11で3D一人称カメラを作成する際に問題が発生しました。

(0、0、-2)に(0、0、100)を見ているカメラがあります。(0、0、0)にボックスがあり、ボックスは正しくレンダリングされます。以下のこの画像を参照してください。

ここに画像の説明を入力してください

ボックス(カメラではない)の位置が変わると、正しくレンダリングされます。たとえば、次の画像は、ボックスが(1、0、0)にあり、カメラがまだ(0、0、-2)にあることを示しています。

ここに画像の説明を入力してください

ただし、カメラが左または右に移動するとすぐに、ボックスは反対方向に移動するはずですが、代わりにねじれているように見えます。これは、カメラが(1、0、-2)にあり、(1、0、100)を見ている場合の例です。ボックスはまだ(0、0、0)にあります:

ここに画像の説明を入力してください

カメラの設定方法は次のとおりです。

// Set the world transformation matrix.

D3DXMATRIX rotationMatrix;          // A matrix to store the rotation information
D3DXMATRIX scalingMatrix;           // A matrix to store the scaling information
D3DXMATRIX translationMatrix;       // A matrix to store the translation information

D3DXMatrixIdentity(&translationMatrix);

// Make the scene being centered on the camera position.
D3DXMatrixTranslation(&translationMatrix, -camera.GetX(), -camera.GetY(), -camera.GetZ());

m_worldTransformationMatrix = translationMatrix;

// Set the view transformation matrix.

D3DXMatrixIdentity(&m_viewTransformationMatrix);

D3DXVECTOR3 cameraPosition(camera.GetX(), camera.GetY(), camera.GetZ());

// ------------------------
// Compute the lookAt position
// ------------------------

const FLOAT lookAtDistance = 100;

FLOAT lookAtXPosition = camera.GetX() + lookAtDistance * cos((FLOAT)D3DXToRadian(camera.GetXZAngle()));
FLOAT lookAtYPosition = camera.GetY() + lookAtDistance * sin((FLOAT)D3DXToRadian(camera.GetYZAngle()));
FLOAT lookAtZPosition = camera.GetZ() + lookAtDistance * (sin((FLOAT)D3DXToRadian(camera.GetXZAngle())) * cos((FLOAT)D3DXToRadian(camera.GetYZAngle())));

D3DXVECTOR3 lookAtPosition(lookAtXPosition, lookAtYPosition, lookAtZPosition);

D3DXVECTOR3 upDirection(0, 1, 0);

D3DXMatrixLookAtLH(&m_viewTransformationMatrix,
                   &cameraPosition,
                   &lookAtPosition,
                   &upDirection);

RECT windowDimensions = GetWindowDimensions();
FLOAT width = (FLOAT)(windowDimensions.right - windowDimensions.left);
FLOAT height = (FLOAT)(windowDimensions.bottom - windowDimensions.top);

// Set the projection matrix.

D3DXMatrixIdentity(&m_projectionMatrix);
D3DXMatrixPerspectiveFovLH(&m_projectionMatrix,
                           (FLOAT)(D3DXToRadian(45)),  // Horizontal field of view
                           width / height,    // Aspect ratio
                           1.0f,              // Near view-plane
                           100.0f);           // Far view-plane

最終的なマトリックスの設定方法は次のとおりです。

D3DXMATRIX finalMatrix = m_worldTransformationMatrix * m_viewTransformationMatrix * m_projectionMatrix;

// Set the new values for the constant buffer
mp_deviceContext->UpdateSubresource(mp_constantBuffer, 0, 0, &finalMatrix, 0, 0);

そして最後に、定数バッファーを使用する頂点シェーダーを次に示します。

VOut VShader(float4 position : POSITION, float4 color : COLOR, float2 texcoord : TEXCOORD)
{
    VOut output;

    output.color = color;
output.texcoord = texcoord;
output.position = mul(position, finalMatrix);  // Transform the vertex from 3D to 2D

    return output;
}

私が間違っていることがわかりますか?私のコードについてさらに情報が必要な場合は、遠慮なく質問してください。私はこれが本当に機能することを望んでいます。

ありがとう!

4

1 に答える 1

1

問題は、行のメジャーマトリックスを使用してfinalMatrixを設定しているのに、HLSLは列のメジャーマトリックスを想定していることです。解決策は、定数を更新する前にD3DXMatrixTransposeを使用するか、次のようにHLSLファイルでrow_majorを宣言することです。

cbuffer ConstantBuffer
{
    row_major float4x4 finalMatrix;
}
于 2012-05-04T08:42:18.377 に答える