Pull to refresh

Comments 131

На этом этапе обнажилось несовершенство физической модели. Каменные колонны вели себя как желе:

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

image

Многие здания на уровнях внутри тоже усилены.

Но это не помогло бы увеличить шаг с сохранением твёрдости. Кость задаёт расстояние между парой частиц, все друг к другу не закрепишь. А события, нарушающие закон созранения энергии происходят по всему объёму. И если увеличить шаг, кости не спасут материю от спонтанной детонации.
я конечно дилетант, но может вместо просчёта частиц, стоит считать связи, и их характеристики. При должной архитектуре, не придётся вводить костыли, вроде костей, и колонны не будут похожи на желе.
Для просчёта частиц, собственно, и считаются связи между ними. Но на уровне связей прочность можно увеличить только ценой производительности. Так что я пошёл на компромисс с «костями». Чтобы добиться большей прочности, и сделать игру играбельной на слабых видеокартах.

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

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

Не соглашусь. 30-50 мс — это вполне комфортная задержка, которой не замечаешь. Знаю из опыта облачного гейминга :)
30-50 мс — это очень хорошая задержка, мой столичный друг :-)
Но так выходит что не все живут в одном городе, и, зачастую, задержки идут в районе 100-200мс, на которых это всё уже отличается ощутимо.
И то, ребята с ДВ, вполне возможно, позавидуют и таким задержкам.
Я думаю, тут нужен тот же подход, что в большинстве крупных современных реалтайм мультиплеерных проектов — все расчёты на сервере, на клиенте только отображение плюс миллион уловок для lag compensation.
Так я о том и написал — в отличии от современных реалтайм мультиплеерных проектов тут значимой информации на порядки больше — всё окружение изменяемо, каждый пиксель влияет на другой.
Как в таких случаях организовывать lag compensation?
Можно, как вы и сказали, синхронизировать семя рандома и просто сообщать место взрыва, тогда у всех клиентов будет одинаковый просчет физики

Как я понял игра пошаговая, как worms, там что тут не нужна реакция на изменение в мире в реальном времени
синхронизировать семя рандома и просто сообщать место взрыва

Скажу по опыту — не все видеокарты считают одинаково. Так что могут быть серьезные расхождения в мире из миллиона частиц
Да, поэтому предлагали переходить на int-значения. Разные видеокарты могут по-разному работать с float. Потеряю в точности, но совсем незначительно. Зато будет шанс сделать симуляцию детерминированной вне зависимости от видеокарты.
Теоретически — да, если как-то хитро синхронизировать циклы. Допустим, симуляция у вас детерменированная и физика обрабатывается 20 раз в секунду. У одного клиента что-то тормознуло и цикл либо пропустился либо выполнился чуть позже. Если подтормаживания возникают регулярно, то время будет идти по-разному. А если пропускать итерации, то физика будет вести себя не одинаково.
Кстати, даже с интами видеокарты ведут себя по-разному. Когда-нибудь проверяли, что будет, если ноль поделить на ноль на гпу разных производителей? или корень из минус единицы? Что будет, если вывести в цвет значение nan или бесконечность? Помню был случай, когда при записи в цвет +бесконечность некоторые гпу выводили белый цвет, а некоторые черный. Конечно все это граничные условия, которые по-хорошему бы обрабатывать отдельно, но все же…
Есть еще вероятность, что с интами видеокарта будет работать медленнее.
Симуляция работает из-под Update(), а не из-под FixedUpdate(), то есть, у каждого со своей скоростью, которая зависит от производительности видеокарты. Поэтому, в любом случае при одновременной игре придётся ориентироваться на самого медленного игрока. Я на принципиальном уровне представляю, как это нужно организвать, чтобы всё работало синхронно, без пропусков. Но сетевого кода никогда не писал, так что подводных камней предвидеть — знаний не хватает.

Касательно интов — да, мне говорили, что видеокарты внутри себя всё во float считают, а инты будут медленней. При этом, существует ряд intrinsic atomic functions, которые пишут общие данные в защищённом режиме, так вот, эти функции существуют только для целы чисел, а для с плавающей точкой — нет. Странно.

А компилятор говорит, что вместо интов лучше использовать uint, потому что они быстрей. Так что сделаю на uint, всего вероятней. Потому что обработать граничные случаи, чтоб разные карточки не имели вольности можно, а вот если производительность потеряю, это будет хуже.
Касательно интов — да, мне говорили, что видеокарты внутри себя всё во float считают, а инты будут медленней.
А зачем гадать? Можно же посмотреть cycles per instruction throughput для нужного GPU и выяснить наверняка.
Там про CUDA написано; это всё применимо к случаю, когда шейдерный код компилится в directx или openCL?

