Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Архитектура современных 
3D движков 
Vitaliy Borodovsky 
Технический директор мобильного подразделения 
Wargaming
Универсальный движок 
Есть ли он, и где его искать…
Современные требования к технологии 
• Хорошие инструменты для создания контента 
• Конкурентноспособное качество всех модулей 
движка 
• Кросс платформенность 
• Высокая производительность 
• Поддержка целевого железа 
• Гибкость и расширяемость
Хорошие инструменты для создания 
к•онтента Высокое качество инструментов 
• Требования растут с каждым днем 
• Большой спектр инструментов 
• Для художников 
• Звуковиков 
• Программистов 
• и других 
• Возможности работать над контентом паралельно 
• Очень актуально для средних и больших комманд 
• Возможность быстро увидеть результат
Расширяемость 
• Гибкая и расширяемая архитектура 
• Легкость поддержки своего кастомного кода 
• Простота перехода на новые версии 
• Удобная инфраструктура 
• Интеграция с техническими сервисами
Кросс-платформенность 
• PC 
• Windows 
• Mac OS 
• Mobile 
• iOS 
• Android 
• Windows Mobile 
• Previous generation 
consoles 
• PS3 
• XBox 360 
• Current generation 
consoles 
• PS4 
• XBox 1
Производительность и железо 
• Огромное количество устройств в различных конфигурациях 
• Производитель GPU 
• Производитель CPU 
• Операционная система и ее версия 
• Выжать максимум из GPU 
• Совершенно разные требования в зависимости от железа 
• Различные API 
• Выжать максимум из CPU 
• Разные архитектуры, однако схожие проблемы 
• Эффективное использование многоядерных процессоров 
• Эффективная работа с памятью
Высокая сложность инженерных задач 
Operation 
Systems 
Graphics APIs 
CPU 
Windows XP 
DirectX 9 
Hardware 
ARM 
x86 
PPC 
GPU 
AMD 
nVidia 
Intel 
SoC GPU 
PowerVR 
Mali 
Adreno 
Tegra 
DirectX 11 
OpenGL & ES 
Metal 
Mantle 
PS4 API 
DX 12 
OpenGL 5 
???? 
Windows 7,8 
Windows 10 
Mac OS X 
iOS 
Android 
APIs 
Windows Phone 
* 3-7 поколений устройств каждого 
из производителей 
Координальные отличия 
Требует поддержки нескольких версий
Конкурентноспособное качество 
• Сложно добиться конкурентного качества на всех 
платформах 
• Для конкуренции на различных платформах 
требуются разные технологии 
• Разные платформы требуют различный 
оптимизаций 
• Однако есть части которые требуются на всех 
платформах
Задача выглядит очень сложной… 
Но есть же Unity и UE4! Зачем свой?
Проблемы универсального движка 
• Выбор общего знаменателя 
• Всегда будет ситуация когда выбор технического 
решения будет сделан в ущерб какой-небудь из 
платформ 
• Универсальный движок всегда хуже движка под 
конкретную игру 
• Платформы обновляются быстро 
• В универсальный движках, часто не хватает новых 
специфических фич платформы
U•nity Обладает массой свойств которые требуются современному 
движку, но есть минусы: 
• C# - создает дополнительные накладные расходы 
• Нет прямого доступа к железу 
• Не возможно выжать максимум из целевого железа 
• Отлично подходит для казуальных игр 
• Не подходит для игр, которые требуют выжать максимум из 
железа 
• Всегда найдутся команды, которые смогут получить 
конкурентное преимущество используя железо по максимуму, 
на своей технологии. 
• Игра - это всегда совокупность идеи и технологии!
UE4 
• Очень многообещающе 
• C++ и полный доступ к исходникам 
• Дает разработчикам полный контроль 
• Отличные инструменты 
• Минусы 
• Основные цели это новые консоли, решения принимаются не в пользу 
мобильных технологий 
• 5% royalty from gross revenue 
• Может быть большой процент от прибыли 
• Особенно для инди разработчиков 
• Часть решений основаны на предыдущем опыте, не идеальном в 
случае UE3
Плата за быструю разработку 
• Использование скриптовых языков или JIT компилируемых языков 
• Быстрая итерация 
• Меньше требования к разработчикам и скриптерам 
• Хорошо на этапе прототипирования, плохо в долгосрочной перспективе 
когда эти люди пишут реальный игровой код 
• Больше нагрузка на CPU 
• Меньше возможностей по выжиманию производительности из целевого 
железа 
• Некачественный код 
• Критично на мобильных платформах
C чего начинали мы
В 2011 году 
• Не было мобильных движков консольного качества 
• Unity не позволял делать то что требовалось проекту 
• Мы имели достаточно неплохую технологию, которая доказала 
себя на казуальных играх 
• Было принято решение доделывать свой движок 
• Учитывая что 3D не было, это было 95% работы 
• Сроки были сжатые 
• 1-ю версию движка и редактора сделали за 2 месяца 
• На первоначальном этапе разработки не всегда 
принимались взвешенные архитектурные решения
Художники увидели редактор в первый раз
Tools (2011-2012) 
• Большая архитектурная ошибка 
• Использовать игровой UI для 
редакторов 
• Не было undo-redo 
• Каждая ошибка дизайнеров 
требовала загрузить карту заново 
• Не было copy-paste 
• Не было переключений между 
элементами по табу 
• Художники с тех пор стали очень 
осторожными и терпеливыми!
Своя технология сейчас 
Мы пересмотрели многие подходы…
Философия 
• Использование современных подходов к 
проектированию архитектуры 
• Тчательный выбор технологий 
• Data-driven подход 
• Рефакторинг 
• Кросс-платформенный подход
Выбор основных технологий 
• C++ 
• Высокая производительность 
• Высокая портабельность 
• Qt для разработки Tools 
• Современная кросс-платформенная технология 
• Много примеров высококачественного софта 
• Движок может напрямую работать с UI 
• WinForms - требуется прослойка на C#, для 
движка
Cross-platform 
• Main focus is iOS & Android 
• Support from low-end to high-end mobile devices 
• PC & Mac 
• Focus on support of low-end PC & Mac with 
embedded video cards 
• Big market 
• Maximum usage of the hardware
Плюсы 
• Полный контроль и максимальная гибкость 
• Возможность менять ее в зависимости от платформ и требований 
• План развития который соответствует планам наших проектов 
• При правильном подходе 
• Возможность использовать по максимуму целевое железо 
• Конкурентное преимущество 
• Практически у всех разработчиков под консоли, свои технологии, 
по этой причине 
• Возможность быстрее итерировать 
• Не нужно ждать когда выпустят новую версию движка, мы 
получаем ее раз в месяц
Минусы 
• Титанический объем работы! 
• Очень высокие требования к команде 
разработчиков.
Подходы к архитектуре 
Наконец переходим к делу
Tools 
• Художникам нужны хорошие инструменты создания 
контента 
• Отдельных инструментов становится все больше и 
больше 
• Фичей в движке с каждым днем становится все 
больше и больше 
• Как можно эффективно разрабатывать, при 
небольшом количестве программистов на тулзах? 
• Data-driven UI
Wargaming.net: Архитектура современных 3D движков
Data-driven UI 
• Reflection / Introspection 
• UI генерируется исходя 
из типов данных которые 
присутствуют в объекте 
• Поддержка иерархий 
объектов 
• Динамическая 
интроспекция 
• Различные варианты 
представление 
одинаковых типов 
данных
Сложные системы движка 
Есть ли решения?
Рендер система 
• Низкоуровневая система 
• Разные API 
• C разными возможностями 
• Разными сложностями 
• Высокоуровневая система 
• Огромное количество алгоритмов 
• Часто очень непохожие друг на друга по принципам и 
требованиям к данным 
• Решение есть
Сцена - рассмотрим на примере 
• Комбинация множества сложных систем 
• Рендеринг 
• Физика 
• Коллизии 
• Анимации 
• Отсечение невидимой геометрии 
• Лоды 
• Скрипты 
• Пользовательская логика 
• и многое другое
Граф сцены 
• ООП подход 
• Полиморфизм 
• Базовый класс 
• Наследники 
SceneNode 
RenderNode 
LODNode 
OtherNode 
Matrix4 localTransform; 
Matrix4 worldTransform; 
Vector<SceneNode*>children; 
virtual void Update() 
virtual void Draw() 
Вроде все просто? 
Не так уж и просто!
Объектно-ориентированное 
пр•оЧгтроа тмакмоие рОоОвПание 
• a programming paradigm that uses "objects" – data 
structures consisting of datafields and methods 
together with their interactions – to design applications 
and computer programs. (Wikipedia) 
• Includes features such as 
• Абстракция данных 
• Инкапсуляция 
• Полиморфизм 
• – Inheritance
Для чего нужно ООП 
• ОО программирование позволяет думать о 
проблемах в терминах объектов и их 
взаимодействий 
• Каждый объект в идеале самодостаточен 
• Содержит в себе свои данные и код 
• Предоставляет интерфейс для взаимодействия 
• Каждый объект может быть представлен как black 
box
Объекты 
• Если объекты самодостаточны 
• Они могут быть повторно использованы 
• Они могут быть изменены, без влияния на 
внешнюю среду 
• Использованы без понимания их внутренней 
структуры 
• Это ведь хорошо, да?
Объекты это ведь хорошо? 
• Да, 
• Нет 
• Немного истории…
C++ 
• Выпущен в 1979 
• Стандартизирован в 1998 
• Новый стандарт в 2003 и 2011 
• За это время, произошло множество изменений: 
• С++ претерпел значительные изменения 
• CPU стали намного быстрее 
• Память тоже стала быстрее 
• Появились многоядерные процессоры
Производительность CPU
Производительность CPU / Memory
Что изменилось с 1979? 
• 1980 - RAM latency - 1 цикл 
• 2010 - RAM latency - 400 циклов * 2 - 4 ядра 
• 2014 - RAM latency - 400-600 cycles * 4-8 ядра 
• Что можно сделать за 400-600 циклов?
На современном железе 
• Инкапсуляция данных это очень плохо! 
• Производительность может быть увеличена в разы, 
при другом подходе к данным 
• Железо диктует органичения, но само ООП, это 
же отличная парадигма, да?
ООП это ведь хорошо? 
• Да? 
• Нет!
Проблемы ООП подхода 
• Наследование и полиморфизм 
• Код написанный в объекте, влияет на всех его 
потомков 
• Высокая связность 
• Разнородный код, выполняется вперемешку 
• virtual Update(), virtual Draw(), virtual Anything()… 
• Сложно эффективно использовать многопоточность 
• С++ статический язык
Немного усложним 
BaseNode 
JointNode 
PhysicalNode 
CollisionNode 
RenderNode 
ContainerNode 
LODNode 
SwitchNode 
SoundNode 
VehicleNode 
ScriptNode 
SkinnedNode 
• Как наследовать классы и не 
ошибиться? 
• Есть классы которые просятся 
ниже 
• AnimationNode - любой 
объект, может быть 
анимированным 
• Physics, Collision, Script 
AnimationNode аналогично 
TransformNode
Множественное наследование? 
Композиция? 
BaseNode 
JointNode 
PhysicalNode 
CollisionNode 
SkinnedNode 
RenderNode 
ContainerNode 
LODNode 
SwitchNode 
SoundNode 
VehicleNode 
ScriptNode 
AnimationNode 
TransformNode 
?
Композиция 
BaseNode 
Animation 
Collision 
Physics 
Script 
etc… 
JointNode VehicleNode 
PhysicalNode 
SkinnedNode 
RenderNode 
ContainerNode 
LODNode 
SwitchNode 
SoundNode 
Мега класс TransformNode 
Мега Update
В• цОибфхорд а50х00 тысяч нод, без трансформаций (8 ms на iPad 
2) 
• if (flags & NODE_REQUIRE_UPDATE)return; 
• Обход 11,111 объектов, без трансформаций (4ms на 
PS3) 
• Почему 
• Неэффективное использование кэша 
• В среднем 2-4 кэш мисса, при переходе к следующему 
объекту 
• Обращение к vtbl, обращение к flags 
• Быстрое переполнение кэша
Поддержка ООП кода 
• Любое изменение в базовом классе требует полное 
тестирование всего движка 
• Чем сложнее система, тем больше объем работы, 
при малейшем изменении 
• Виртуальные функции влияющие на потомков, 
являются постоянным источником проблем 
• Для сложных игровых систем 
• Наследники могут ломать логику оригинальных 
классов 
• Влияние классов друг на друга значительно
Другие подходы 
• Data-driven paradigm - in which the program statements describe 
the data to be matched and the processing required rather than 
defining a sequence of steps to be taken. 
• Оперируем над однородными данными 
• Алгоритмы преобразовывают входные данные в выходные 
данные 
• Component-based paradigm 
• It is a reuse-based approach to defining, implementing and 
composing loosely coupled independent components into 
systems. 
• Слабосвязные компоненты 
• Пример: unix tools, промышленная электроника
Data-driven подход к той же проблеме 
• Есть данные 
• TransformComponent 
• RenderComponent 
• LODComponent 
• PhysicsComponent 
• и др. 
• Для каждого однотипного массива данных мы выполняем необходимые 
операции 
• For each transform in transformComponentArray 
• Perform Transform 
• For each renderComponent in renderComponentArray 
• Call Render
Что мы получаем 
• Независимые потоки выполнения подсистем 
• Слабая связность 
• Легко оптимизировать 
• Легко разложить на многоядерные процессоры 
• Можно расположить данные для подсистем 
линейно, в удобном для них виде 
• Как связать компоненты воедино?
Entity 
• Entity - сущность 
• Только ID 
• Список принадлежащих этой entity компонентов
Г•деКо пд ив скоамтпьо нкеонтда?х 
• virtual void 
Component::Process() 
• Гибко, и красиво, но мы 
попадаем в ту же ловушку 
наследования 
• Появляются разнородные 
данные, обрабатываемые 
через одинаковые классы. 
• Проблема меньше чем с мега- 
классом, но все еще не идеал 
• Код должен быть отдельно!
Entity-Component-System парадигма 
Entity 
ID 
Components 
Только связь 
Component 
Data *optional Data 
Только 
данные 
System 
Алгоритм 
Scene 
Process all systems
Реальный пример 
Components 
Render 
Transform 
Collision 
Physics 
Animation 
Script 
Sound 
Particle 
More 
Systems 
Render Update System - update render system with info from others 
TransformSystem - perform transformations 
CollisionSystem - perform collisions 
Physics - calculate physics 
AnimationSystem - system to transform animations 
ScriptSystem - system to perform scripts 
SoundUpdateSystem - update positions from world to sound engine 
ParticleUpdateSystem - update particle systems 
UpdateSystem, OcclusionSystem, CullingSystem and many others
Плюсы 
• Легко добавлять новую функциональность 
• Слабая связность, помогает реже ломать 
написанный код 
• Нет потока кода (логики), который управляет 
программой, тоже приводит к большей стабильности 
кода при изменениях 
• Можно легко параллелить на несколько ядер 
• Позволяет расположить данные линейно 
• Системы могут перекладывать данные таким образом 
как им это удобно
Сложные случаи 
Components 
TransformComponent 
LookAtComponent 
Systems 
TransformSystem 
LookAtSystem
Сложные случаи 
Components 
TransformComponent 
LookAtComponent 
Entity1 
Systems 
TransformSystem 
LookAtSystem 
TransformComponent 
Entity2 
LookAtComponent 
Entity3 
TransformComponent 
Entity4 
LookAtComponent
Сложные случаи 
Components 
TransformComponent 
LookAtComponent 
Entity1 
Systems 
TransformSystem 
LookAtSystem 
TransformComponent 
Entity2 
LookAtComponent 
Entity3 
TransformComponent 
Entity4 
LookAtComponent
Сложные случаи 
Components 
TransformComponent 
LookAtComponent 
Entity1 
Systems 
TransformSystem 
LookAtSystem 
TransformComponent 
Entity2 
LookAtComponent 
Entity3 
TransformComponent 
Entity4 
LookAtComponent
Как решать 
• Dependency Manager 
• Определяет зависимости между компонентами, группирует их в 
списки, вызывает Process системам в правильном порядке 
• Красиво, но сложно. 
• TransformComponent, LookAtComponent - оба работают с одними 
данными 
• Могут быть частью одной TransformSystem-ы 
• Связывает все в одну систему. 
• Зависимость между системами 
• LookAtSystem вызывает Process для TransformSystem 
• Просто в реализации
Что почитать 
• Artemis 
• http://gamadu.com/artemis/tutorial.html 
• T-machine blog 
• http://t-machine.org/index.php/2007/09/03/entity-systems-are-the- 
future-of-mmog-development-part-1/ 
• Stack overflow links: 
• http://stackoverflow.com/questions/1901251/component-based-game- 
engine-design 
• DAVA Framework 
• https://github.com/dava/dava.framework
Что делать, если ошибся? 
Терпеть? Или переписывать?
Ни то, ни другое 
Баланс ключ к успеху
Баланс это сложно 
• Старайтесь найти время на переработку архитектуры 
• Если в порядке архитектура, это откроет новые возможности в 
будущем 
• Не обязательно делать все сразу 
• Итеративный подход понимая где ваша цель 
• Анализ того что вы получите по итогу 
• Наш переход от SceneGraph к Entity Component System был 
болезненным 
• Мы не смогли все сделать сразу, ввиду сроков по проекту 
• Не смогли сделать JOB-ы и multithreading 
• Помните, что заложив правильный фундамент, кирпичи можно 
положить потом
Маленькие вещи 
Иногда экономят много времени
Launcher 
• Similar to Tanks Game Launcher 
• List of tools with latest versions 
• Stable versions updated automatically 
• Artists are happy! Because they always have latest 
version.
Спасибо! 
Вопросы?

