четверг, 27 апреля 2017 г.

Angie Engine

Много времени прошло с последнего сообщения. Было много чего переписано/переделано/перелопачено, настолько много, что я не удержался и переименовал движок :)
Встречайте, Angie Engine.

Концептуально изменилось вообще все, от базовых core-классов, до высокоуровневых классов движка: сцен граф, рендерер, ресурс менеджер и т.д.

Архитектура построения сцены, теперь компонентная. Примеры таких архитектур - движки Unity3D и Urho3D. Сцена описывается узлами, объединенными в иерархию "parent-childs". Каждый узел описывает некоторую трансформацию в пространстве (позицию, поворот, масштаб). Функциональность узла определяется и расширяется компонентами.

Ресурсы отделены от сцены. В данный момент существуют следующие типы ресурсов:

Texture
  Любые растровые данные: albedo, normalmap, roughness, metallic, ambient, cubemap, texture array, cubemap array и т.д.

Material
 Материал описывает набор сэмплер-стейтов и констант (юниформов), которые можно менять из вне (например из кода игровой логики). Также материал содержит код (MaterialRoutine), который преобразуется на этапе загрузки материала в glsl шейдер (в будущем также в hlsl шейдер).
 Поддерживается инстансинг материалов. Один и тот-же материал может быть инстанцирован, а для каждого инстанса может быть установлен свой набор текстур и констант, что позволяет уменьшить переключение между шейдерами при рендеринге и эффективно сортировать материалы.

StaticMesh
 Статическая сетка. Совокупность вершинного и индексного буфера. Меши можно загружать из файлов/ассетов или модифицировать вручную, создавая процедурные меши.

DynamicMesh
 Динамическая сетка. Используется для геометрий, которые нуждаются в частой модификации. Кстати, на примере с vertex-based-анимацией на моделях из оригинального Quake используется DynamicMesh.



SkinnedMesh
 Меш со скелетом. Отличается от статического меша форматом вершин (каждая вершина привязана к одной и более костям и содержит веса) и наличием скелета.

SkinnedAnim
 Анимация для SkinnedMesh. Содержит анимацию для всех или группы костей скелета.

В процессе Audio.

Рендерер.
 Рендерер теперь Clustered Forward.
 Вкратце, это forward renderer, при этом фрустум разбивается на кластеры 16x8x24. В каждом кластере хранятся списки источников освещения, которые передаются в буфер на GPU. Для этого на каждом кадре происходит frustum-shaped-вокселизация/кластеризация OBB источников. Все - с использованием SIMD инструкций для оптимизаций (SSE). В шейдере по xyz фрагмента определяется индекс кластера, по индексу извлекается список источников освещения, которыми шейдится фрагмент.
 Ниже приведено видео вокселизации источника освещения в Angie Engine.


 Кластерный рендеринг, для примера, используется в idTech6 (Doom 4) и Avalanche Engine.

 Теперь про освещение. Теперь оно Physically-based (Physically based rendering). Была выбрана техника Metallic/Roughness вместо Specular/Glossiness, т.к. при одних и тех же результатах Metallic/Roughness менее затратна по памяти, т.к. требует всего 2 канала, вместо 4-х. Для отражения используется предрассчитанная Evironment probe. Скоро планируется добавить Screen space reflections (SSR).

 Для отсечения невидимой геометрии и невидимых источников освещения внедрена портальная система. Которую можно продемонстрировать на уровне из Doom 3, загруженном в Angie Engine:

...........видео будет чуть позже.................

 Есть возможность расширять систему отсечений невидимой геометрии, не изменяя сам движок. Так я, чисто по-фану, написал два примера загрузки уровней из Quake и Quake 3 Arena / Quake Live с их BSP/PVS системами. При этом, код движка остается без изменений, отсечение происходит на "верхнем" уровне. Геометрия - в StaticMesh:


В примере можно увидеть, что фильтрация mipmap nearest. Это настраивается через сэмплер-стейты материала, и в данном случае сделано, чтобы сцена с уровнем из Quake выглядела наиболее приближенно к оригиналу.