Переключение с перспективы на ортогональное с сохранением одинакового размера вида и масштабирования - PullRequest
0 голосов
/ 04 марта 2019

У меня угол обзора = 60, ширина = 640 и высота = 480 окон, около = 0,01 и далеко = 100 плоскостей, и я получаю матрицу проекции, используя glm::perspective()

glm::perspective(glm::radians(fov),
                              width / height,
                              zNear,
                              zFar);

Это работает хорошо.

Затем я хочу изменить тип проекции на ортогональный, но я не знаю, как правильно рассчитать входные параметры glm::ortho().Я пробовал много способов, но проблема в том, что после переключения на ортопроекцию размер модели объекта становится другим.

Пусть у меня есть куб с центром в (0.5, 0.5, 0.5) и размером 1, а также камера с mEye в (0.5, 0.5, 3), mTarget in (0.5, 0.5, 0.5) и mUp(0, 1, 0).Матрица вида glm::lookAt(mEye, mTarget, mUp) С перспективной проекцией она работает хорошо.С glm::ortho(-width, width, -height, height, zNear, zFar) мой куб стал маленьким пикселем в центре окна.Также я попытался реализовать этот вариант Как переключаться между перспективными и орфографическими камерами, сохраняя размер желаемого объекта , но результат (почти) такой же, как и раньше.

Итак, первый вопросКак вычислить орто-параметры для сохранения исходного размера вида объекта / положения камеры?

Кроме того, масштабирование с

auto distance = glm::length(mTarget - mEye)
mEye = mTarget - glm::normalize(mTarget - mEye) * distance;

не влияет на орто. Таким образом, второй вопрос заключается в том, как реализовать масштабирование в случае орто-проекции?

Ps Полагаю, я правильно понимаю орто.Пропорции модели не зависят от глубины, но, тем не менее, я все же могу решить, где находится камера для правильной настройки размера модели и использования увеличения.Также я предполагаю, что это простая и тривиальная задача, например, при разработке 3D-программы просмотра / редактора / и т.д.Поправь меня, если это не так.

1 Ответ

0 голосов
/ 05 марта 2019

как вычислить орто-параметры для сохранения исходного размера вида объекта / положения камеры?

При ортографической проекции 3-мерная сцена является параллельной проекцией в 2-мерное окно просмотра.
Это означает, что объекты, которые проецируются в окне просмотра, всегда имеют одинаковый размер, независимо от их глубины (расстояния до камеры).

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

Если вы переключаете перспективу формы только на ортогональную проекциюобъекты в 1 плоскости, которая является плоской (параллельной) с viepwort, kkp его глубина.Обратите внимание, что плоскость является двухмерной и не имеет «глубины».Это приводит к тому, что двухмерный объект никогда не может «выглядеть» одинаково при переключении проекции.Но двумерный рекламный щит может сохранять размер.

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

float ratio_size_per_depth = atan(glm::radians(fov / 2.0f) * 2.0f;

Если вы хотите настроить ортографическую проекцию, которая сохраняет размер для определенного расстояния (глубины), то сначала вам нужно определить глубину:

например, расстояние до целевой точки:

auto distance = glm::length(mTarget - mEye);

проекция может быть настроена следующим образом:

float aspect = width / height
float size_y = ratio_size_per_depth * Z;
float size_x = ratio_size_per_depth * Z * aspect;

glm::mat4 orthProject = glm::ortho( -size_x, size_x, -size_y, size_y, 0.0f, 2.0f*distance );

как реализовать увеличениеслучай орто-проекции?

Масштабирование XY компонентов ортографической проекции:

glm::mat4 orthProject = glm::ortho( -size_x, size_x, -size_y, size_y, 0.0f, 2.0f*distance );

float orthScale = 2.0f;
orthProject = glm::scale(orthProject, glm::vec3(orthScale, orthScale, 1.0f));

Установить значение для orthScale, которое составляет > 1,0 дляувеличение и значение <1,0 </em> для уменьшения.

...