Координатные пространства/Coordinate Space в компьютерной графике. Объясняю на чайниках 🫖
В этой статье вы узнаете:
1.Что такое пространство?
2.О самых распространенных пространствах:
- World Space
 - Object/Local Space
 - Camera/View Space
 - Tangent Space
 
3.Причем тут трансформ и умножение матриц?
4.И о том, как их можно использовать на примерах:
- Шейдер заснеженного камня
 - Паралакс Шейдер
 
Что понадобится
🧑💻 Опыт работы с игровым движком или 3D софтом
📐 Пространственное мышление
☕ Чашечка кая/чофе
Что такое пространство?
Пространство - это координатная система, которая начинается из Точки отсчета/Нулевой координаты/Ориджина/Пивота с направляющими векторами, абсциссой, ординатой и аппликатой, они же X,Y,Z направляющие.
Объекты, находящиеся в пространстве, занимают Положение и Направление относительно Пивота пространства и его Направляющих.
Примеры направляющих из вьюпорта обычно используют World Space направляющие относительно направления камеры.
Обратите внимание, UP вектор в Unity использует значение Y, в отличии от прочих, использующих Z.
Важно понимать, что идентичная концепция, может иметь разное представление в отличной среде.
Пространства могут иметь и прочую размерность, в этой статье мы будем говорить исключительно о Эвклидовых пространствах.
Распространенные пространства
1.World Space
Из названия понятно, что это пространство Мира в котором существует сцена/левел. Она статична и любой объект созданный напрямую в сцене сразу попадает в World Space.
Передвигая объект, изменяется и его положение в World Space, которое наглядно демонстрирует компонент Transform в поле Location.
2.Object/Local Space
Каждый объект так же имеет собственное(локальное) пространство, начало которого определено его пивотом.
Статичный объект внутри Object Space, сохраняет свое положение вне зависимости от положения в World Space.
3.Camera/View Space
Аналогично Object Space, Camera Space так же располагается в объекте, но в этом случае конкретно в камере.
Фиксирован одним вектором в глубину, и наверх/вправо остальными, что делает его положение на экране всегда предсказуемым.
4.Tangent Space
Пожалуй сложнейшее для понимания и объяснения пространство.
Каждая вершина объекта обладает собственным пространством, которое всегда перпендикулярно Нормали и определяет направления Касательной и Бинормали на основе UV координат.
Звучит сложно, попробуем изобразить наглядно.
Мы не ограничены вершинами, пространство так же ожидаемо работает и с Fragment контекстом после интерполяции.
Причем тут трансформ и умножение матриц?
Данные о положении и направлении хранит и изменяет компонент Transform, найти который вы можете в любом софте.
Все они обладают подобным набором свойств и выполняют идентичные функции.
Помимо положения в пространстве, пара важных параметров Scale и Rotation, которые отвечают за величину и направление объекта в пространстве соответственно.
В случаях, когда мы приводим объект из одного пространства в другое, меняются и его значения Transform. Очень кстати, что Transform хранит данные в матричном виде. Это открывает нам путь к использованию матричных операций/свойств/функций.
В этой статье мы не будем вдаваться в эту тему, просто скажем, что такая возможность у нас есть :^>
Если вам все же интересно капнуть глубже, рекомендую посмотреть крутое видео Джона Чапмана, объясняющего преобразования матриц для компьютерной графики и почему это так охренительно и производительно!
Или видео 3Blue1Brown, который объясняет все тоже самое в графическом виде.
Как применить эти знания?
Часто мы сталкиваемся с пространствами когда дело доходит до шейдеров, частиц, анимации и иерархий объектов. Здесь же я приведу некоторые примеры шейдерных реализаций.
Заснеженный камень
Создадим простой материал с базовым цветом и нормалью, используем его на меше.
Добавим текстуры снега и Lerp между схожими текстурами для смешивания.
Остается найти значение, на основе которого будет выбрана текстура.
Нам известно, что снег падающий на объект, с большей вероятностью находится на поверхности направленной к облакам.
В этом случае, нормаль поверхности объекта, напрямую сообщает о коэффициенте смешивания.
Сейчас нормаль объект находится в Tangent Space, для того что бы перевести ее в World Space воспользуемся функцией Transform.
Для репрезентации UP вектора, нам достаточно использовать значение Z, X и Y вектора находятся в перпендикулярной плоскости и не влияют на результат.
Используем значение Z в качестве коэффициента для Lerp предварительно его заклемпив от 0 до 1.
Добавил SmoothStep для усиления контраста.
Таким образом, вне зависимости от положения объекта, нормаль, направленная вверх относительно World Space, всегда будет заснежена, и наоборот.
Но что, если мы хотим использовать заснеженную часть по отношению к объекту, что бы снег всегда оставался на его оригинальной макушке?
В этом случае воспользуемся преобразованием в Object Space.
Теперь нормали будут смотреть вверх относительно локального пространства объекта и следовать за его направлением.
Паралакс Шейдер
Возможно вы уже сталкивались с подобными эффектами, в них картинка как бы наложена поверх объекта вне зависимости от его положения.
Выглядит круто, и скрывает под собой простую реализацию.
Для начала возьмем подходящий меш и затайленую текстуру космоса.
Я буду использовать крутой меч, который нашел на Scetchfab
В BaseColor мапу добавляем область которую мы будем красить шейдером в альфаканал.
Находим изображение с космической пылью.
Для своего примера, отчистил подходящее от звезд нейросетями, после чего затайлил используя PixPlant.
Отдельно собираем звезды на на альфа канале, которые добавят глубины.
Собираем базовый материал и располагаем меч на сцене.
Добавим значения Alpha канала из BaseColor в качестве параметра смешивания через Lerp с текстурой космоса.
На текстуре заметны швы в местах с разорванной разверткой, сама текстура просто наложена поверх меча и статична.
Чтобы решить эту проблему, попробуем представить пространство нашего экрана в качестве UV координат в ширину и высоту, эти данные мы можем получить используя преобразование TransformPosition из Object Space в Camera Space.
Теперь вне зависимости от положения объекта или камеры, мы всегда будем получать UV на плоскости экрана.
Семплируем текстуру используя эти координаты и добавим контроллер масштаба UV координат.
Добавим поверх пару слоев со звездами используя разное масштабирование и их альфа канал в качестве масок смешивания.
Все еще не хватает объема, текстуры как бы приклеены друг к другу. Добавим движения с разной скоростью на основе времени.
...Но мы можем лучше!
Унесем яркие звезды на Emmisive слой, добавим шумов для блеска, приглушим свет иии...
Благодарю за прочтение и, разумеется,
Если у вас есть желание поддержать автора статьи, то вы можете:
-Бахнуть по кнопке лайк, чтобы она взорвалась ❤
-Поделиться этой статьёй с людьми, которым интересна тема компьютерной графики.
-Подписаться на мой блог:
-Оставить фидбек под статьёй и пожелания о топиках, которые были бы вам интересны.
-Типнуть на кофеёк
Деловая почта: shakoretka@yandex.ru