Сделал игру, работающую на видеокарте

Достоинства и недостатки вычислений на GPU.

Полтора года назад я решил сделать игру, весь мир в которой состоял бы из вычисляемых в реальном времени физических объектов. То есть по сути игра должна была быть физической симуляцией, внутри которой действует управляемый игроком персонаж. Первые эксперименты показали, что выполняться всё должно на графическом процессоре, иначе производительности не хватит.

Сделал игру, работающую на видеокарте

И вот, полтора года экспериментов и разработки миновало, игра выпущена. Основной код игры — это огромный compute shader, 6 тысяч строк на HLSL. Десятки тысяч взаимодействующих частиц обрабатываются параллельно, и выходит довольно быстро. И игра получилась именно такой, какой я её задумал. Всё в ней сделано из физических частиц. Вот видео, в котором показано, как это работает.

В этой своей заметке я хочу просуммировать опыт разработки такого рода игры. Зачем? Я убеждён, что разработчикам есть смысл некоторые алгоритмы переносить на видеокарту. Он есть уже давно, но редко кто это делает. Несмотря на наличие подводных камней, чудовищная производительность видеокарт может здорово помочь в реализации алгоритмов, в сторону которых раньше разработчики даже не смотрели.

Какие достоинства и недостатки у вычислений на видеокарте?

Достоинства:

Производительность GPU в 10-100 раз выше, чем у процессора, когда дело касается параллельных вычислений. Это очень много, так что на видеокарте можно делать принципиально другие игры, чем на процессоре. Моя игра просто не работала бы на CPU (то есть, была бы слишком медленной).

Недостатки:

Мало туториалов. Я потратил довольно много времени, чтобы всё изучить. И ещё больше — чтобы решить возникавшие проблемы.

Программировать для графического ядра в принципе сложнее. Привычные для процессорного вычисления вещи могут не работать. Например, вместо трёхмерного цикла на трёхмерном массиве я должен был организовать трёхмерное пространство потоков, одновременно обрабатывающих одномерный массив (в который пришлось разложить исходный трёхмерный). Кроме того, надо заботиться, чтобы параллельные потоки работали с общими данными в защищённом режиме. В целом всё это решаемо, но требует больше времени.

Проблемы возникли и при чтении данных из видеопамяти. Это приходилось делать на каждом цикле, но работало оно слишком медленно. Потому что в Unity не было асинхронного чтения в удобное для графического конвейера время, и он постоянно блокировался при чтении данных. В итоге fps падал вдвое. Пришлось использовать нативный плагин для асинхронного чтения из видеопамяти средствами DirectX, но во-первых, это не работало вне Windows, а во-вторых, по неизвестным причинам, это не работало на некоторых видеокартах, игроки жаловались.

Не у всех есть достаточно современные видеокарты, поддерживающие шейдеры и обладающие достаточной производительностью. Это ограничивало круг игроков, способных поиграть в мою игру. А те, у кого тормозило, были не прочь написать в Steam негативный отзыв.

Графические API на разных платформах немного отличаются друг от друга. В простых случаях они совместимы со стандартом directX, но у меня — не простой случай, я приблизился ко многим лимитам вплотную. К примеру, в DX11 один кернел может работать только с восемью буферами. А андроидный API — только с четырьмя. У Metal тоже свои ограничения, вроде отсутствия защищённой записи в общую для потоков текстуру, у Vulkan — ещё какие-то ограничения. В итоге, игра работает только на Windows.

Не удалось сделать вычисления детерминированными, так что пришлось обойтись без мультиплеера. Хотя, теоретически понятно: надо всё сделать на int-ах, и результаты на каждом цикле не должны зависеть от очерёдности потоков (которая может отличаться от раза к разу в одинаковых условиях). Но мои эксперименты пока не привели к детерминированности вычислений.Но по итогам, я всё-таки доволен, что сделал что хотел.Как игроку мне очень интересно было посмотреть, каково это — поиграть в игре, полностью физичной, чтоб всё было разрушаемым.