Или вот вопрос, там говорится про int и float, а у меня компилятор говорит: чтоб быстрей считать, используйте uint вместо int. А в таблице этого различия не упомянуто, в чём может быть дело?
К OpenCL точно применимо, думаю что и к DirectX тоже — вычислительные модули одни и те же ведь. Но я раньше аналогичные таблицы и для OpenCL находил, в т.ч. и для AMD. Про uint/int не знаю, надо гуглить.
обратите также внимание на if statements, по этой причине в ПО для MD избегают «обрезанных» версий потенциалов, стараясь так настроить симуляции, что бы частички никогда не попадали в «обрезанную» зону.
Да, слышал про if statements, стараюсь избавляться, где возможно. У меня обрезание пиков происходит через clamp() расстояния между частицами.
Не знаю, какая производительность clamp(), но думаю что намного хуже чем add/multiply. Надо проверять, простенький кернел сделать и проверить.
Ок, потестирую. Наверняка сейчас недооптимизированность есть в подобных мелочах.
Throughput of single-precision floating-point add, multiply, and multiply-add is 8 operations per clock cycle.

Throughput of compare, min, max is 8 operations per clock cycle.

nvidia_opencl_programmingguide.pdf
То есть наравне, можно пользоваться.
Хм, да, вы правы. Не имеет значения, где запущен сервер, на отдельном компьютере или на одном из клиентов.
Симуляция в данный момент недетерминированая, так что у игроков с каждым шагом ситуация будет развиваться немного по-разному. Сонхронизация при таком количестве объектов, действительно, непрактична.

Так что я собираюсь попытаться сделать синхронизацию детерминированной. Для этого я перейду с float на int, и сделаю все вычисления не зависящими от порядка обращения параллельных потоков к общим данным.

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

А если не получится с детерминированностью, буду мудрить с оптимизацией синхронизации, это будет сложно, но очень хочется мультиплеер, можно заморочиться.
Ход разработки — в r/Unity3D и в r/Unity2D

А просто гифки, чтобы заинтересовать игроков, постил в r/Gaming, там аудитория шире.
Я так понимаю, чтобы добавить деталей в вашем движке надо симулировать все бОльшее количество точек.
Интересно было бы почитать про это.
Да, чем больше точек-частиц, тем больше, собственно, материи, из которой всё лепится. Но чем их больше, тем выше вычислительная нагрузка и ниже скорость работы. Так что я примерно по 20-30 тысяч частиц на уровень использую, чтоб с моей видеокартой работало. А если б я ориентировался на самые мощные модели, типа GTX 1080, можно было бы хоть 100К частиц использовать.

А почитать об этом, кроме упомянутого первого поста на хабре, можно ещё в моём посте на пикабу.
+

Если будет под мак — поддержу покупкой :)
В новой версии Юнити появилась возможность копилить compute shader под Мак. Так что теоретически я могу выпустить игру для Мака. И планирую жто сделать, но не сразу, хочется сначала доделать до окончательной версии. Так что через пару месяцев только.

Очень здорово! Сам думал о таком, вдохновившись The Powder Toy, так же, с подвижными объектами, разрушениями, плавлением, расчетами на видеокарте и т.п, но дальше теоретического фантазирования дело так и не дошло.


P.S. Не нашел информации, OpenCL или CUDA? Будет работать на AMD видеокартах?

Я тоже вдохновился именно The Powder Toy.

Сделал в Юнити, на compute shader. Код шейдера пишется на HLSL, и юнити компилит его на directX или openCL. Так что на вполне AMD работает. А новая версия даже умеет компилить под Metal.
Прекрасно, непременно посмотрю. А на какой видеокарте она комфортно работает? gtx 1060 хватит?

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

в смысле на фулл, демо можно сразу попробовать

Мне кажется, КДПВ с "сырой" реализацией выглядит гораздо лучше остальных.
Причем, полагаю, именно в GIF, за счет дизеринга. Такой-то веб-панковский вид.

Да, что-то в ней есть. Но я в любом случае что-то буду менять с выводом пикселей на экрен. Либо доводить до большей гладкости, либо стилизовать эти пиксели до чего-то более упоротого.
В скорче было оружие выжигающее куски земли, без разлета в разные стороны, меганюка например. И во всех играх, как в скорче, так и в леммингах, чевях можно были строить конструкции или засыпать участки землей.
Я сразу решил, что реализм на первом месте. Так что выжигания не будет, земля будет разлетаться. Но диапазон типов оружия я расширю со всем уважением к богатству оружия в скорче.
Здорово! У меня два вопроса есть:

