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

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

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

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

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

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

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

Недостатки:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 
Источник: DTF

Читайте также