Как видите, трудности есть, но они решаемы. Кроме того, графические API постепенно развиваются, делая вычисления на видеокарты более практичными.

Что касается самой игры, то мне пришлось войти в эту область и попытаться придумать геймплей, который бы имел смысл именно в физическом мире, использовал бы эту особенность и давал игроку уникальные игровые впечатления. Так что как гейм-дизайнеру, мне было интересно поиграть с физикой, поэксперимениторвать. Изначально игра планировалась как римейк Scorched Earth с физической симуляцией, но в итоге я создал аркадную кампанию, эдакий платформер, в котором всё можно разрушить и нужно много копать.

А как программисту мне было полезно приобрести навык вычислений на GPU. Думаю, постепенно всё больше разработчиков будут использовать видеокарты для вычислений, слишком уж хороший выигрыш в производительности. Вовсе не обязательно делать на GPU целую игру, как сделал я. Можно перенести некоторые части игры на обработку в видеопроцессор. Например, поиск пути в стратегиях. По сути сейчас основное препятстве к этой практике состоит в том, что не любой разработчик будет готов писать compute shader, если всё равно его придётся дублировать, на случай, если игра запущена на платформе, не поддерживающей вычисления на видеокарте. Но уже сегодня можно написать compute shader таким образом, чтобы он работал на любой платформе.

Так что остаётся лишь попробовать свои силы в этой области.

Тут среди читателей много разработчиков игр, и если вы, волею случая, имеете опыт работы в Unity, и хотите выйти на разведку в мир вычислений на GPU, то у меня для вас хорошая новость. Я написал пару туториалов о том, как в юнити писать компьют шейдеры.

Вот ссылка на основной туториал, в котором рассматривается, как сделать физическую симуляцию, вычисляемую на видеокарте. В этом руководстве есть ссылка на второй, совсем простенький туториал, к которому вы сможете перейти, если первый покажется сложным.

Ну и напоследок, если кому будет интересно взглянуть поближе на получившуюся у меня игру-симуляцию, то вот ссылка на её страницу в Steam

На этом у меня всё, и я с удовольствие отвечу на ваши вопросы про вычисления на видеокарте, физические симуляции и инди-геймдев.

Если вы хотите поделиться своим опытом создания игры или рассказать какую-то историю, связанную с геймдевом, то смело нажимайте кнопку «Написать» и делитесь опытом. А мы, отредактировав текст (если это потребуется), перенесём его в раздел Gamedev.

179179
77 комментариев

Когда сделал игру выполняемую на видеокарте, а все видеокарты исчезли из продажи, или подорожали в три раза...<тут мем "человек с песком" :)>

43
Ответить

Не благодарите

12
Ответить

На самом деле всё отлично. Всплеск спроса со стороны майнеров и диплёрнеров дал кучу бабла производителям. Они это бабло пускают в развитие технологии, что в итоге приводит к удешевлению терафлопса. Кроме того, запрос на видеокарты как на вычислитель стимулирут развитие архитектуры, она эволюционирует в сторону большей дружественности к произвольным вычислениям, хотя изначально была заточена только на графику.

Так что через 2-3 года вычисления на видеокарте перестанут быть проблемой, а станут инструментом для повышения конкурентоспособности игр, и все начнут их использовать.

Хотя, сам я лелею надежду, что через некоторое время майнинговый бум закончится, майнеры понесут продавать свои карточки, и я прикуплю по дешёвке вычислительный блок из некольких штук, и замучу эволюцию нейросетей, с которой давно экспериментирую, но упираюсь в недостаток производительности.

8
Ответить

Как же приятно что есть такие извращенцы как Вы, сударь:)

30
Ответить

Ставлю лайк за трек аргонова в стима.

Ответить

Комментарий недоступен

18
Ответить

Комментарий недоступен

9
Ответить