1. Можно ли код интегратора посмотреть?
2. Когда игра будет доступна?
1. Интегратор тривиальный, кажется это называется методом Эйлера. К координатом на каждом шагу прибавляются значения скоростей. А скорости обновляются с учётом действующих сил.

2. Уже доступна на раннем доступе в стиме для винды, в конце поста ссылочка есть.
Эта разностная схема (Эйлера) 1-го порядка точности. Преимущества: менее требовательна к железу, больше скорость, а вот недостатки: ее на больших временных шагах нельзя использовать — ошибка быстро нарастает.
А контактная модель соударения (взаимодействия) частиц какая используется? У вас при бОльшем шаге dt смещение частиц большое, они перекрываются больше и по закону Гука нормальная составляющая контактной силы F=kx очень большая, а из-за нее, соответственно, ускорение большое и скорость на следующей итерации у частиц очень большая, поэтому частицы улетают «в небеса». Опишите подробнее контактное взаимодействие. Возможно, его можно поднастроить. Хотя бы общая формула. Обычно, нормальная составляющая выражает упруго-пластическое взаимодействие, тангенциальная — силу трения. У вас, наверное, так.
да, поддерживаю вопрос, тоже хочется деталей по этой части, для собственных экспериментов
Контактное взаимодействие? Если я правильно понимаю термин, то я отказался от такого взаимодействия. Вначале, когда шаг был большой, я рассчитывал, не пересекаются ли траектории частиц, и если пересекаются, вычислял точку контакта и реализовывал упругое мгновенное столкновение, изменяя скорости и координаты столкнувшихся частиц.

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

Так что сейчас используется только сила Леннарда-Джонса. Небольшая доля частиц движется быстро, и, действительно, перекрываются в столкновении, с возникновением неадекватных величин в нормальной составляющей силы взаимодействия. Но я это исправил, обрезав пики у кривой Леннарда-Джонса, оставив плато. Большинство частиц взаимодействуют в области вблизи равновесия между отталкиванием и притяжением, и там значения величины силы корректное. А если экстремальное сближение происходит, сила не растёт.

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

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

Помимо силы Леннарда-Джонса, есть ещё вязкость. При чём — не помню, из каких соображений — я реализовал только нормальную компоненту вязкости. Пара частиц обменивается долей их относительной скорости, проецирующейся на соединяющую их центры прямую.

Вместо разностной схемы мне на реддите предложили попробовать rk4. Я счёл, что это исправит ситуацию для экстремальных градиентов поля, но за это придётся заплатить большим количеством вычислений, так что выигрыш не гарантирован. Поэтому, я пока не спешу её пробовать. Скрее всего попробую её позже, когда возьмусь за перевод модели с float значений на int, в надежде сделать симуляцию детерминированной.
Попробуйте метод Верле, стандартный в молекурярной динамике. Выше порядок точности, гораздо лучше сохраняет полную энергию системы (в вашем случае это неважно, но всё же), а вычислений сил столько же, сколько и в Эйлере. На английской википедии Velocity Verlet написан и сам алгоритм, смотрите тот, который из четырёх пунктов
Преимущества: менее требовательна к железу, больше скорость, а вот недостатки: ее на больших временных шагах нельзя использовать — ошибка быстро нарастает.

А ещё она теряет устойчивость при решении жестких систем уравнений, которые как раз это самое контактное взаимодействие и описывают

Можно использовать неявную схему Эйлера, если система уравнений линейная, то получается вообще шикарно
Почему просто не хотите оперировать плотностью, вязкостью и твердостью. У вас же получается физика жидких тел, но не твердых. Вот и вытекает желейность. Скелет тут погоды особой не сделает, он только сгруппирует частицы «желе» вокруг себя.
Я вначале экспериментировал с моделью без частиц, с полем векторов, с динамикой жидкости. Но меня эта модель не устроила, для описания земли лучше подошла модель с частицами. Всё же идеал — это твёрдое тело. Пусть он не достижим из-за слишком большого шага, но приближение меня устроило. «Бетон» качается и ходит волнами, но даже в виде горизонтальной балки он держит танк игрока, и это примерно то, чего я хотел получить.
Еще пара вопросов:
1. А форма частиц какая? Только круглые? Примените прямоугольники-квадраты — будет более стабильно смотреться. Однако у «движка» скорость упадет — больше вычислений на детектирование коллизий между объектами и вычисление контактных сил.
2. Масса у всех частиц одинаковая? Может некоторым частицам массы добавить — инерция увеличится и не будет заметно «желе»?
если частицы будут не круглыми, то придётся считать физику вращения и пересечения граней, что очень накладно (более-менее эффективно это делает, например, Bullet на OpenCL, но количества частиц сразу становятся несравнимыми)

