В настоящее время я пытаюсь создать функцию перспективы, которая выдает проекцию для OpenGL. Я создал его многими способами, последней реплицирующей функцией GLM, которая его обрабатывает (для своего назначения я должен использовать свой собственный класс Matrix4). Независимо от того, какой код я пробую, я всегда получаю неправильные числа по сравнению с GLM, что приводит к тому, что мой куб рендерит только с GLM.
Они оба инициализируются с одинаковыми переменными
glm::mat4 ProjectionGLM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
Matrix4 Projection = Matrix4::Perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
Функция перспективы
Matrix4 Matrix4::Perspective(double fov, double aspect, double zNear, double zFar) {
double fovy = fov * 0.0174532925;
double const tanHalfFovy = tan(fovy / 2.0f);
Matrix4 temp;
temp.data[0][0] = 1.0f / (aspect * tanHalfFovy);
temp.data[1][1] = 1.0f / (tanHalfFovy);
temp.data[2][2] = -(zFar + zNear) / (zFar - zNear);
temp.data[2][3] = -1.0f;
temp.data[3][2] = -(2.0f * zFar * zNear) / (zFar - zNear);
return temp;
Код моделируется непосредственно после GLM, за исключением static_cast и шаблонов. Это та же математика, что и многие другие функции, которые я пробовал. Тем не менее, результирующая матрица отличается.
Результат GLM
1.34444320 0 0 0
0 1.79259098 0 0
0 0 -1.00200200 -1.00000000
0 0 -0.200200200 0
Мои результаты
1.81066012 0 0 0
0 2.41421366 0 0
0 0 -1.00200200 -1.00000000
0 0 -0.200200200 0
Любая идея о том, что может быть не так с моей функцией перспективы или что GLM может делать по-другому?
Ссылка на мою математическую библиотеку (только файлы .h и .cpp)
https://mega.co.nz/#!lokhCBaB!5r7GwpWhEZ-tUcXV_ccxmQvZgRwIVU8K7dlIffVqZic
GLM принимает угол обзора в радианах, а значение, которое вы передаете (45.0
) в градусах.
Документация GLM для параметра примерно неясно, как это может быть:
Определяет угол поля зрения, в градусах, в направлении y. Выражается в радианах.
Да, оба говорят, что это в градусах и в радианах. Но если вы посмотрите на исходный код, это действительно радианы.
Это согласуется с вашим результатом. Для матричного элемента [2][2]
, который:
1.0 / tan(0.5 * fov)
Оценивается с tan()
функция, работающая в радианах, это дает следующее при использовании 45.0
непосредственно:
1.0 / tan(0.5 * 45.0) = 1.0 / tan(22.5) = 1.79251
При преобразовании угла в радианы сначала:
1.0f / tan(0.5 * 45.0 * pi / 180.0) = 1.0 / tan(0.3927) = 2.41421
Поэтому, если вы преобразуете входной угол для версий GLM в радианы, я предсказываю, что вы получите то же значение, что и рассчитанное вами:
glm::mat4 ProjectionGLM = glm::perspective(45.0f * M_PI / 180.0f, 4.0f / 3.0f, 0.1f, 100.0f);