Я ищу алгоритм для установки ограничительной рамке в области просмотра (в моем случае сцена DirectX). Я знаю об алгоритмах для центрирования сферы ограничения в ортогональной камере, но нуждался бы в том же для ограничительной рамки и перспективной камеры. Я не могу только изменить FOV, потому что это приложение имеет FOV как пользователя доступная для редактирования переменная, таким образом, это должно переместить камеру.
У меня есть большинство данных:
Проблемы я имею:
Как я нахожу положение камеры так, чтобы оно заполнило область просмотра как пиксель, прекрасный как возможную (исключение, являющееся, если соотношение сторон далеко от 1,0, оно только должно заполнить одну из экранной оси)?
Я попробовал некоторые другие вещи:
Справка!
Существует множество возможных положений + ориентаций камеры, при которых ограничивающая рамка будет помещаться внутри области обзора. Но любая процедура будет выбирать одно конкретное положение и ориентацию камеры.
Если вы хотите рассмотреть ограничивающие сферы, одним из решений может быть
С ограничивающими ящиками вы можете рассмотреть более ранний шаг, сначала расположив камеру перпендикулярно центру самой большой (или самой маленькой, как вам больше нравится) грани куба.
У меня нет опыта работы с DirectX, но перемещение и изменение направления взгляда камеры для центрирования определенной точки должно быть простым. Самое сложное - сделать математический расчет, чтобы решить, на какое расстояние нужно переместиться, чтобы увидеть объект.
Если вы знаете граничный размер s
объекта в мировых координатах (нас не интересуют пиксели или координаты камеры, поскольку они зависят от расстояния), исходя из ориентации камеры, вы можете вычислить необходимое расстояние d
камеры до граничной формы, если вам известны углы x и y поля зрения a
перспективной проекции.
frustum ------
------ ***** -
----- * * |
-=== ) FOV a *bounding box | BB size s
camera ----- * * |
------ ***** -
------
|-------------------|
distance d
Итак, математика: tan(a/2) = (s/2) / d
=> d = (s/2) / tan(a/2)
.
Это даст вам расстояние, на котором камера должна быть расположена от ближайшей граничной поверхности.
Поскольку у вас есть ограничивающая рамка, у вас должна быть основа, описывающая ее ориентацию. Кажется, что вы хотите расположить камеру на линии, совпадающей с базисным вектором, описывающим наименьший размер коробки, а затем поверните камеру так, чтобы наибольшее измерение было горизонтальным (при условии, что у вас есть OBB, а не AABB). Это предполагает, что соотношение сторон больше 1.0; в противном случае вы захотите использовать вертикальный размер.
Что бы я сделал:
boxWidth / (2 * tan (horizontalFov / 2))
. Обратите внимание, что boxWidth
- это ширина наибольшего измерения бокса. boxCenter + scaledBasis
, глядя на boxCenter
. Редактировать:
Итак, я думаю, вы имеете в виду, что камера находится в произвольной позиции и куда-то смотрит, а AABB находится в другой позиции.Не перемещая камеру к стороне коробки, вы хотите:
В этом случае у вас будет немного больше работы; вот что я предлагаю:
Отмените проецирование
двух противоположных углов ограничивающей рамки экранного пространства в мировое пространство. Для значения Z используйте ближайшие точки мирового пространства вашего AABB к камере. Сейчас у меня ее нет под рукой, но книга, которая вам нужна - http://www.amazon.com/Jim-Blinns-Corner-Graphics-Pipeline/dp/1558603875/ref=ntt_at_ep_dpi_1
У него есть целая глава об этом