Этап 1: копия beamNG

Сначала мне стало интересно, можно ли сделать физику аналогичную beamNG? Вкратце расскажу как она работает:

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

Article content

Самое главное в этой системе - малый шаг интегрирования, всего 5 миллисекунд. Это делает физику стабильной, множество пружин не успевают "взорваться" за столь малый шаг, и вся система работает довольно хорошо.

Такую систему воспроизвести достаточно легко. Особенно учитывая что предок beamNG - rigs of rods - лежит в открытом доступе. Нет, я не копировал вслепую, но ИИ явно в курсе этого проекта, ведь он обучен на открытых исходников различных проектов

Но у такой системы есть недостаток - разрывы моделируются плохо. Балку можно разорвать при достижении порога силы. Но она удаляется целиком и фактически пропадает кусок физической модели. И что делать с графикой? Обычно в таком варианте в beamNG полигоны улетают в рандомную сторону, из-за чего графика треугольниками растягивается по экрану

Этап 2: shell материалы

Article content

Тут я вспомнил свою старую идею - моделировать материал не балками, а треугольниками. Их можно решать точно так же как и балки, только вместо двух точек будет три. К этому можно добавить усилия между двумя соседствующими через общее ребро два треугольника, не давать им сгибаться друг относительно друга, тем самым моделировать упругость листа материала. А так же отрывать треугольники друг от друга вдоль соседствующих ребер.

Таким образом мы можем получить изгибы и разрывы, без потери геометрии: изначальная площадь треугольников будет равна площади после разрыва.

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

А еще, к разрывам можно применять паттерны. Например, для стекла или пластика при контакте сразу делать "надрезы" в виде трещин и круговых повреждений вокруг точки контакта. Для дерева, например, делать разрыв вдоль волокон легче, чем поперек

Article content

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

Но у такой системы есть нюанс, она очень неточная и податливая. В beamNG для жесткости кузова делается множество хаков, добавляются балки дающие нужную жесткость тем или иным частям, нивелирую не очень точную физику. Здесь же точность становится еще меньше, и с ней просто не получается смоделировать жесткий кузов автомобиля.

Но есть еще одна старая идеа

Этап 3: FEM

Вообще-то реалистичные повреждения кузова уже умеют моделировать давно, их применяют в проектировании реальных автомобилей. Называется это finite element method (FEM), в которой подход фактически такой же как в beamNG, однако применяется совершенно другой решатель системы.

Article content

В beamNG он тупой и простой - решаем каждую балку как пружину, считаем силы, применяем их к точкам. Но точек много и связей тоже, на одну вершину может влиять множество пружин, и в какую сторону ее двигать? Ну, в какую-то подвинется, на следующем кадре еще, а так как шаг интегрирований всего 5 миллисекунд, система более-менее уравновешивается и работает правдоподобно

Более правильно, а точнее "точно", решать такие сложные системы - через системы уравнений, то есть через матрицы (атеншн, могут быть флешбеки из школы или института). В таком подходе вершина уже движется не "куда-то", а туда куда приводит решение системы уравнений.

Фактически, метод beamNG - это численный метод решения все тех же систем уравнений (каждая балка - уравнение). А численные методы фактически решают систему итерациями, и чем больше итераций, тем ближе решение к реальному. То есть в этот подход фактически заложена неточность

Подход FEM гораздо точнее, но и гораздо медленнее. Инженерное моделирование деформации кузова авто считается не один час. Это довольно точно получается, но явно не подходит под геймдев.

Но что если разительно уменьшить количество элементов кузова, и решить через систему уравнений (матрицы)? Кузов можно упростить и сделать что-то вроде трубчатой рамы, на который навешать рычаги подвески и гибкие, менее точные shell-листы

Этап 4: ээээксеприменты

Article content

Честно говоря, получилось плохо. По отдельности все отлично:

  • трубчатый каркас ведет себя реалистично, в том числе моделирование многорычажной подвески авто

  • shell-листы выглядят реалистично на изгиб и разрыв

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

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

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

Этап 5: еще пара идей

Я посмотрел на перфоманс FEM решателя, и подумал "а что если так моделировать и панели автомобиля"? Кроме балок так же добавить конечный элемент - треугольник. Да, это супер-тяжелые рассчеты, но их получилось распараллелить. Здесь круто что ИИ довольно хорошо это может оптимизировать и улучшить.

По сути мой подход был такой: профилируй сам, ищи узкие места сам, нужно вписаться в стабильные 60FPS. Черт, я конечно умею в оптимизации и смог бы сделать это сам, но как будто бы это не особо и нужно - ИИ отлично справился. Окей, это было не совсем так просто, и я ставил более сложные условия, типа утилизации кеша процессора и уменьшение взаимных блокировок, но я думаю мистер клод это все знает и без меня

Так или иначе, получилось смоделировать кузов, подвеску, панели и бампера автомобиля полностью в FEM системе, при стабильных 60 FPS.

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

Ну и самое главное: это работает довольно точно и может моделировать разрывы. Здесь все так же применяется детализация при столкновении:

  • балки делятся на несколько, тем самым могут более реалистично гнуться

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

Поверх физической модели можно по аналогии beamNG натянуть графическую модель. Работает довольно просто, аналогично костным анимациям: вершины по расстояниям привязываются к ближайшим вершинам физической модели, учитывая позицию и вращение. Разрыв можно моделировать либо через исчезновение полигонов, либо через их тесселяцию

Отличный тест работы системы - разрубить машину огромным топором. Такого точно нет в beamNG!

Финальный результат

Стало ли это лучше физики beamNG? Честно скажу, и да и нет. Тест топора - показательный. А еще физика шасси немного точнее beamNG, тут я даже сделал отдельный элемент симулцяии колеса и шины авто. Думаю, это немного лучше физики колеса beamNG, где оно фактически моделируется как множество вершин с некоторыми хаками для коллизий и устойчивости.

С другой стороны, перфоманс на грани: физика столкновения двух автомобилей занимает 15-20 миллисекунд, что нормально для демки, но недопустимо много для реальной игры, где нужно обсчитывать еще кучу всего в игровом мире

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

Здесь лежит демо под mac os:

https://drive.google.com/file/d/16SjBebgNcFKsUPTdfPY67K0w-n1XX8GM/view?usp=sharing


Больше о разработке игр, движков и о разработке в целом в моем телеграм‑канале.

Комментарии (0)