SPH симуляции («на круглых частицах») — наиболее эффективно считаются в Soft Body, даже nVidia в nVidia Flex даунсемплит до массивов круглых шариков объекты, чтобы физику мягкого тела можно было считать в realtime

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

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

Мне кажется стоит смотреть в сторону динамической детализации. Сколько частиц не считай, всё равно будет мало. Важно правильно выбирать детализацию. Нужен LOD для физики.
В Minecraft был мод — LittleBlocks, жаль забросили его уже много лет. Позволял разбить блок на более мелкие детали, но физики там не было. Был мод с физикой(не очень интересной, но всё же), но он не работал с LittleBlocks. Скрестить бы их, уже было бы хорошо. Что-то оставляем в виде плохой детализации, что-то в более хорошей.
Пока лучшее, что я видел с физикой в 3D, это заброшенный проект SoA.
Но перестал следить, может есть что-то более интересное?

Оказывается VoxelFarm, продолжает как-то развиваться.
B AtomontageEngine тоже не совсем мёртв.
Но вообще идея с воксельной физикой почему-то очень медленно развивается.
Я пять лет назад думал, что появится очень быстро много интересных проектов.
Но все мертвы.
Удачи вам хотя бы с 2D.

В VoxelFarm, кажется, тот же подход, что в Red Faction. Коллайдеры динамически натягиваются на оставшиеся без опоры меши. Но в видео заметно, что если меш хоть маленькой стеночкой соединён с основным зданием, то эта стеночка не сломается, хотя должна бы. То есть, этот подход требует учёта большого объёма частных случаев. Разработчики Red Faction тоже жаловались на эту сложность. Возможно, в ней кроется медленное развитие направления воксели+физика. Слишком сложно.
Вы правы, если сделать большой мир, но просчитывать только кусок в видимой области, то ограничения по размеру мира снимутся. Именно в этом направлении я планирую развивать свой движок. Но это уже после того, как доделаю игру. А то на новые эксперименты времени уйдёт много.

SoA прикольно выглядит, спасибо за ссылку.

А из интересного я недавно видел вот такую штуку: там тоже материя из частиц, но в 3д и с VR.
Замените title в оконной версии. Там сейчас Compute Shader Test :)
Игра — это ограничивающие правила. Где можно разрушить правила — там вряд ли может быть игра.
Вы правы, если дать больше свободы, то будет больше будет лазеек для срезания углов. Но по сути, это лишь повышает требования к дизайну уровней. Свобода разрушений может обогатить пространство стратегий, не разрушив, а расширив ограничивающие условия игровой механики.

