Переключение с ортогональной на перспективную проекцию - PullRequest
2 голосов
/ 15 октября 2019

Я пытаюсь добавить эффект паралакса к существующему движку. Пока двигатель работал с ортогональной проекцией. Объекты размещаются в пиксельных координатах на экране. Проблема в том, что я не могу понять, как повторить ту же проекцию с матричной проекцией и т. Д. что я могу добавить координату Z для глубины.

Я уже пробовал различные комбинации матриц и координат z, и результатом всегда был черный экран.

Матрица, которую я пытаюсь заменить:

glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(1280.0f), static_cast<GLfloat>(720.0f), 0.0f, 0.0f, -100.0f);

Вершинный шейдер:

// Shader code (I tested this while having identity matrices for view and model

#version 330 core

layout (location = 0) in vec2 vertex;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main() {
    gl_Position = projection * view * model * vec4(vertex.xy, 1.0f, 1.0f);
}

Код проекции, который, как я думал, может работать:

    glm::mat4 model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(-640, -310.0f, 0.0f));
    model = glm::scale(model, glm::vec3(1.0f / 1280.0f, 1.0f / 720.0f, 1.0f));

    glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 0.0f);
    glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
    glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); 
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, -100.0f);

Ожидается, что прямоугольник все еще отображается в аналогичной позиции (Я могу исправить детали, если что-то работает) без черного экрана.

Ответы [ 2 ]

2 голосов
/ 19 октября 2019

Таким образом, исправленная матрица перевода модели и требуемая глубина в шейдере, чтобы координаты совпадали на плоскости, были следующими:

int width = 1280.0f;
int height = 720.0f;

glm::mat4 model = glm::mat4(1.0f);  
model = glm::scale(model, glm::vec3(-1.0f / width, -1.0f / height, 1.0f));
model = glm::translate(model, glm::vec3(-((float)width / 2.0f), -((float)height / 2.0f), 0.0f));

glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, 1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); 
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f);

Шейдер с Z-значением:

#version 330 core

layout (location = 0) in vec2 vertex;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main() {
    gl_Position = projection * view * model * vec4(vertex.xy, 1.208f, 1.0f);
}

Что будет эквивалентно этой ортогональной матрице:

glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(this->width), static_cast<GLfloat>(this->height), 0.0f, 0.0f, -100.0f);

Матрицы также можно умножать вместе, чтобы иметь только одну проекционную матрицу, которую вы передаете шейдеру. Это облегчит фактическую матрицу модели, переданную с сеткой и т. Д.

2 голосов
/ 15 октября 2019

Неверно указана матрица Перспективная проекция .

glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, -100.0f);

glm::perspective определяет Просмотр усеченного конуса на угол поля зрения вдоль оси y, соотношение сторон и расстояние до ближней и дальней плоскостей.
Таким образом, вблизи и дальней плоскостидолжны иметь положительные значения (> 0) и около должно быть меньше далеко :

0 < near < far

например:

glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f);

Геометрия должна находиться между ближней и дальней плоскостями, иначе она обрезается.
Соотношение размеров проецируемой области и глубины является линейным и может быть рассчитано. Это зависит от угла поля зрения:

float fov_y = glm::radians(45.0f);
float ratio_size_depth = tan(fov_y / 2.0f) * 2.0f;

Обратите внимание, если объект должен отображаться с половиной размера в проекции в области просмотра, расстояние от объекта до камеры (глубина) должно быть удвоено.

...