More Related Content

Wargaming.net: Архитектура современных 3D движков

  • 1. Архитектура современных 3D движков Vitaliy Borodovsky Технический директор мобильного подразделения Wargaming
  • 2. Универсальный движок Есть ли он, и где его искать…
  • 3. Современные требования к технологии • Хорошие инструменты для создания контента • Конкурентноспособное качество всех модулей движка • Кросс платформенность • Высокая производительность • Поддержка целевого железа • Гибкость и расширяемость
  • 4. Хорошие инструменты для создания к•онтента Высокое качество инструментов • Требования растут с каждым днем • Большой спектр инструментов • Для художников • Звуковиков • Программистов • и других • Возможности работать над контентом паралельно • Очень актуально для средних и больших комманд • Возможность быстро увидеть результат
  • 5. Расширяемость • Гибкая и расширяемая архитектура • Легкость поддержки своего кастомного кода • Простота перехода на новые версии • Удобная инфраструктура • Интеграция с техническими сервисами
  • 6. Кросс-платформенность • PC • Windows • Mac OS • Mobile • iOS • Android • Windows Mobile • Previous generation consoles • PS3 • XBox 360 • Current generation consoles • PS4 • XBox 1
  • 7. Производительность и железо • Огромное количество устройств в различных конфигурациях • Производитель GPU • Производитель CPU • Операционная система и ее версия • Выжать максимум из GPU • Совершенно разные требования в зависимости от железа • Различные API • Выжать максимум из CPU • Разные архитектуры, однако схожие проблемы • Эффективное использование многоядерных процессоров • Эффективная работа с памятью
  • 8. Высокая сложность инженерных задач Operation Systems Graphics APIs CPU Windows XP DirectX 9 Hardware ARM x86 PPC GPU AMD nVidia Intel SoC GPU PowerVR Mali Adreno Tegra DirectX 11 OpenGL & ES Metal Mantle PS4 API DX 12 OpenGL 5 ???? Windows 7,8 Windows 10 Mac OS X iOS Android APIs Windows Phone * 3-7 поколений устройств каждого из производителей Координальные отличия Требует поддержки нескольких версий
  • 9. Конкурентноспособное качество • Сложно добиться конкурентного качества на всех платформах • Для конкуренции на различных платформах требуются разные технологии • Разные платформы требуют различный оптимизаций • Однако есть части которые требуются на всех платформах
  • 10. Задача выглядит очень сложной… Но есть же Unity и UE4! Зачем свой?
  • 11. Проблемы универсального движка • Выбор общего знаменателя • Всегда будет ситуация когда выбор технического решения будет сделан в ущерб какой-небудь из платформ • Универсальный движок всегда хуже движка под конкретную игру • Платформы обновляются быстро • В универсальный движках, часто не хватает новых специфических фич платформы
  • 12. U•nity Обладает массой свойств которые требуются современному движку, но есть минусы: • C# - создает дополнительные накладные расходы • Нет прямого доступа к железу • Не возможно выжать максимум из целевого железа • Отлично подходит для казуальных игр • Не подходит для игр, которые требуют выжать максимум из железа • Всегда найдутся команды, которые смогут получить конкурентное преимущество используя железо по максимуму, на своей технологии. • Игра - это всегда совокупность идеи и технологии!
  • 13. UE4 • Очень многообещающе • C++ и полный доступ к исходникам • Дает разработчикам полный контроль • Отличные инструменты • Минусы • Основные цели это новые консоли, решения принимаются не в пользу мобильных технологий • 5% royalty from gross revenue • Может быть большой процент от прибыли • Особенно для инди разработчиков • Часть решений основаны на предыдущем опыте, не идеальном в случае UE3
  • 14. Плата за быструю разработку • Использование скриптовых языков или JIT компилируемых языков • Быстрая итерация • Меньше требования к разработчикам и скриптерам • Хорошо на этапе прототипирования, плохо в долгосрочной перспективе когда эти люди пишут реальный игровой код • Больше нагрузка на CPU • Меньше возможностей по выжиманию производительности из целевого железа • Некачественный код • Критично на мобильных платформах
  • 16. В 2011 году • Не было мобильных движков консольного качества • Unity не позволял делать то что требовалось проекту • Мы имели достаточно неплохую технологию, которая доказала себя на казуальных играх • Было принято решение доделывать свой движок • Учитывая что 3D не было, это было 95% работы • Сроки были сжатые • 1-ю версию движка и редактора сделали за 2 месяца • На первоначальном этапе разработки не всегда принимались взвешенные архитектурные решения
  • 18. Tools (2011-2012) • Большая архитектурная ошибка • Использовать игровой UI для редакторов • Не было undo-redo • Каждая ошибка дизайнеров требовала загрузить карту заново • Не было copy-paste • Не было переключений между элементами по табу • Художники с тех пор стали очень осторожными и терпеливыми!
  • 19. Своя технология сейчас Мы пересмотрели многие подходы…
  • 20. Философия • Использование современных подходов к проектированию архитектуры • Тчательный выбор технологий • Data-driven подход • Рефакторинг • Кросс-платформенный подход
  • 21. Выбор основных технологий • C++ • Высокая производительность • Высокая портабельность • Qt для разработки Tools • Современная кросс-платформенная технология • Много примеров высококачественного софта • Движок может напрямую работать с UI • WinForms - требуется прослойка на C#, для движка
  • 22. Cross-platform • Main focus is iOS & Android • Support from low-end to high-end mobile devices • PC & Mac • Focus on support of low-end PC & Mac with embedded video cards • Big market • Maximum usage of the hardware
  • 23. Плюсы • Полный контроль и максимальная гибкость • Возможность менять ее в зависимости от платформ и требований • План развития который соответствует планам наших проектов • При правильном подходе • Возможность использовать по максимуму целевое железо • Конкурентное преимущество • Практически у всех разработчиков под консоли, свои технологии, по этой причине • Возможность быстрее итерировать • Не нужно ждать когда выпустят новую версию движка, мы получаем ее раз в месяц
  • 24. Минусы • Титанический объем работы! • Очень высокие требования к команде разработчиков.
  • 25. Подходы к архитектуре Наконец переходим к делу
  • 26. Tools • Художникам нужны хорошие инструменты создания контента • Отдельных инструментов становится все больше и больше • Фичей в движке с каждым днем становится все больше и больше • Как можно эффективно разрабатывать, при небольшом количестве программистов на тулзах? • Data-driven UI
  • 28. Data-driven UI • Reflection / Introspection • UI генерируется исходя из типов данных которые присутствуют в объекте • Поддержка иерархий объектов • Динамическая интроспекция • Различные варианты представление одинаковых типов данных
  • 29. Сложные системы движка Есть ли решения?
  • 30. Рендер система • Низкоуровневая система • Разные API • C разными возможностями • Разными сложностями • Высокоуровневая система • Огромное количество алгоритмов • Часто очень непохожие друг на друга по принципам и требованиям к данным • Решение есть
  • 31. Сцена - рассмотрим на примере • Комбинация множества сложных систем • Рендеринг • Физика • Коллизии • Анимации • Отсечение невидимой геометрии • Лоды • Скрипты • Пользовательская логика • и многое другое
  • 32. Граф сцены • ООП подход • Полиморфизм • Базовый класс • Наследники SceneNode RenderNode LODNode OtherNode Matrix4 localTransform; Matrix4 worldTransform; Vector<SceneNode*>children; virtual void Update() virtual void Draw() Вроде все просто? Не так уж и просто!
  • 33. Объектно-ориентированное пр•оЧгтроа тмакмоие рОоОвПание • a programming paradigm that uses "objects" – data structures consisting of datafields and methods together with their interactions – to design applications and computer programs. (Wikipedia) • Includes features such as • Абстракция данных • Инкапсуляция • Полиморфизм • – Inheritance
  • 34. Для чего нужно ООП • ОО программирование позволяет думать о проблемах в терминах объектов и их взаимодействий • Каждый объект в идеале самодостаточен • Содержит в себе свои данные и код • Предоставляет интерфейс для взаимодействия • Каждый объект может быть представлен как black box
  • 35. Объекты • Если объекты самодостаточны • Они могут быть повторно использованы • Они могут быть изменены, без влияния на внешнюю среду • Использованы без понимания их внутренней структуры • Это ведь хорошо, да?
  • 36. Объекты это ведь хорошо? • Да, • Нет • Немного истории…
  • 37. C++ • Выпущен в 1979 • Стандартизирован в 1998 • Новый стандарт в 2003 и 2011 • За это время, произошло множество изменений: • С++ претерпел значительные изменения • CPU стали намного быстрее • Память тоже стала быстрее • Появились многоядерные процессоры
  • 40. Что изменилось с 1979? • 1980 - RAM latency - 1 цикл • 2010 - RAM latency - 400 циклов * 2 - 4 ядра • 2014 - RAM latency - 400-600 cycles * 4-8 ядра • Что можно сделать за 400-600 циклов?
  • 41. На современном железе • Инкапсуляция данных это очень плохо! • Производительность может быть увеличена в разы, при другом подходе к данным • Железо диктует органичения, но само ООП, это же отличная парадигма, да?
  • 42. ООП это ведь хорошо? • Да? • Нет!
  • 43. Проблемы ООП подхода • Наследование и полиморфизм • Код написанный в объекте, влияет на всех его потомков • Высокая связность • Разнородный код, выполняется вперемешку • virtual Update(), virtual Draw(), virtual Anything()… • Сложно эффективно использовать многопоточность • С++ статический язык
  • 44. Немного усложним BaseNode JointNode PhysicalNode CollisionNode RenderNode ContainerNode LODNode SwitchNode SoundNode VehicleNode ScriptNode SkinnedNode • Как наследовать классы и не ошибиться? • Есть классы которые просятся ниже • AnimationNode - любой объект, может быть анимированным • Physics, Collision, Script AnimationNode аналогично TransformNode
  • 45. Множественное наследование? Композиция? BaseNode JointNode PhysicalNode CollisionNode SkinnedNode RenderNode ContainerNode LODNode SwitchNode SoundNode VehicleNode ScriptNode AnimationNode TransformNode ?
  • 46. Композиция BaseNode Animation Collision Physics Script etc… JointNode VehicleNode PhysicalNode SkinnedNode RenderNode ContainerNode LODNode SwitchNode SoundNode Мега класс TransformNode Мега Update
  • 47. В• цОибфхорд а50х00 тысяч нод, без трансформаций (8 ms на iPad 2) • if (flags & NODE_REQUIRE_UPDATE)return; • Обход 11,111 объектов, без трансформаций (4ms на PS3) • Почему • Неэффективное использование кэша • В среднем 2-4 кэш мисса, при переходе к следующему объекту • Обращение к vtbl, обращение к flags • Быстрое переполнение кэша
  • 48. Поддержка ООП кода • Любое изменение в базовом классе требует полное тестирование всего движка • Чем сложнее система, тем больше объем работы, при малейшем изменении • Виртуальные функции влияющие на потомков, являются постоянным источником проблем • Для сложных игровых систем • Наследники могут ломать логику оригинальных классов • Влияние классов друг на друга значительно
  • 49. Другие подходы • Data-driven paradigm - in which the program statements describe the data to be matched and the processing required rather than defining a sequence of steps to be taken. • Оперируем над однородными данными • Алгоритмы преобразовывают входные данные в выходные данные • Component-based paradigm • It is a reuse-based approach to defining, implementing and composing loosely coupled independent components into systems. • Слабосвязные компоненты • Пример: unix tools, промышленная электроника
  • 50. Data-driven подход к той же проблеме • Есть данные • TransformComponent • RenderComponent • LODComponent • PhysicsComponent • и др. • Для каждого однотипного массива данных мы выполняем необходимые операции • For each transform in transformComponentArray • Perform Transform • For each renderComponent in renderComponentArray • Call Render
  • 51. Что мы получаем • Независимые потоки выполнения подсистем • Слабая связность • Легко оптимизировать • Легко разложить на многоядерные процессоры • Можно расположить данные для подсистем линейно, в удобном для них виде • Как связать компоненты воедино?
  • 52. Entity • Entity - сущность • Только ID • Список принадлежащих этой entity компонентов
  • 53. Г•деКо пд ив скоамтпьо нкеонтда?х • virtual void Component::Process() • Гибко, и красиво, но мы попадаем в ту же ловушку наследования • Появляются разнородные данные, обрабатываемые через одинаковые классы. • Проблема меньше чем с мега- классом, но все еще не идеал • Код должен быть отдельно!
  • 54. Entity-Component-System парадигма Entity ID Components Только связь Component Data *optional Data Только данные System Алгоритм Scene Process all systems
  • 55. Реальный пример Components Render Transform Collision Physics Animation Script Sound Particle More Systems Render Update System - update render system with info from others TransformSystem - perform transformations CollisionSystem - perform collisions Physics - calculate physics AnimationSystem - system to transform animations ScriptSystem - system to perform scripts SoundUpdateSystem - update positions from world to sound engine ParticleUpdateSystem - update particle systems UpdateSystem, OcclusionSystem, CullingSystem and many others
  • 56. Плюсы • Легко добавлять новую функциональность • Слабая связность, помогает реже ломать написанный код • Нет потока кода (логики), который управляет программой, тоже приводит к большей стабильности кода при изменениях • Можно легко параллелить на несколько ядер • Позволяет расположить данные линейно • Системы могут перекладывать данные таким образом как им это удобно
  • 57. Сложные случаи Components TransformComponent LookAtComponent Systems TransformSystem LookAtSystem
  • 58. Сложные случаи Components TransformComponent LookAtComponent Entity1 Systems TransformSystem LookAtSystem TransformComponent Entity2 LookAtComponent Entity3 TransformComponent Entity4 LookAtComponent
  • 59. Сложные случаи Components TransformComponent LookAtComponent Entity1 Systems TransformSystem LookAtSystem TransformComponent Entity2 LookAtComponent Entity3 TransformComponent Entity4 LookAtComponent
  • 60. Сложные случаи Components TransformComponent LookAtComponent Entity1 Systems TransformSystem LookAtSystem TransformComponent Entity2 LookAtComponent Entity3 TransformComponent Entity4 LookAtComponent
  • 61. Как решать • Dependency Manager • Определяет зависимости между компонентами, группирует их в списки, вызывает Process системам в правильном порядке • Красиво, но сложно. • TransformComponent, LookAtComponent - оба работают с одними данными • Могут быть частью одной TransformSystem-ы • Связывает все в одну систему. • Зависимость между системами • LookAtSystem вызывает Process для TransformSystem • Просто в реализации
  • 62. Что почитать • Artemis • http://gamadu.com/artemis/tutorial.html • T-machine blog • http://t-machine.org/index.php/2007/09/03/entity-systems-are-the- future-of-mmog-development-part-1/ • Stack overflow links: • http://stackoverflow.com/questions/1901251/component-based-game- engine-design • DAVA Framework • https://github.com/dava/dava.framework
  • 63. Что делать, если ошибся? Терпеть? Или переписывать?
  • 64. Ни то, ни другое Баланс ключ к успеху
  • 65. Баланс это сложно • Старайтесь найти время на переработку архитектуры • Если в порядке архитектура, это откроет новые возможности в будущем • Не обязательно делать все сразу • Итеративный подход понимая где ваша цель • Анализ того что вы получите по итогу • Наш переход от SceneGraph к Entity Component System был болезненным • Мы не смогли все сделать сразу, ввиду сроков по проекту • Не смогли сделать JOB-ы и multithreading • Помните, что заложив правильный фундамент, кирпичи можно положить потом
  • 66. Маленькие вещи Иногда экономят много времени
  • 67. Launcher • Similar to Tanks Game Launcher • List of tools with latest versions • Stable versions updated automatically • Artists are happy! Because they always have latest version.

Editor's Notes

  1. Чем сложнее система, тем сложнее поддерживать и тестировать С ростом сложности систем часто есть желание опустить класс на уровень ниже Или все полиморфно, или каждый класс при использовании намертво связывает тот кусок кода в котором он используется
  2. Нет данных которые лежат последовательно