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

Стандарты

Алгебра связана с правилами, которые мы устанавливаем. При выполнении вычислений в трехмерных пространствах мы должны определить правило для следующих вещей:

  • Правило левой или правой руки для системы координат
  • Вектор показан в виде строки или столбца
  • Порядок матрицы
  • Направление координат X Y Z
  • Направление положительных углов (это не обязательно связано с хиральностью нашей системы координат)
  • Порядок вращения для углов Эйлера
  • И т. д.

Эти стандарты/правила важны для наших математических расчетов, а также для нашей интерпретации результатов расчетов. Мы должны выбрать, как интерпретировать значения X Y Z при визуализации трехмерного пространства. Какая из этих осей направлена ​​вверх? Если мы выберем Y как ось вверх/вниз, +Y будет направлением вверх или -Y? Порядок вращения имеет решающее значение для углов Эйлера. Вращение, применяемое в порядке X Y Z (т. е. вращение вокруг оси X, затем вращение вокруг оси Y, затем вращение вокруг оси Z), даст другую ориентацию, чем вращение, примененное в порядке Z X Y.

Поэтому мы должны определиться со стандартом. Выбор, который мы делаем для этих стандартов, является произвольным (хотя некоторые стандарты работают лучше для некоторых приложений), пока мы последовательны в этом. Последовательность – это самое главное. Неважно, выбираем ли мы порядок XZY или порядок YXZ, пока мы выбираем один и придерживаемся его. Вы должны быть предельно осторожны, чтобы следовать стандартам/правилам, которые вы установили. Отсутствие последовательности может привести к ошибкам, которые чрезвычайно трудно отследить. Как инженер, разрабатывающий игровые движки, важно принять решение и обеспечить соблюдение этих стандартов.

К сожалению, разные источники/авторы используют разные стандарты — это огромный источник путаницы. Unity, наиболее часто используемый игровой движок в мире, использует ось Z в качестве оси вперед/назад, ось Y в качестве оси вверх/вниз и ось X в качестве оси вправо/влево с положительными направлениями. будучи вперед, вверх, вправо соответственно. Unreal Engine использует X для вперед/назад, Z для вверх/вниз и Y для вправо/влево. Blender использует те же оси, что и Unreal, но использует положительное направление Y как левое, а не правое (правосторонний против левостороннего). Blender использует правило правой руки для всех вращений, в то время как Unreal использует правило правой руки для вращений по осям X и Y, но использует правило левой руки для вращений по оси Z (направление вращения не привязано к вращению системы координат).

Однако эти несоответствия тривиальны по сравнению с тем, что я считаю самой большой головной болью, когда речь идет о разных авторах, использующих разные стандарты: порядок вращения.

Порядок вращения

Углы Эйлера ужасны. Справедливости ради следует отметить, что разные способы кодирования информации о вращении/ориентации имеют свои сильные и слабые стороны. Я, вероятно, буду использовать «поворот» и «ориентация» как синонимы, но есть небольшая разница. Разница в том, что ориентация — это вращение, применяемое к некоторому вектору направления (чаще всего к прямому вектору — независимо от того, что стандарт выбирает). Другими словами, вы можете думать об ориентации как о вращении относительно некоторого вектора направления. Двумя другими распространенными альтернативами для представления вращений являются матрицы и кватернионы. У обоих есть свое применение, но с обоими трудно работать на человеческом уровне. Углы Эйлера кодируют ориентацию как серию вращений вокруг осей XYZ — это очень легко концептуализировать, и это в удобочитаемом формате. На практике матрицы и кватернионы также могут быть волшебными ящиками, в которые мы не вникаем. С углами Эйлера объективно проще всего работать, поэтому интерфейс редактора Unity использует углы Эйлера, хотя внутри эти углы Эйлера преобразуются в кватернионы.

У углов Эйлера есть много проблем (например, блокировка карданного подвеса, невозможность преобразования векторов, невозможность отображать вектор или точку из одного координатного пространства в другое и т. д.), но одна из самых раздражающих заключается в том, что порядок вращения имеет значение. Порядок вращения XYZ может давать ориентацию, отличную от порядка XZY, ZXY, YZX, YXZ, ZYX.

Допустим, мы используем порядок вращения XZY, то есть сначала применяем вращение вокруг X, затем вращение вокруг Z и последнее вращение вокруг Y. Сначала мы применяем вращение по оси X, что означает, что вращение по оси X подлежит последующим вращениям. Когда мы применяем вращение по оси Z, мы уже применили вращение по оси X, что означает, что начальное вращение по оси X, которое мы определили, фактически определено в контексте этого вращения по оси Z. Наконец, когда мы применяем вращение по оси Y, мы влияем как на вращение по оси Z, так и на вращение по оси X, которые были до него. Это по своей сути создает иерархию вращений, где Y — самый высокий уровень, а X — самый низкий (т.е. Y -> Z -> X). Обратите внимание, если мы напишем порядок поворотов от самого высокого в иерархии к самому низкому, то у нас будет YZX, который перевернут от XZY. Что раздражает, так это то, что некоторые авторы будут писать порядок ротации в терминах этой иерархии, а некоторые — в терминах фактического порядка ротации. Это означает, что если вы где-то видите порядок XZY, вы не можете быть уверены, означает ли это XZY или YZX без тщательного изучения.