Простой пример: дать ограниченое число патронов для мощной пушки. Будет выбор: проломить стену и обойти врага или сохранить их для битвы с боссом. Впрочем, я только начал делать уровни кампании и тестировать задумки. Возможно, многие из них окажутся непрактичны из-за открывающихся коротких путей.
Вот отличный пример игры:
http://buildandshoot.com/
Режим игры babel очень интересный. Команды должны строить лестницы, чтобы захватить чемоданчик. Можно ломать лестницу другой команды, можно копать туннели…
Это называется игра-песочница
Чтоб решить проблему со стабильностью можно модифицировать потенциал Леннарда-Джонса так, чтобы он был конечен в 0. Например, добавить к радиусу константу, т.е. вычислять не U( r) а U(r+c). Вообще разные варианты гуглить можно по «lennard jones soft-core».
В итоге можно увеличивать шаг(ценой точности) и использовать больше частиц, хотя некоторые soft-core потенциалы могут быть сами по себе сложнее для вычислений, что скажется на FPS.
Ага, я сейчас так и поступаю, пик потенциала срезан, вместо него плато, куда попадают самые быстрые частицы, хотя для большинства части градиент силы вычисляется на неискажённом участке кривой вблизи равновесия между отталкиванием и притяжением. У меня ещё несколько подобных хитростей использовано там и сям, так что можно сказать, что исчерпан весь диапазон возможностей увеличения жёсткости материи без оплаты производительностью.
>Материя стала более прочной, и я создал несколько разных физических материалов: камень, металл, снег, песок, земля, лёд, желе, и т.д.
Почти Библия. Очень вдохновляющий рассказ
«Размолотить в кашу» хороший термин описывающий то что получилось.
кататься по поверхности как-то примитивно, подумайте над тем чтоб соеднить физику полёта в Rokez (https://www.youtube.com/watch?v=SnAIuJsBQKQ) и ваш «мир»

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

Но как минимум я сделаю редактор уровней. И ещё добавлю разные сорта оружия, влияющего на материю. Уже сейчас можно копать в какой-то мере. И это довольно кайфово.
Немного обидно за мою 980M, которая набрала всего 5.8 ниже оптимального. Быстрее её работают ни так уж и много видеокарт :)
В науке подобные симуляции используются в Molecular Dynamics Simulations. Силы, характеризующие кристаллические (прочные, типа бетона или металлов) структуры неплохо описываются гармоническим потенциалом: U=k(x-x0)^2, где x0 задает длину связи, а k — её жесткость. Соответственно для создания жесткой структуры достаточно добавить от каждой частички по 6 (например) гармонических связей к её соседям и получится нечто жесткое. И от 12й степени получится уйти. Ну а проблема несохранения энергии в физических симуляциях решается введением термо/баро-статов. Способов реализации термостатов довольно много, но в Вашем случае, наверное, лучше всего что-то типа термостата ланжевена подошло бы.
Ну и реализацию molecular dynamics на GPU можно подсмотреть, например тут или тут, может какие-то интересные идеи Вам пригодятся.
Для ориентира, openMM обеспечивает производительность в примерно 2.3 тысячи шагов симуляции в секунду для системы из 23558 атомов на NVIDIA Titan X Pascal. На GTX 980 получается примерно половина от этого. Под шагом я понимаю интервал временной дискретизации. А сколько шагов симуляции вы делаете между кадрами? Я так понял, что 10?
Да, 10 шагов между кадрами, то есть 300 в секунду на 30 fps. Для примерно 20000 частиц. Я бы с удовольствием сделал шаг поменьше, но приходится ориентироваться на свою карточку gtx 750m, чтоб не тестировать игру на низких fps.

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

А уход от двенадцатой степени не самоценнен, intrinsic вункции языка HLSL на удивление быстрые, видимо там на низком уровне много ускорения математики. Важна в основном кривая в узкой области вблизи равновесия, её вклад в реакцию материи на толчки — наибольший. У функции U=k(x-x0)^2 вблизи точки равновесия иная кривизна, чем у леннарда-джонса, и сложно предсказать, что даст лучшее поведение материи. Так что поэкспериментирую.
У меня тоже сразу возникла мысль уйти от Леннарда Джонса на потенциал вида -1/((X-Xo)^2+a). Быстрее считает, уход от авоста от 12 степени, не надо срезать. Не надо Рунге-Кутта, Эйлера достаточно. Да и детального сохранения энергии не надо. Единственное, что жалко — красивое название :)

Чтобы уйти от желейности поиграть с вязкостью, так как именно она определяет затухание (а не срезка потенциала Л-Д). Если бы поподробнее о текущих формулах вычисления вязкости…

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

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

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

А формулы для вязкости сейчас таковы, что отсутствует обмен тангенциальной компонентой скорости между соседями. Потому что это тормозило вращение небольших кусков материи. Обмен происходит только долями нормальной компоненты скорости.
Никакого огромного коэффициента:
image
Разница в потенциалах лишь в коэффициентах.
Яма у шестой степени у дна более прямоугольная. Соответственно, более кашеобразный материал получается. Наклон и, соответственно, сила равный при а =7.

А вязкость приведет к затуханию, если не сохранять кинетическую энергию. Уводить в нагрев, если по чесноку физику отбивать. Тангенциальная компонента совершенно правильно игнорируется. Определять к чему относится частица, вроде, накладно.

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

Уход кинетической энергии в нагрев, кстати, есть, я сейчас подумал. При обмене нормальной компонентой относительной скорости часть энергии гасится. Но вязкость у меня считается не для каждой пары достаточно близких частиц, а только если между ними возникает «связь». У каждой частицы есть аналог валентности. Связь может возникнуть с шестью частицами или меньше. Условия возникновения и разрыва связей зависят от типа физического материала. А если делать вязкость для всех частиц, вне зависимости от связей, то материя проявляет жидкостную динамику более, чем динамику твёрдого тела. Для песка или крошашегося бетона это не очень хорошо.

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

