Введение
«Графика стала слишком сложной».
В последние годы я всё чаще слышу подобные фразы: программирование графики теперь настолько сложно изучать, что это демотивирует людей осваивать его как хобби и/или профессию, или заставляет их сдаться. Я глубоко очарован этой областью программирования, поэтому подобные комментарии всегда бьют по больному. Программирование графики для игр — это специализация, приносящая невероятное удовольствие, она постоянно эволюционирует и обновляется, к тому же имеет (по большей части) одно из лучших сообществ программистов, развивающееся благодаря активному обмену информацией. Так что же происходит?
Это сложно объяснить, но произносящие такие фразы в чём-то правы.
Когда я начал писать этот пост пару месяцев назад, он был совершенно другим, по сути, в нём аргументировалась необходимости создания высокоуровневой (как DX11, но лучше) API-обёртки для D3D12.
Но чем больше я писал, тем сильнее понимал, что проблема сложнее, чем кажется, а после публикации этого опроса в Twitter я убедился, что единого, подходящего всем решения для изучения графики больше не существует.
Кто-то может сказать «но и раньше его не было», и будет прав, но за последние годы разрыв увеличился. Давайте поговорим об этом.
«Фулстек-программистов» графики больше нет
Именно это расстраивает многих людей, не понимающих, что за последние несколько лет ситуация в отрасли значительно изменилась. Можно спорить о том, когда это случилось конкретно, но думаю, можно сказать, что смерть фулстек-программиста графики произошла примерно в 2013 году. Для контекста добавлю, что в этом же году я начал работать в этой сфере, поэтому в то время многие изменения остались для меня незамеченными.
В 2013 году отрасль начала эволюционировать в сторону усложнения программирования игровой графики. С одной стороны, в играх появился физически корректный рендеринг (PBR), что видно из этого курса SIGGRAPH 2013: Physically Based Shading in Theory and Practice; с другой стороны, был выпущен Mantle API компании AMD.
Это означало, что игровая графика была на грани значительного расширения возможностей, и на то были причины. Благодаря PBR мы совершили рывок из эпохи Блинна-Фонга и стремились переосмыслить конвейеры создания графики, а Mantle обеспечивал нам низкоуровневый API, наконец-то давший инструменты для снижения нагрузки на ЦП, повышаемой функциями графического CPU (например, вызовами отрисовки или созданием конвейеров), что в то время считалось основным ограничивающим фактором. До этого программисты графики часто работали над всеми уровнями «стека», но сегодня такое можно увидеть всё реже. Кажется, впервые наглядно я увидел это в «The Technical Interview [LEAKED]» Анджело Пеше.
Хотя разделение на подспециализации в игровой графике зависит от проекта, оно бесспорно существует. Помните об этом, когда ощутите, что в разработке графики слишком много всего, и уделите время выбору той специализации, которая интереснее вам больше всего.
Лично я тяготею к специализации на движках/API и имеют посредственное (но достаточное) понимание других областей, а если бы вы посмотрели на ребят, которых я нанимал в нашу команду ZeniMax Online Studio, то увидели бы, что я искал людей с разной экспертизой, чтобы закрыть весь необходимый спектр знаний. Вместе мы образуем всесторонне развитую команду!
Если вас привлекла эта сфера, то вы, вероятно, задаётесь вопросом, с чего же начать. Судя по моему опросу, «правильной» точки старта не существует; по крайней мере, невозможно найти ту, с которой были бы согласны все специалисты. Вот мои рекомендации с учётом этого (на момент написания статьи, 2021 год).
С чего мне начинать?
«Я не знаю, чего хочу, или хочу познакомиться с большинством аспектов программирования графики»
Насколько я понимаю, https://learnopengl.com/ — лучший ресурс для изучения основных частей программирования графики. Начните с начала и пройдите весь путь, этот процесс позволит понять, что же вам интересно.
«Мне хочется чего-то визуального и с быстрой обратной связью, или я хочу узнать, как писать шейдеры»
Вы не ошибётесь, начав с Shadertoy. На сайте есть множество написанных сообществом туториалов и примеров для любого уровня опыта, а также примеры по любой теме, связанной с затенением. Вам не придётся думать о графических API или заниматься их настройкой. Это самое удобное место для использования в качестве графической «песочницы».
«Я хочу понимать графический конвейер и архитектуру на низком уровне»
Если вы хотите сильно углубиться: рекомендую начать с изучения D3D12 или Vulkan. Если вам неинтересны мобильные платформы, то выберите D3D12; мне кажется, он требует меньше мыслительных усилий и времени, однако за это придётся расплачиваться тем, что современные ресурсы для изучения не всегда хороши.
Для изучения D3D12 начните с github, где собраны примеры по D3D12, в частности, с примеров «hello world»:
https://github.com/microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12HelloWorld
В процессе воссоздания примеров сверяйтесь с руководством по программированию и справочной документацией:
https://docs.microsoft.com/en-us/windows/win32/direct3d12/directx-12-programming-guide
https://microsoft.github.io/DirectX-Specs/
Присоединяйтесь к Discord, это может сильно повлиять на процесс обучения: https://discord.com/invite/directx
Также стоит изучить ресурсы, подобранные Йендриком Иллнером: https://www.jendrikillner.com/post/d3d12-learning-plan/
Для изучения Vulkan начните с туториала по примерам Vulkan (благодарю Aeva): https://vulkan.lunarg.com/doc/view/1.2.154.1/windows/tutorial/html/index.html
Можно также прочитать туториал по Vulkan: https://vulkan-tutorial.com/
Завершив с ними. переходите к github с примерами Vulkan Саши Уиллемса: https://github.com/SaschaWillems/Vulkan
И, разумеется, всегда держите под рукой спецификацию по Vulkan. https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html
Присоединяйтесь к Discord сообщества разработчиков: https://discord.com/invite/tFdvbEj
Хорошей целью для обучения может стать создание высокоуровневой обёртки для выбранного вами API. Занявшись ею, вы многое узнаете об API и абстракциях. В начале пути не стоит забывать о множестве ресурсов для новичков на github (DirectXTex, Vulkan Memory Allocator, D3D12 Memory Allocator, DirectX Shader Compiler, и т. д.).
Я пишу туториал для новичков в D3D12, используя более современные концепции, и надеюсь опубликовать его в ближайшем будущем. Мне кажется, в нём есть необходимость.
Если вам нужно более поверхностное знакомство: рекомендую изучить D3D11 или OpenGL на основе множества доступных ресурсов (на один из них я дал ссылку выше). Если у вас нет конкретных предпочтений, то рекомендую D3D11, потому что поиск примеров и туториалов по OpenGL различных версий может вас запутать. Изученное вами на этом уровне останется полезным, если вы захотите изучать более низкоуровневые API.
Я понимаю, почему многие могли потерять мотивацию, поэтому и создал свой опрос в Twitter. Хотелось бы, чтобы в D3D11 были новые функции, которые появились только в D3D12, но для их отсутствия есть причины. Если бы эти функции были, или если бы у нас была официальная высокоуровневая обёртка поверх D3D12, то я бы порекомендовал её. Судя по результатам моего опроса, многие хотят иметь такую штуку, и в целом люди предпочитают, чтобы авторитеты в отрасли (например, Microsoft) предоставляли её, а мы не были вынуждены подбирать разные сторонние варианты на github.
Не заставляйте себя изучать тонкости D3D12/Vulkan, если в процессе изучения вы настолько выдохлись, что уже готовы отказаться от разработки графики. Нет ничего плохого в изучении более старых API, чтобы сначала лучше уяснить высокоуровневые концепции, а уже потом переходить к низкоуровневым API, чтобы понять, как они устроены внутри.
«Я хочу изучить рендеринг»
Пропустите этап платформенных API и переходите напрямую к сторонним абстракциям. Есть много вариантов на выбор, лично я рекомендую вам bgfx. Он достаточно высокоуровневый, чтобы не вдаваться в подробности внутреннего устройства и иметь возможность работы с высокоуровневыми концепциями. Также у него есть справочная документация по API, десятки примеров проектов, сообщество и выпущенные игры.
Если вы хотите рассмотреть альтернативы, то изучите The Forge, Sokol и Wicked Engine.
«Я хочу научиться писать функции, с которыми будут взаимодействовать художники»
Скачайте Unreal, Unity или Godot и начните читать туториалы по тому, как в них работать. Несколько лет назад я не задумываясь порекомендовал бы Unity, но теперь в нём есть три разных конвейера, что усложняет освоение и использование графических технологий движка, особенно для новичков. На данный момент я не знаю точно, какой из трёх лучше подойдёт для простоты обучения. Попробуйте каждый и остановитесь на том, который понравился больше.
Книги
Если вы хотите изучить ресурсы, которые будут актуальны всегда и дают фундаментальные знания, то рекомендую прочитать Foundations of Game Engine Development и Real-Time Rendering.