Это сбивает с толку? Это моя точка зрения. Я рекомендую поэкспериментировать с различными порядками вращения в Blender, если вы действительно хотите разобраться в этом. Следующее видео также может помочь.

Обратите внимание, как в видео автор говорит, что иерархия Y->X->Z создает порядок вращения YXZ, когда фактический порядок применения поворотов ZXY. Напротив, в Документации Blender по вращениям отмечается, что их XYZ, XZY, YXZ, YZX, ZXY и ZYX режимы вращения Эйлера названы с использованием букв осей по порядку, начиная с оси внизу иерархии и заканчивая тем, кто наверху.

Вы также можете прочитать эти страницы документации для Unity:





Обратите внимание, что на странице Quaternion.Euler написано: «Возвращает вращение, которое поворачивает z градусов вокруг оси z, x градусов вокруг оси x и y градусов вокруг оси y; применяется в таком порядке». Вы можете подумать, что это означает, что Unity использует порядок вращения ZXY. Вы были бы в основном правы. Однако порядок вращения ZXY в Unity не совпадает с порядком вращения ZXY в Blender, потому что Blender использует +X как положительное направление вперед, а Unity использует +Z. Разве это не бесит?

Это то, что вы должны иметь в виду при работе с вращениями.

Кватернионы

Кватернионы могут сбивать с толку. Шутка в том, что никто на самом деле не понимает, как они работают. Но на самом деле кватернионы состоят из простых свойств и просты в использовании. Есть также много проблем, которые могут решить только кватернионы (например, сферическая интерполяция). Кроме того, некоторые задачи проще решить с помощью кватернионов. Например, у меня был прожектор, указывающий в направлении А. Я хотел вычислить величину вращения, которую мне нужно применить к этому прожектору, чтобы он указывал в направлении Б. С кватернионами это тривиально. Мы просто находим разницу вращения между двумя ориентациями направлений A и B (разница = quat B * инверсия quat A). С углами Эйлера это гораздо более сложная проблема, потому что теперь мы думаем о разнице поворотов как о комбинации поворотов вокруг осей XYZ.

Как упоминалось ранее, Unity использует кватернионы для внутренних поворотов, и я считаю, что Unreal делает то же самое. Кватернионы очень удобны, и вам следует использовать кватернионы внутри, если вы создаете игровой движок. Но кватернионы не удобочитаемы/дружественны для человека и не дружественны к GPU — GLSL и HLSL работают с матрицами. Поэтому ваш игровой движок должен иметь возможность свободно конвертировать между тремя различными представлениями. Самое лучшее, что вы можете иметь в представлении, — это любое представление. Важно понимать взаимосвязь между кватернионом, матрицей преобразования (в частности, вращения) и углами Эйлера, чтобы вы могли реализовать функции для преобразования между этими представлениями.

Кватернионы широко используются в космических челноках, поэтому НАСА провело значительный анализ этих взаимосвязей. Ниже приведены фотографии отчета НАСА, описывающие эти отношения. Обратите внимание, что отношения различаются в зависимости от порядка вращения. Это еще один важный источник головной боли. Опять же, вам нужно помнить о порядке вращения.

Тот, кто написал этот отчет, написал порядок ротаций как порядок иерархии, а не порядок применения.

Этот отчет НАСА и следующее являются хорошими ссылками на эти соотношения: Формулы угла Эйлера.

Координатные пространства

Основное применение линейной алгебры в разработке игр — отображение из одного координатного пространства в другое. Например, вершины 3D-модели представлены относительно начала координат 3D-модели. Когда 3D-модель помещается в игру, нам нужно знать, где вершины модели находятся в игре относительно начала игрового мира. Таким образом, мы отображаем координатное пространство модели в мировое координатное пространство.

Это чрезвычайно мощно. Это позволяет нам легко «преобразовывать» координату в пространстве модели в мировое пространство в пространство камеры в пространство экрана и обратно. Если мы использовали матрицу A для перехода из пространства модели в мировое пространство, мы просто используем обратную матрицу A для перехода из мирового пространства обратно в пространство модели. Действительное понимание координатных пространств и сопоставление между ними имеет решающее значение для компьютерной графики и разработки игрового движка. Это дает тебе столько силы. Преобразование между этими координатными пространствами лежит в основе графического конвейера. Если вы понимаете шаги, которые мы предпринимаем для сопоставления координат в мировом пространстве с пространством экрана, вы можете просто изменить эти шаги, чтобы перейти из пространства экрана в мировое пространство. Теперь, если игрок щелкает на экране в пикселях x: 300 и y: 500, вы знаете, как сопоставить этот щелчок в пространстве экрана с мировым пространством и выяснить, где в мире щелкнул игрок.

Использование несовпадающих координатных пространств — еще один источник путаницы и ошибок в компьютерной графике и разработке игр. У вас будут неправильные расчеты, если входные данные для ваших расчетов не все находятся в одном и том же координатном пространстве.

Заключение

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

Дальнейшее чтение















Первоначально опубликовано на https://kevch.in 12 декабря 2021 г.