мы в восхищении, королева в восхищении (С)

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

Для настройки типов физики у меня сейчас используется что-то около десяти параметров взаимодействия частиц. Это даёт довольно широкий простор для изменений. Единственное ограничение — сила связи. Но мне выше посоветовали использовать другой интегратор, и есть шанс, что он уменьшит ошибку большого шага, что позволит увеличить потолок сил, и это расширит диапазон физических свойств материалов.
А что если обсчёт очередного dt вести в несколько подшагов — в несколько прогонов вычислений для частиц каждого из разнотипных материалов отдельно?
Тогда вместо обсчёта всех 20000 частиц медленным вычислением, можно будет обсчитать 5000 медленным и 15000 быстрым. И значит будет возможность снизить требования к мощи видюх пользователей, или даже заметно увеличить число частиц на уровне.
Сократить число взаимодействий убрав дальнодействие — разбить все пространство на области и считать взаимодействия только внутри областей. Чтобы не появились граничные эффекты на границах областей области должны быть перекрывающимися. Так сказать черепица.
Именно так всё в данный момент и происходит.
Поделюсь своим опытом:
Я как-то тоже делал такой 2D физический движек, сила взаимодействия между частицами у меня была 2 типов:
1) отталкивающая между любыми близкими частицами
2) заранее (при конструировании мира) заданный набор притягивающих связей. Эти связи разрушались, если частицы отдалялись друг от друга далее определьного расстояния.
image

Вместо желе получились вполне нормальные упругие тела.
Здорово! А это оно в реальном времени так прыгает? И сколько частиц в сцене? В моей модели тоже жёстко получается, если сделать лчень маленький шаг, и увеличить силу взаимодействия. Но это повлияло бы напроизводительность, потому что ради быстрых вычислений в реальном времени пришлось бы сократить число частиц в сцене.
Да это в реальном времени около 2000 частиц, в один поток, на CPU, на Mac Pro 2015.
Чтобы получить такую жесткость действительно пришлось сильно уменьшить шаг интегрирования (100 микросекунд), при большем шаге тела ближе к пудингу. Вообще асимптотика нагрузки на CPU от «жесткости» не знаю какая но очень крутая, надо как-нибудь попробовать вывести… Давно мечтаю придумать что-нибудь чтобы ее улучшить, но идеи пока сырые… ))
Но в такой конфигурации сил тела по крайней мере сохраняют форму. Я тоже пробовал с силой Леннарда-Джонса, но тела тогда расползаются и деформируются, а тут гнутся до предела — потом рвутся. Наверно так можно разные материалы моделировать.
Я на леннарде-джонсе использовал высокие коэффициенты, так что тела ближе к упругости. Использовал бы ещё более высокие, но это потребовало бы уменьшения шага, чтоб всё не взрывалось из-за ошибки большого шага.

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

Кстати, разрыв связей при привышении порога я тоже сделал. То есть, у меня две системы наложены. Примерно такая, что у вас действует до разрушения, а после — чистый леннард-джонс без запрета на разрыв связи.
Я еще заранее собираю тела в правильной кристаллической решетке (6-гранные соты). Все связи заданы заранее в 6 направлениях от каждой частицы.
Не делал точных замеров но по ощущениям увеличивает эффективную прочность тел.
Я тоже собираю, все уровни так строятся, частицы размещаются в узлах шестиугольной решётки, чтоб сразу попасть в равновесие. А в первых экспериментах этого не делалось, частицы просто вбрасывались на уровень кучей. И там можно было наблюдать интересный эффект, как внутри тела существуют конкурирующие кристаллы с разным углом кристаллизации, и если нагревать эту материю, то одни области поглощаюд другие, распространяя на них свой порядок.
Кстати, а какой метод интегрирования у Вас?
У меня Верле, хотя и Эйлер не сильно по эффективности отличается (по экспериментам: процентов на 10 примерно уменьшение шага интегрирования компенсирует разницу между ними)
10%? Неплохо. Я как раз хочу перейти с Эйлера на Верле, как мне тут посоветовали. А с Рунге-Куттой не сравнивали?
Эффективность я оцениваю так: на одной и той же сцене какой максимальной длинны можно сделать шаг интегрирования прежде чем все взрывается. От метода зависит очень слабо.
Рунге-Кутта не пробовал, вычислительно сложнее а выигрыш точности явно не скомпенсирует этого. Тут бы придумать что-то для неравномерного интегрирования, чтобы одни частицы чаще другие реже…
Да, именно такой способ оценки эффективности меня интересует. Спасибо, что поделились опытом сравнения интеграторов с этих позиций.

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

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

А как Вы распараллеливали вычисления? Делили сцену на сегменты по потокам, если так то как синхронизовывали стыки?
Параллелизация идёт по частицам. На каждую частицу — один поток на каждом шаге вычислений.

Сцена разделена на сегменты ради того, чтоб каждая частица взаимодействовала только с соседями, а не просматривала весь объём частиц в поиске соседей. Но радиус взаимодействия меньше размера просматриваемой в поисках соседей области сетки, так что проблема стыков отсутствует.
Поток на частицу? У Вас тысячи потоков? А структура данных по которой вы ищете ближайших соседей синхронизуется каждый тик по всему объему? Мне не доводилось считать на GPU не знаю особенностей.
Я предполагал что-то вроде разбиения сцены на N не пересекающихся участков и в каждом обсчитывать все частицы в одном потоке. Возникают нюансы синхронизации на стыке этих участков.
Так тоже делают, с разбиением пространства. Хотя, обычно каждый кусок протранства считают на отдельной видеокарте.

И да, у меня десятки тысяч потоков, по числу частиц. А когда текстура рендерится — по потоку на пиксель -> миллион потоков. Архитектура GPU очень развита для работы с таким количеством.

Структура данных, которая хранит ссылки на ближайших соседей, обновляется каждый тик, да. Это занимает ничтожную долю вычислительного времени.
Ваша задача очень хорошо исследована, еще с 70х годов, обычно проходит под именем «молекулярная механика» («molecular mechanics») или «молекулярная динамика» (molecular dynamics). В последние лет 10 исследовано также применение GPU и даже FPGA и ASIC к этой задаче. Также исследованы в контексте этой задачи алгоритмы интегрирования, термостаты, способы уменьшения сложности вычислений уходом от дальнодействия (distance cutoffs, reaction field, Particle Mesh Ewald, etc). Есть готовые open-source реализации на C/C++/Fortran/CUDA/OpenCL с очень высокой производительностью (ссылки давал выше).

В MD обычно применяют многокомпонентные потенциалы. Близкое взаимодействие происходит от гармонического потенциала и других, а дальнее — леннард-джонс + кулон.
У меня он и используется, но упрощённо — чистый леннард-джонс.

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

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

На данный момент у меня есть два вопроса: какой интегратор покажет лучшие резальтаты меньшей ценой производительности. И можно ли на что-то заменить силу ланнарда-джонса, с тем же критерием.
Спасибо за информацию и ссылки, обязательно почитаю.
Как я понимаю, там все же больше уклон именно в точное моделирование для научных целей. Тут нужно для игры и приемлемы любые хаки, которые сохранят визуальную правдоподобность и не более.
Согласен, но для научного моделирования важна производительность, поэтому все возможные хаки и не хаки тоже рассматриваются и оцениваются с точки зрения преимуществ/недостатков и можно было бы про это прочитать и может быть даже взять что-то, от чего в MD в своё время отказались.
Да, технически это возможно, но у меня нет машины на Линуксе, чтоб сделать билд, так что я пока игру доделаю до более вменяемого вида, и тогда выпущу для Линукса и МакОС.
Поздравляю с ранний релизом! Уважаю за упорность развития проекта.
Хотел поделиться парой мыслей насчет развития, хотя, вероятно, изменения слишком радикальные для уже отрелиженной игры.
Вы не думали отойти от стилистики scorched earth в сторону чего-то другого? У вас уже есть отличный движок, но вы пошли по пути дополнения модели, чтобы все хорошо выглядело в выбранной стилистике. Другой путь был бы: если все выглядит как манная каша и желе — то и стилистика должна соответствовать манной каше и желе. Это могут быть зефирки или орешки истребляющие друг друга за место в мороженом, или инопланетные личинки в слизи… ну или что-нибудь еще такое не серьезное, но яркое и интересное.
Я сделал пару уровней с кондитерской тематикой. В остальном, пока хочется придерживаться реализма в декорациях. А дальше посмотрю по массовой реакции игроков. Если для людей будет неприемлема желейность в бетонных столбах, придётся менять стиль.

Мне это напомнило какую-то игру, которая у меня была на Sony Ericsson. Только там нельзя было двигаться, и танки стреляли поочерёдно.


Сделано очень круто! Поздравляю!


