Координаты

На этот раз я попробую ответить на Главный Вопрос Жизни, Вселенной и Всего-всего, а именно — осветить тему координат в WebGL. И начать стоит с того, зачем же для представления точки в трехмерном пространстве используется четыре координаты? И этот вопрос ведет нас к понятию Однородные координаты…


Часть 1: Однородные координаты

Итак, в однородных координатах вершины имеют четыре компоненты: x, y, z и w, первые три из которых — это привычные всем координаты евклидова пространства. Зачем же нам нужна четвертая компонента?.. Дело в том, что декартовы координаты не позволяют описать смещение (так как за смещение отвечает четвертый столбец матрицы 4х4). Кроме того, однородные координаты (в отличие от декартовых) позволяют найти точку пересечения двух параллельных линий — линии пересекутся в бесконечности, что важно для перспективной проекции WebGL. Для понимания перспективы представьте, что вы стоите между рельсов железной дороги и смотрите вдаль. Несмотря на то, что рельсы параллельны, они будут сужаться по мере удаления, пока не сойдутся в одной точке где-то на горизонте.

Еще одно преимущество однородных координат — они позволяют отличить точку от направления. Если w = 1, тогда вектор (x, y, z, 1) — это точка в пространстве. Если w = 0, тогда вектор (x, y, z, 0) — это направление. Просто запомните это без доказательств.

Перевод декартовых координат в однородные и обратно происходит очень легко. При переводе из декартовых координат в однородные достаточно добавить единицу в четвертую компоненту. А при переводе из однородных координат в декартовы необходимо все координаты разделить на w, после чего отбросить четвертую компоненту.

  • Декартовы(x, y, z) = Однородные(x, y, z, 1)
  • Однородные(x, y, z, w) = Декартовы(x/w, y/w, z/w)


Часть 2: Системы координат

На пути к изображению на мониторе координаты вершин объекта проходят через множество систем координат, включая координаты объекта, мировые координаты, координаты камеры и другие. Рассмотрим их все по порядку.


Координаты объекта

Здесь еще нет других объектов, сцены и всего другого. Есть только один объект — и все координаты расположены относительно его центра (и Солнце вращается вокруг него, и установлен этот объект на спинах слонов). Равносторонний куб со стороной равной единице и с центром в координатах (0, 0) будет выглядеть следующим образом:



Координаты мира

Когда у нас появляется множество объектов, сразу встает вопрос — как они будут расположены друг относительно друга? В пространстве объекта у каждого куба была своя система координат, но теперь при отображении всех кубов одновременно нам потребуется новая общая система координат, в роли которой и выступает мировое пространство. Координаты мира определяют, где расположен тот или иной объект. На следующей картинке вы можете видеть, как расположены 16 кубов в мировых координатах (-3, -3, 0), (-3, -1, 0), (-3, 1, 0) и так далее до (3, 3, 0)

Обратите внимание, как при этом расположена камера.


Координаты камеры (координаты наблюдателя)

После того, как все объекты заняли свои места в мировом пространстве, пришло время на них взглянуть. Напомню, что в WebGL нет такого объекта как камера, которым мы могли бы манипулировать. Предполагается, что камера всегда расположена в координатах (0, 0, 0) и направлена в отрицательную сторону оси Z. А раз камеру мы переместить не можем, то нужно переместить объекты таким образом, чтобы они находились перед камерой. За этот перенос (и поворот с масштабированием) отвечает матрица вида. Но в WebGL нет отдельной матрицы вида (как и матрицы модели, которая должна располагать объект в мировом пространстве). Вместо этого есть одна матрица модель-вид, совмещающая в себе матрицу модели и матрицу вида. И вот что мы увидим после умножения на матрицу модель-вид (на самом деле на данном этапе мы еще не можем получить изображение, которое можно вывести на 2D экран, поэтому следующее изображение является довольно условным):



Координаты отсечения

В сцене может содержаться множество объектов — одни будут позади камеры, другие слева или справа, вне области видимости. Естественно, такие объекты не должны участвовать в рендеринге. Поэтому цель данного этапа — определить, какой объем пространства попадет на экран и каким образом он будет спроецирован. Этот объем ограничивается шестью плоскостями (передняя, задняя, левая, правая, верхняя и нижняя) и называется фрустум:

Эти шесть плоскостей заложены в проекционной матрице. Вершины, лежащие за пределами фрустума, отсекаются и не участвуют в дальнейшей обработке. Кроме того, форма фрустума задает тип проекции 3D-картинки на 2D-экран. Если передняя и задняя плоскость будут одинаковых размеров, то будет использована ортографическая проекция (в этом случае объекты вблизи и вдалеке будут иметь одинаковые размеры, что создает не очень реалистичную картину). В противном случае будет использована перспективная проекция (в этом случае деревья вдалеке будут меньших размеров по сравнению с ближайшими, а рельсы сойдутся на горизонте — именно так мы видим мир в реальной жизни).


Нормализованные координаты устройства

На данном этапе фрустум проецируется на переднюю плоскость для получения 2D-координат — именно это изображение в дальнейшем станет тем, что мы увидим на мониторе. Нам уже известно, что для получения декартовых координат необходимо разделить x, y и z на w (это еще называется перспективное деление). После деления мы получаем три компоненты: координаты x и y определяют положение вершин на плоскости, а координата z отвечает за глубину вершины, что помогает WebGL определить, какие объекты находятся ближе к наблюдателю и попадут на экран, а какие будут перекрыты и не будут отображены.

Нормализованные координаты не зависят от экрана устройства. Вы можете представить их в виде куба, все координаты которого находятся в диапазоне от -1 до 1 по всем осям.

За перспективное деление также отвечает проекционная матрица.


Экранные координаты

Это заключительный этап всех преобразований. Здесь нормализованные координаты устройства выводятся на canvas (который не обязательно должен быть квадратный, в отличие нормализованных координат устройства). В отличие от предыдущих преобразований здесь не используется матрица. За преобразование в экранные координаты отвечает функция viewport. И вот, что мы увидим на экране:



Подводя итоги

Если обобщить все вышеизложенное, мы получим такую схему:

Схема также показывает разницу между теорией и реализацией в WebGL — пять трансформаций в теории выполняются за три трансформации в реализации WebGL, каждую из которых мы подробно рассмотрели.

Координаты

Метки:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *