Hello,
I have a really annoying problem with my camera. It distort objects when they close to the window edges (make objects wider than they really are).
I cannot understand why such behavior could be. I want to achieve such behavior when objects will not stretch in any case.
Here is some code from my engine:
//Calculationg correct window size (For D2D)
RECT r = {0, 0, screenWidth, screenHeight};
AdjustWindowRect(&r, WS_TILEDWINDOW, false);
screenWidth = r.right - r.left;
screenHeight = r.bottom - r.top;
CameraDX_Free::CameraDX_Free()
{
m_accumPitchDegrees = 0.0f;
m_rotationSpeed = 0.1f;
m_fovx = 90.0f;
m_aspectRatio = 0.0f;
m_znear = 0.0f;
m_zfar = 1000.0f;
m_CameraSpeedFlight = 10.1f;
m_eye = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_eye_min = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_eye_max = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_xAxis = XMFLOAT3(1.0f, 0.0f, 0.0f);
m_yAxis = XMFLOAT3(0.0f, 1.0f, 0.0f);
m_zAxis = XMFLOAT3(0.0f, 0.0f, 1.0f);
m_viewDir = XMFLOAT3(0.0f, 0.0f, 1.0f);
m_acceleration = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_acceleration_min = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_acceleration_max = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_currentVelocity = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_velocity = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_velocity_max = XMFLOAT3(0.0f, 0.0f, 0.0f);
m_orientation = XMQuaternionIdentity();
m_viewMatrix = XMMatrixIdentity();
m_projMatrix = XMMatrixIdentity();
}
//Updating View Matrix
void CameraDX_Free::updateViewMatrix()
{
// Reconstruct the view matrix.
m_orientation = XMQuaternionNormalize(m_orientation);
m_viewMatrix=XMMatrixRotationQuaternion(m_orientation);
XMFLOAT4X4 temp;
XMStoreFloat4x4(&temp,m_viewMatrix);
m_xAxis = XMFLOAT3(temp(0,0), temp(1,0), temp(2,0));
m_yAxis = XMFLOAT3(temp(0,1), temp(1,1), temp(2,1));
m_zAxis = XMFLOAT3(temp(0,2), temp(1,2), temp(2,2));
m_viewDir = m_zAxis;
temp(3,0) = -XMVectorGetX(XMVector3Dot(XMLoadFloat3(&m_xAxis), XMLoadFloat3(&m_eye)));
temp(3,1) = -XMVectorGetX(XMVector3Dot(XMLoadFloat3(&m_yAxis), XMLoadFloat3(&m_eye)));
temp(3,2) = -XMVectorGetX(XMVector3Dot(XMLoadFloat3(&m_zAxis), XMLoadFloat3(&m_eye)));
m_viewMatrix = XMLoadFloat4x4(&temp);
}
//Camera look at
void CameraDX_Free::lookAt(const XMFLOAT3 &eye, const XMFLOAT3 &target, const XMFLOAT3 &up)
{
m_eye = eye;
m_zAxis = target - eye;
XMStoreFloat3(&m_zAxis, XMVector3Normalize (XMLoadFloat3(&m_zAxis)));
m_viewDir = m_zAxis;
XMStoreFloat3(&m_xAxis, XMVector3Cross( XMLoadFloat3(&up), XMLoadFloat3(&m_zAxis)));
XMStoreFloat3(&m_xAxis, XMVector3Normalize (XMLoadFloat3(&m_xAxis)));
XMStoreFloat3(&m_yAxis, XMVector3Cross( XMLoadFloat3(&m_zAxis), XMLoadFloat3(&m_xAxis)));
XMStoreFloat3(&m_yAxis, XMVector3Normalize (XMLoadFloat3(&m_yAxis)));
XMStoreFloat3(&m_xAxis, XMVector3Normalize (XMLoadFloat3(&m_xAxis)));
m_viewMatrix = XMMatrixIdentity();
XMFLOAT4X4 temp;
XMStoreFloat4x4(&temp,m_viewMatrix);
temp(0,0) = m_xAxis.x;
temp(1,0) = m_xAxis.y;
temp(2,0) = m_xAxis.z;
temp(3,0) = -XMVectorGetX(XMVector3Dot(XMLoadFloat3(&m_xAxis), XMLoadFloat3(&m_eye)));
temp(0,1) = m_yAxis.x;
temp(1,1) = m_yAxis.y;
temp(2,1) = m_yAxis.z;
temp(3,1) = -XMVectorGetX(XMVector3Dot(XMLoadFloat3(&m_yAxis), XMLoadFloat3(&m_eye)));
temp(0,2) = m_zAxis.x;
temp(1,2) = m_zAxis.y;
temp(2,2) = m_zAxis.z;
temp(3,2) = -XMVectorGetX(XMVector3Dot(XMLoadFloat3(&m_zAxis), XMLoadFloat3(&m_eye)));
// Extract the pitch angle from the view matrix.
m_accumPitchDegrees = XMConvertToDegrees(asinf(temp.m[1][2]) );
m_viewMatrix = XMLoadFloat4x4(&temp);
m_orientation = XMQuaternionRotationMatrix(m_viewMatrix);
}
Camera perspective
void CameraDX_Free::perspective(float fovx, float aspect, float znear, float zfar)
{
// Construct a projection matrix based on the horizontal field of view
// 'fovx' rather than the more traditional vertical field of view 'fovy'.
float e = 1.0f / tanf(XMConvertToRadians(fovx) / 2.0f);
float aspectInv = 1.0f / aspect;
float fovy = 2.0f * atanf(aspectInv / e);
float xScale = 1.0f / tanf(0.5f * fovy);
float yScale = xScale / aspectInv;
XMFLOAT4X4 temp ;
XMStoreFloat4x4(&temp,m_projMatrix);
temp(0,0) = xScale;
temp(1,0) = 0.0f;
temp(2,0) = 0.0f;
temp(3,0) = 0.0f;
temp(0,1) = 0.0f;
temp(1,1) = yScale;
temp(2,1) = 0.0f;
temp(3,1) = 0.0f;
temp(0,2) = 0.0f;
temp(1,2) = 0.0f;
temp(2,2) = zfar / (zfar - znear);
temp(3,2) = -znear * zfar / (zfar - znear);
temp(0,3) = 0.0f;
temp(1,3) = 0.0f;
temp(2,3) = 1.0f;
temp(3,3) = 0.0f;
m_projMatrix = XMLoadFloat4x4(&temp);
m_fovx = fovx;
m_aspectRatio = aspect;
m_znear = znear;
m_zfar = zfar;
}
Does anyone knows what could cause this issue and how to fix it and make rendered image near to this:
http://en.wikipedia.org/wiki/File:Panotools5618.jpg (second image).
P.S. maybe something wrong with my Vertex shader?
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
float4 position : POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType LightVertexShader(VertexInputType input)
{
const float C = 0.1f;
float Far = 100000000.0f;
PixelInputType output;
// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix); //???????????, ???????? ? ???????? ?????????
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.position.z = log(C*output.position.z + 1) / log(C*Far + 1) * output.position.w;
// Store the texture coordinates for the pixel shader.
output.tex = input.tex;
// Calculate the normal vector against the world matrix only.
output.normal = mul(input.normal, (float3x3)worldMatrix);
// Normalize the normal vector.
output.normal = normalize(output.normal);
return output;
}
I attached some screen shots from my engine to show the problem.