[Перевод] Как стать программистом графики: советы команды AMD Game Engineering
Введение
Очень часто нас спрашивают о хороших веб-сайтах для новичков по изучению программирования графики. Разумеется, мы бы с радостью порекомендовали GPUOpen, но правда в том, что основная целевая аудитория GPUOpen — программисты среднего или высокого уровня. Для только начинающих погружаться в мир графики есть более подходящие веб-сайты.
Как и во многих других сферах, в графике нет одного единственно правильного пути. В основном он зависит от имеющихся знаний, предпочитаемого способа обучения, личного выбора, доступного оборудования и так далее. Поэтому это руководство будет перечнем веб-сайтов, которые, по нашему мнению, полезны для новичков, и небольшим обсуждением плюсов и минусов этих веб-сайтов и их программы обучения.
Какой язык программирования?
Когда мы разговариваем со студентами о нашей работе, то почти всегда слышим один вопрос: на каком языке программирования вы пишете? Короткий ответ: C++.
Длинный ответ: ну, если вы занимаетесь графикой, то пишете код для CPU, обычно на C++, но также пишете код и для GPU, который в нашей отрасли называется кодом шейдеров; обычно его пишут на высокоуровневых языках шейдеров наподобие HLSL или GLSL. Также необходим способ связать их вместе: попросить CPU, чтобы он попросил GPU сделать что-то полезное при помощи шейдеров и других необходимых данных и метаданных. Здесь на помощь приходят графические интерфейсы программирования приложений (API), которыми мы обычно управляем как кодом для CPU, написанным на C++.
Поэтому менее однозначный вопрос заключается в следующем: с какого графического API нужно начинать. Но на него у нас ответа нет, лишь множество разных мнений и соображений. Мы сузим его до популярных графических API, используемых сейчас для написания большинства игр для PC и 3D-приложений, забыв о таких аспектах, как игровые консоли с их проприетарными (по большей мере) API.
Существуют различные графические API, но на 2023 год самые популярные — это:
OpenGL®, DirectX®11 и WebGL™ — это легаси-API. В них используется старый подход к программированию GPU. Тем не менее, они по-прежнему широко применяются в научных кругах и игровой отрасли, потому что их проще понимать с точки зрения программиста и легче изучать. Однако за их простоту приходится расплачиваться: внутренняя реализация этих API в драйверах и коде среды исполнения со временем усложняется, создавая узкие места на стороне хоста и заставляя производителей GPU писать очень сложные драйверы.
Примерно с 2013 по 2016 год ситуация изменилась: AMD представила графический API Mantle для PC. Он спроектирован только для GPU AMD совместно с EA DICE. Mantle снимает бремя легаси-API, предоставляя программисту гораздо более низкоуровневый доступ к GPU и снижая толщину абстракции поверх его внутренней работы. В результате благодаря более эффективному использованию GPU повысилась производительность, что открыло новые перспективы.
Появившийся в 2014 году Metal для платформ Apple, за которым в 2016 году последовали DirectX®12 и Vulkan® тоже используют похожий низкоуровневый и более явный подход к программированию GPU. Все эти API повышают требования к программисту, заставляя его в более явной и чёткой форме доносить, чего он хочет добиться GPU, но и дают программисту больше контроля.
По сути, это переносит часть традиционных драйверов GPU в приложение. Благодаря этому у программиста появляется больше контроля, а значит и больше возможностей обеспечения производительности и эффективности работы GPU.
Кажется, что осознавая смену парадигмы программирования GPU, принять решение о выборе API сделать легко. Если вы хотите изучать программирование графики для Windows®, то есть основной целевой платформы игр для PC, то логично будет выбрать Vulkan® или DirectX®12, потому что они самые новые.
Однако легаси-API не только по-прежнему широко используются, но и гораздо проще в изучении. Поэтому может оказаться правильным сначала изучить легаси-API, а затем переходить к современным графическим API. Вместо того, чтобы сразу взбираться на Эверест, вы сначала потренируетесь на ближайшем холме.
Простой пример: можно сравнить, сколько строк кода необходимо в разных API для отрисовки на экране треугольника — это аналог «Hello, World!» в программировании графики. Для вывода на экран первого треугольника в OpenGL® или DirectX®11 нужно примерно 10 строк кода, а в Vulkan® и DirectX®12 — по крайней мере, на порядок величин больше.
С другой стороны, можно сказать, что при написании кода на Vulkan® и DirectX®12 нужно давать GPU более явные указания. Да, необходимы сто строк кода, но каждая строка чётче описывает то, что произойдёт в GPU. Хотя при работе с OpenGL® и DirectX®11 многие сложности скрыты от программиста, сам GPU при этом выглядит как «чёрный ящик» и это не даёт понимания о его внутренней работе.
Vulkan® и DirectX®12 изначально заставляют иметь дело с низкоуровневыми знаниями, а OpenGL® и DirectX®11 действуют на высоком уровне, позволяя сосредоточиться на более продуктивных аспектах программирования графики.
Послушаем мнение участников команды AMD Game Engineering о том, с чего начинать — с легаси-API или с современного API:
«Начинать изучение программирования графики с DX12® или Vulkan® для подростка будет тяжело».
«Мы прошли долгий путь от старого доброго hello triangle, рисуемого при помощи glVertex».
«Очень жаль, что OpenGL® уже не так актуален».
«Думаю, для изучения основ OpenGL® по-прежнему достаточно хорош».
«Я начинал с DX10®, который, по-моему, неплох, но многие из новичков испытывают с ним трудности, если плохо владеют C++». DX10® — это устаревший предок DX11®, не изучайте DX10®!
«Тут есть множество аспектов. Изучение теории растеризации и трассировки лучей. Обучение традиционному конвейеру. Изучение того, как передать GPU работу и так далее… Не знаю, в каком порядке это следует изучать, но обычно я целиком работаю на C++ (нет необходимости осваивать другой язык), так что, вероятно, мне стоит посоветовать просто начать с Vulkan®…, но на самом деле я не уверен».
И, разумеется, есть также возможность программирование графики без OpenGL®, DirectX®11, Vulkan® и DirectX®12. Среди общих классов графических API мы упомянули WebGL™ и WebGPU, они оба работают в среде веб-браузеров, которая представляет собой целую программную экосистему (а по сути и настоящую операционную систему).
Графику реального времени можно создавать и в браузере при помощи WebGL™ или WebGPU! Преимущество этого заключается в том, что для веба вам не нужен C++ (но, строго говоря, он может всё равно управлять графикой в браузере через что-то наподобие WebAssembly). Для работы в браузере вполне подходит его основной язык — JavaScript!
А если вы не хотите заниматься высокоуровневыми вещами, мучиться с низкоуровневыми подробностями графических API и вручную писать шейдеры, то, возможно, вам подойдёт игровой движок. Unreal Engine — самый популярный движок игр для PC, его самая распространённая альтернатива — Unity®; ещё есть целая куча более простых и маленьких опенсорсных движков наподобие Godot.
Вот мнения команды AMD Game Engineering:
«Мне кажется, заставлять новичков начинать с DX12® или Vulkan® — это слишком жестоко, но, вероятно, вполне осуществимо. Я бы сказал, что для понимания графического конвейера проще всего начать с WebGL™ (к тому же вы сосредоточитесь только на самом необходимом)».
«WebGPU может обучить вас концепциям, которые ближе к современным графическим API, не добавляя лишних низкоуровневых подробностей».
«Наверно, WebGPU со временем станет намного лучше, но, полагаю, сейчас при написании нетривиального кода будет всплывать множество странностей. Тем не менее, он оказался очень крутым и работал на удивление хорошо. Я искренне надеюсь, что он будет совершенствоваться, но и то, что есть, уже выглядит очень многообещающе. Для прототипирования он безумно хорош. И да, вероятно, он хорошо подойдёт в качестве API для обучения/преподавания».
«Я знаю, что на первых курсах рендеринга многие школы используют Unity®, что не так уж плохо, но боюсь, есть опасность того, что студенты так и не поймут, зачем им нужно изучать низкоуровневые концепции».
«Начинать с явного API нормально, если вы хорошо знаете современный графический конвейер и его высокоуровневую реализацию оборудованием GPU, или если вы хотите в процессе изучения обрести понимание этого оборудования GPU. В противном случае стоит начать с чего-то попроще, а потом, если будет желание или необходимость, попробовать явные API».
«Лично мне кажется, что акклиматизация к шейдерам через популярный игровой движок с последующим переходом к написанию собственного хост-кода — хороший способ войти в профессию. Очень сложно учиться, если не имеешь чёткого понимания, чего хочешь достичь в графическом API, в противном случае тебе может надоесть, ещё когда доберёшься до треугольника».
Полезные веб-сайты
Какие же обучающие ресурсы мы можем посоветовать? Вот некоторые из ресурсов, рекомендованных участниками команды AMD Game Engineering:
https://learnopengl.com: «LearnOpenGL — лучший сайт для начинающих, демонстрирующий, как на самом деле делать вещи с реальным API на C++».
https://www.scratchapixel.com: «Scratchapixel удобен тем, что не приходится осваивать кучу кода. Например, можно сосредоточиться на том, как работает трассировка лучей».
https://www.udemy.com/: «Udemy — хорошее место с курсами для начинающих».
https://rastertek.com/tutindex.html: «туториал по OpenGL®/DirectX®11»
https://github.com/RayTracing/raytracing.github.io: трассировка лучей за одни выходные — «Мне нравится практичный подход к обучению, поэтому Ray Tracing in a weekend удобен, если вы умеете немного кодить».
https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-graphics-pipeline-2011-index/: «Экскурсия по графическому конвейеру с точки зрения GPU. Статья опубликована в 2011 году, то есть до появления явных API, но многие аппаратные и программные концепции по-прежнему актуальны».
https://sotrh.github.io/learn-wgpu/: «Это сайт для обучения webgpu, аналогичный learnopengl, но пока очень сырой».
https://codelabs.developers.google.com/your-first-webgpu-app: «Полностью я его не прочитал, но выглядит достойно».
https://www.shadertoy.com/: «Shadertoy позволяет писать шейдеры, не затрагивая никакой графический API. Я бы никогда не заинтересовался графикой достаточно сильно, чтобы захотеть изучать OpenGL®, если бы не начал с чего-то попроще (для меня это было простое рисование на canvas Java)».
https://vulkan-tutorial.com/: «Мне кажется, людям важно не бояться копипастить, особенно при изучении Vulkan® и DirectX®».
Итог
Что же дальше? Если вы ещё не решили, с какого языка программирования и экосистемы графического API начать, не волнуйтесь. Можете попробовать разные подходы и выбрать наиболее подходящий для вас.
Мы бы также с радостью услышали ваше мнение! Как вы учились программированию графики? С чего рекомендуете начинать будущим программистам?