Проблемы реализации перспективной проекции в 3D графике, (d3d)
У меня огромные трудности с настройкой перспективной проекции с прямым x. Я застрял на этом в течение нескольких недель, любая помощь будет оценена.
Насколько я могу, мой конвейер настроен нормально, поскольку шейдер получает именно те данные, которые я упаковываю, поэтому я воздержусь от включения этого кода, если меня не попросят.
Я использую glm для математики (следовательно, матрицы столбцов) на стороне хоста. Он настроен на использование левой системы координат. Однако я не мог заставить ее матрицу проекции работать (я получаю пустой экран, если использую матрицу, которую я получаю из нее), поэтому я написал это - что, я надеюсь, будет только временным.
namespace
{
glm::mat4
perspective()
{
DirectX::XMMATRIX dx = DirectX::XMMatrixPerspectiveFovLH(glm::radians(60.0f), 1, 0.01, 1000.0f);
glm::mat4 glfromdx;
for (int c = 0; c < 3; c++)
{
for (int r = 0; r < 3; r++)
{
glfromdx[c][r] = DirectX::XMVectorGetByIndex(dx.r[c], r);
}
}
return glfromdx;
}
}
это дает мне проекционную матрицу, которая работает, но я не думаю, что она работает. Я не уверен, является ли это фактической проекцией, и мое пространство клипа незначительно. Если я перемещаю свою камеру на всех, это скрепляет. Фотографии включены.
фото 1: (прямо)
фото 2: (камера наклонена вверх)
фото 3: (камера наклонена влево)
Вот мой вершинный шейдер https://gist.github.com/anonymous/31726881a5476e6c8513573909bf4dc6
cbuffer offsets
{
float4x4 model; //<------currently just identity
float4x4 view;
float4x4 proj;
}
struct idata
{
float3 position : POSITION;
float4 colour : COLOR;
};
struct odata
{
float4 position : SV_POSITION;
float4 colour : COLOR;
};
void main(in idata dat, out odata odat)
{
odat.colour = dat.colour;
odat.position = float4(dat.position, 1.0f);
//point' = point * model * view * projection
float4x4 mvp = mul(model, mul(view, proj));
//column matrices.
odat.position = mul(mvp, odat.position);
}
А вот и мой фрагментный шейдер https://gist.github.com/anonymous/342a707e603b9034deb65eb2c2101e91
struct idata
{
float4 position : SV_POSITION;
float4 colour : COLOR;
};
float4 main(in idata data) : SV_TARGET
{
return float4(data.colour[0], data.colour[1], data.colour[2] , 1.0f);
}
полная реализация камеры также доступна здесь https://gist.github.com/anonymous/b15de44f08852cbf4fa4d6b9fafa0d43 https://gist.github.com/anonymous/8702429212c411ddb04f5163b1d885b9
Наконец, эти вершины передаются в позиции 3, цвет 4
(0,0f, 0,5f, 0,0f, 1,0f, 0,0f, 0,0f, 1,0f), (0,45f, -0,5f, 0,0f, 0,0f, 1,0f, 0,0f, 1,0f), (-0,45 f, -0,5f, 0,0f, 0,0f, 0,0f, 1,0f, 1,0f)
Редактировать:
Я изменил вычисление P*M*V*P в шейдере на это; odat.position = mul(mul(mul(proj, view), model), odat.position); все еще с той же проблемой.
Изменить 2:
Хм, вышеописанные изменения смешались с изменением того, что создает перспективу, теперь просто используя glm.
glm::mat4 GLtoDX_NDC(glm::translate(glm::vec3(0.0, 0.0, 0.5)) *
glm::scale(glm::vec3(1.0, 1.0, 0.5)));
glm::mat4 gl = GLtoDX_NDC * glm::perspectiveFovLH(60.0f, 500.0f, 500.0f, 100.0f, 0.1f);
Это работает, поскольку объект больше не отбраковывается с микрометром и проецируется до приблизительных размеров. Тем не менее, теперь все с ног на голову и вращение вызывает сдвиг...