Я обожаю физику в играх, и мне интересно разрабатывать физические движки.
Недавно мне захотелось сделать игру, в которой персонажи будут сделаны в виде физической симуляции мягкого тела. И чтобы всё управление персонажем происходило через физический интерфейс движка.
Мне хотелось, чтобы движение игровых сущностей было физически достоверным, чтобы игрок мог предсказывать последствия своих действий на основе опыта жизни в реальном физическом мире.
Вся физика вычисляется на видеокарте, что совершенно логично. Архитектура и АПИ GPU идеально подходят для многопоточной работы с массивами данных, и производительность на два порядка выше, чем у CPU. В Юнити можно писать компьют шейдеры, и весь код физики написан на HLSL.
Я начал с создания кристаллической решётки, узлы которой - свободно плавающие частицы, соединённые друг с другом пружинами. Хотелось посмотреть, как эта штука будет себя вести.
Получилось неплохо. Это можно было использовать как физический материал для создание игровых объектов.
Кроме пружин, я реализовал взаимодействие между свободно плавающими частицами. Использовал потенциал Леннарда-Джонса. Так что частицы спонтанно слипались в разрушаемую материю.
Это могло пригодиться для создания разрушаемых частей игрового мира и для каких-то механик.
Если силу взаимодействия частиц сделать значительной, они слипаются в убедительное подобие разрушаемой физической материи.
В этом видосе я сделал чтобы как в Терминаторе у Т-1000 дырки появлялись.
Но если силу взаимодействия частиц сделать слишком большой, симуляция взрывается, так что пришлось применить ряд оптимизаций, чтобы материя хорошо выдерживала давление и экстремальные силы. В этом видосе мы видим, что при сжатии материя ведёт себя как паста с гидродинамическими свойствами, которая при этом достаточно прочна, чтобы слипаться в относительно твёрдое тело.
Но свободные частицы в контексте моей цели имеют два надостатка: они не прочно держатся. Материя разваливается, если посильней стукнуть. Кроме того, частицы выглядят как набор шариков, а мне нужен меш персонажа. Это и для производительности, и для эстетики лучше.
Тут конечно подошёл бы метод marching cubes, но у него есть некоторые недостатки. Например, информацию о текстуре пришлось бы проецировать на получающийся меш, вместо того, чтобы хранить uv-координаты для каждой вершины. Поэтому, я решил использовать физическое тело с пружинами.
Сформировал из него персонажа-змейку.
И затем стал искать способ генерировать меш вокруг физического тела. И удерживать его в окрестностях физического тела, как кожу.
Я экспериментировал с разными способами, но всё было недостаточно хорошо, например:
В итоге изобрёл способ, при котором вершины будущего меша отталкивают друг друга, но при этом остаются в окрестностях физического тела. По мере остужения, они формируют кристалл, который затем тетрагонизируется, и внешние треугольники становятся мешем. Результат меня наконец-то устроил, получился достаточно хороший меш.
Оставалось автоматически заскинить меш физическими частицами тела, как если бы они были костями. Получилось мягкое тело, игровая сущность.
С этим уже можно было работать.
Я перенёс алгоритм анимации заскиненного меша в ГПУ (для скорости), и добавил на каждом кадре сглаживание поверности меша. Кроме того, реализовал простенькое управление персонажем.
И получился физически симулируемый персонаж, управляемое мягкое тело. То есть, главную цель эксперимента я достиг.
Естественно, я не избежал искушения для научных целей сделать и симуляцию женской груди. Этот видос сюда не буду выкладывать, а то из-за одного видоса весь пост делать 18+ не хочется. Выложу отдельно чуть позже.
В общем, на этом завершился этап принципиального R&D для задуманной мной игры. С физическим мягким персонажем уже можно пилить геймплей из механик, возможных только в игре-симуляции.
Однако, оценив трудозатраты, я решил переключиться на 2Д-движок для выпуска игры, чтобы на нём решить ряд технических сложностей. Всё-таки хочется поскорей игру выпустить, а не тратить два года на разработку.
В следующем посте я расскажу про 2Д-движок, в котором я продвинулся гораздо дальше.