#c #opengl #glm-math #perspectivecamera #projection-matrix
#c #opengl #glm-математика #перспективная камера #проекция-матрица
Вопрос:
Когда я использую перспективную проекцию в OpenGL, моя ось X инвертируется, как показано на изображении ниже. Приведенный ниже код может быть недействительным, потому что я сильно изменил его, чтобы сделать его менее неясным. Это может не сработать, так что просто имейте это в виду. Вот код и вершины:
typedef struct{
float x;
float y;
float z;
} vertex_t;
glm::vec3 position = glm::vec3(0, 0, 0);
glm::vec3 look_at = glm::vec3(0, 0, 1);
glm::mat4 projectionMatrix = glm::perspective(45.0f, (float)800 / (float)600, 0.1f, 100.f);
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 5.0f));
glm::mat4 viewMatrix = glm::lookAt(
position,
look_at,
glm::vec3(0, 1, 0)
);
vertex_t data[3] = {
{-0.5, 0.5, -0.5f},
{ 0.5, 0.5, -0.5f},
{-0.5, -0.5, -0.5f},
};
unsigned int indices[3] = {
0, 1, 2
};
glm::mat4 mvp = projectionMatrix * viewMatrix * modelMatrix; //This is passed in as the uniform u_MVP later
Это вершинный шейдер:
#version 330 core
layout(location = 0) in vec4 position;
uniform mat4 u_MVP;
void main(){
gl_Position = u_MVP * position;
}
И это результат. Как вы можете видеть, он не соответствует предоставленным вершинам.
Если вам нужен весь код целиком или если вы хотите, чтобы я предоставил оригинальную версию, пожалуйста, дайте мне знать. Спасибо!
ОБНОВЛЕНИЕ: я пробовал отрицательную ось Z, и это не сработало. Вот код:
position = glm::vec3(0, 0, 0);
look_at = glm::vec3(0, 0, -1);
glm::mat4 projectionMatrix = glm::perspective(45.0f, (float)800 / (float)600, 0.1f, 100.f);
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));
viewMatrix = glm::lookAt(
position,
look_at,
glm::vec3(0, 1, 0) // Tilt/rotation (unclear) set y to -1 for upside down view
);
Комментарии:
1. Я думаю, что ваша проблема может быть связана с вашей камерой, а не с вашей проекционной матрицей. Что происходит, так это то, что вы смотрите на него сзади, поэтому кажется, что x перевернут. Помните, что OpenGL использует правостороннюю систему координат, что означает, что ось z указывает за пределы экрана в вашу сторону. Представьте свой треугольник на экране. Вы переводите его на 5 (~ 5 шагов от экрана), и ваша камера (на экране) смотрит в этом направлении. Отсюда и вывод. То, что вам нужно, — это модель, перемещенная на -5, и камера, смотрящая в отрицательном направлении.
2. @Beko спасибо! не могли бы вы опубликовать это в качестве ответа?
3. Np, Rabbid уже ответил на этот вопрос, так что в этом нет необходимости.
4. @Beko Вы правы. Мы обнаружили одну и ту же проблему (почти в одно и то же время). Не оставляйте комментарии, но оставляйте ответы. На самом деле ваш комментарий — это ответ.
5. @Rabbid76 Да, почти одновременно. Я буду иметь это в виду (:
Ответ №1:
Ось x не инвертируется из-за матрицы проекции, но она инвертируется из-за матрицы представления.
glm::vec3 position = glm::vec3(0, 0, 0);
glm::vec3 look_at = glm::vec3(0, 0, 1);
glm::mat4 viewMatrix = glm::lookAt(position, look_at, glm::vec3(0, 1, 0));
Пространство просмотра — это правосторонняя система, в которой ось X указывает вправо, а ось Y — вверх. Ось Z указывает за пределы представления (обратите внимание, что в правой системе ось Z является перекрестным произведением осей X и осей Y).
Следовательно, вы смотрите на треугольник сзади.
Измените матрицу модели и матрицу представления. Сдвиньте треугольник вдоль отрицательной оси Z. Определите линию обзора, указывающую в отрицательном направлении z:
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));
glm::vec3 position = glm::vec3(0, 0, 0);
glm::vec3 look_at = glm::vec3(0, 0, -1);
glm::mat4 viewMatrix = glm::lookAt(position, look_at, glm::vec3(0, 1, 0));
Расстояния до ближней и дальней плоскости должны быть положительными значениями, а единица угла для glm::perspective
является лучистой:
0 < near < far
glm::mat4 projectionMatrix = glm::perspective(45.0f, (float)800 / (float)600, -0.1f, -100.f);
glm::mat4 projectionMatrix = glm::perspective(
glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.f);
Комментарии:
1. Я получаю черный экран, треугольник не появляется. Но чем выше число на оси Z, тем дальше становится треугольник, предполагая, что это левосторонняя система. Что не так?
2. изменил их оба, когда позиция z отрицательна, я ничего не вижу.
3. я добавил код, не могли бы вы взглянуть?
4. Я попробовал это с положительными значениями, то же самое
5. У меня это не работает. Я сузил проблему до этой строки :
look_at = glm::vec3(0, 0, -1);
. Когда это выглядит при z = 1, все в порядке (в том числе, когда modelMatrix имеет значение -5 z), но когда оно равно отрицательному 1, я ничего не вижу