Я сейчас работаю над кампанией для одного игрока

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


Посмотрите хотя бы на "BattleBlock Theater" или "Move or Die". История не так увлекает, как возможность пофаниться с друзьями. А в вашей игре, с написанной вами физикой, фана будет море, судя по всему.

Кстати, решил открыть свой стим и посмотреть список рекомендуемого. Нашёл там это.


Вот примерно о таком конечном результате я говорил. Отзывы "Очень положительные". Синглплеер в такой игре вряд ли кого заинтересует, ибо делать там нечего особо, а вот мультиплеер...

Согласен, мультиплеер — основной источник интереса. Мультиплеер я запланировал, но для этого нужно сначала исправить недетерминированность симуляции, чтобы синхронизация была не слишком сложной.
А стоит ли уж так дотошно синхронизировать? Лишь бы не до уровня «победил игрок 1 и одновременно с победил игрок 2». А о разнице в деталях мы никому не скажем.
Было бы интересно поиграть с такой физикой, но в сеттинге Teeworlds(с теми же режимами deathmatch,capture the flag,etc).
Имхо это была бы не бомба, но весьма востребованной игрой.)
Да, интересно. Я в эту сторону движок как раз и поведу. Чтоб строить полноценные уровни из разрушаемой материи, и на них играть в мультиплеере.
Отличная идея. Удачи вам!
Позволю несколько советов/замечаний:
  • Никогда не оправдывайтесь, что игра платная (видел ваши ответы под роликом на ютубе). Любой труд должен быть оплачен.
  • Интересно бы было иметь возможно собирать свой танк, как из конструктора(это добавило вариативность в прохождение). Причем не просто из декоративных модулей, а именно функциональных.
  • Трейлер не очень. Вроде и неплохо, музыка хорошая, красивые кадры, но он должен интриговать и привлекать внимание с первых же кадров, а вы наоборот весь сок ближе к концу разместили. Ну и таких мелочей в рекламном видеоролики много.
  • Свяжитесь с летсплейщиками (тот же куплинов), которые смогут отлично продвинуть игру просто играя на своих каналах. Причем бесплатно для Вас.
  • Ну и «Кооператив наше все» (с) десятые годы 2 тысячелетия.


Спасибо за замечания.

Модульность танка я обдумываю. Сейчас пока есть прямая прокачка. Купил апгрейд двигателя — едет мощнее. Но новые разновидности танков понадобятся, так что скорее всего сделаю конструктор из универсальных деталей.

С летсплейщиками свяжусь когда кампания будет готова, чтобы им было во что поиграть. Пока только hot seat есть, это не так зрелищно.

Мультиплеер — в ближайших планах. Пока есть технические трудности, но вроде решаемые.

С трейлером пока непонятно, как поступать. Я его по сути собрал из гифок, которые привлекли внимание раньше на реддите. Почитаю что-нибудь на эту тему.
(Музыка — из техно-оперы Виктора Аргонова «2032». Не очень подходит по смыслу, но волнующая).

Вот это — очень серьезная ошибка. Есть узкий круг людей, которым такая музыка нравится. Им будет «волнующая». Для всех остальных она будет только «не подходит по смыслу и жанру». Необходимо чувствовать жанр и подбирать музыку под него. Вот другому разработчику нравится Гарри Мур и он тоже б в трейлер вставил волнующую, но не подходящую по смыслу музыку.

В общем, мой вам совет — подберите не то, что вам нравится слушать, а то, что подходит под игру. Потому что сейчас из-за неудачной музыки теряется 80% динамизма трейлера.
Я тоже хотел откомментить про музон :) Это частая ошибка.

Но сама игра очень заинтересовала. Желейные колонны тоже понравились.
Напомнило Cortex Command, но там физика по ощущениям ближе к твердым телам
А что если еще усложнить систему большей реальностью, скажем сделать не отдельные виды материала, а виды химических соединений и отдельные атомы из периодической системы, все данные по ним уже известны, как и, в принципе, взаимодействие друг с другом и поведение в нашем мире.

Вопрос автору — играл ли ты когда нибудь в Broforce? Нет ли у тебя желания создать что-то подобное, скажем, совместить твои наработки с DeadBoys (не знаю найдется ли еще такая игра в папках интернета), с OpenLieroX и с Soldat'ом? Кооперативка на 4-х игроков с трэшевым Deathmatch)
Чёрт ещё одна реализация position-based физики, с годной статьи gamedev.ru бородатой древности :)
Sign up to leave a comment.

Articles