Я хочу создать свою собственную матрицу mvp в качестве упражнения.
auto lookAt(Vec)(const Vec eye, const Vec center, const Vec up)
if(isVector!Vec && Vec.dimension is 3){
auto z = (eye - center).unit;
auto x = cross(up.unit, z);
auto y = cross(z, x);
alias Mat = Matrix!(Vec.Type, 4, 4);
alias Vec4 = Vector!(Vec.Type, 4);
return Mat(Vec4(x, 0),
Vec4(y, 0),
Vec4(z, 0),
Vec4(0, 0, 0, 1)) * translate(-eye);
}
Преобразование вида было довольно простым, я настроил его так, что теперь смотрю по отрицательной оси Z.
Но у меня есть несколько проблем с матрицей перспективы.
y' = 1 / (tan(fov/2) * z
x' = 1 / (ar * tan(fov/2) * z
Где x'
и y'
— новые искаженные значения. Так я придумал эту матрицу
Mat4f projection(float fov, float ar, float near, float far){
import std.math: tan;
auto tanHalfAngle = tan(fov/2.0f);
return Mat4f(
Vec4f(1.0f / (ar * tanHalfAngle) , 0, 0, 0),
Vec4f(0, 1.0f / tanHalfAngle, 0, 0),
Vec4f(0, 0, 1, 0),
Vec4f(0, 0, -1, 0));
}
В настоящее время я просто настроил его так, чтобы значение Z
всегда было -1
. Но я сделал небольшую ошибку, потому что теперь я делю на -Z
.
Дело в том, что Матрица выше работает. В настоящее время я визуализирую вращающийся куб, и, кроме значений глубины, все выглядит правильно.
Но я очень хотел эту матрицу
Mat4f projection(float fov, float ar, float near, float far){
import std.math: tan;
auto tanHalfAngle = tan(fov/2.0f);
return Mat4f(
Vec4f(1.0f / (ar * tanHalfAngle) , 0, 0, 0),
Vec4f(0, 1.0f / tanHalfAngle, 0, 0),
Vec4f(0, 0, -1, 0),
Vec4f(0, 0, 1, 0));
}
Но куб больше не появляется на экране, и я не понимаю, почему.
auto view = lookAt(Vec3f(0, 0, -5), Vec3f(0, 0, 0), Vec3f(0, 1, 0));
auto proj = projection(PI/2, 4.0f/3.0f, 0.1f, 100);
Я устанавливаю тестовые значения
auto v = proj * view * Vec4f(0.5,0.5,0.5,1);
Это результат, который я получаю с первой матрицей, где я делю на -Z
Vec(-0.375, 0.5, -5.5, 5.5)
Vec(-0.0681818, 0.0909091, -1) // divided by w
Это результат, который я получаю со второй матрицей, где я делю на Z
Vec(-0.375, 0.5, 5.5, -5.5)
Vec(0.0681818, -0.0909091, -1) //divided by w
Единственное, что изменилось, это знак.
Но почему я вижу куб с первой матрицей, а со второй ничего не вижу?