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

Многие здания на уровнях внутри тоже усилены.
Но это не помогло бы увеличить шаг с сохранением твёрдости. Кость задаёт расстояние между парой частиц, все друг к другу не закрепишь. А события, нарушающие закон созранения энергии происходят по всему объёму. И если увеличить шаг, кости не спасут материю от спонтанной детонации.
Но у костей есть и дополнительная роль, они анимируют мостики. Так что их существование оправдано расширением геймплея.
Предполагаю что адекватного решения для мультиплеера в реальном времени тут и не сделать никак, т.к. в отличии от других игр с меньшим количеством значимых изменений поведение будет слишком разниться.
Можно, конечно, отрисовывать только то, что получено от сервера, рандом считать с общим семенем, но тогда очень лимитируется расстояние до самого сервера, особенно с учетом прям реалтайм действий.
Буду рад если меня тут поправят и расскажут о адекватных вариантах.
Можно, конечно, отрисовывать только то, что получено от сервера, рандом считать с общим семенем, но тогда очень лимитируется расстояние до самого сервера, особенно с учетом прям реалтайм действий.
Не соглашусь. 30-50 мс — это вполне комфортная задержка, которой не замечаешь. Знаю из опыта облачного гейминга :)
Как в таких случаях организовывать lag compensation?
Как я понял игра пошаговая, как worms, там что тут не нужна реакция на изменение в мире в реальном времени
синхронизировать семя рандома и просто сообщать место взрыва
Скажу по опыту — не все видеокарты считают одинаково. Так что могут быть серьезные расхождения в мире из миллиона частиц
Кстати, даже с интами видеокарты ведут себя по-разному. Когда-нибудь проверяли, что будет, если ноль поделить на ноль на гпу разных производителей? или корень из минус единицы? Что будет, если вывести в цвет значение nan или бесконечность? Помню был случай, когда при записи в цвет +бесконечность некоторые гпу выводили белый цвет, а некоторые черный. Конечно все это граничные условия, которые по-хорошему бы обрабатывать отдельно, но все же…
Есть еще вероятность, что с интами видеокарта будет работать медленнее.
Касательно интов — да, мне говорили, что видеокарты внутри себя всё во float считают, а инты будут медленней. При этом, существует ряд intrinsic atomic functions, которые пишут общие данные в защищённом режиме, так вот, эти функции существуют только для целы чисел, а для с плавающей точкой — нет. Странно.
А компилятор говорит, что вместо интов лучше использовать uint, потому что они быстрей. Так что сделаю на uint, всего вероятней. Потому что обработать граничные случаи, чтоб разные карточки не имели вольности можно, а вот если производительность потеряю, это будет хуже.
Касательно интов — да, мне говорили, что видеокарты внутри себя всё во float считают, а инты будут медленней.А зачем гадать? Можно же посмотреть cycles per instruction throughput для нужного GPU и выяснить наверняка.
Или вот вопрос, там говорится про int и float, а у меня компилятор говорит: чтоб быстрей считать, используйте uint вместо int. А в таблице этого различия не упомянуто, в чём может быть дело?
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, и сделаю все вычисления не зависящими от порядка обращения параллельных потоков к общим данным.
Если получится, сделаю мультиплеер с запаздыванием на пару фреймов, чтоб игроки обменялись нажатыми клавишами, так как состояние будет полностью определяться вводом игроков. Да и для пошагового режима активный игрок будет играть в реальном времени без задержки, а остальные игроки будут просто видеть, что происходит, тут задержка не важна.
А если не получится с детерминированностью, буду мудрить с оптимизацией синхронизации, это будет сложно, но очень хочется мультиплеер, можно заморочиться.
Интересно было бы почитать про это.
А почитать об этом, кроме упомянутого первого поста на хабре, можно ещё в моём посте на пикабу.
Очень здорово! Сам думал о таком, вдохновившись The Powder Toy, так же, с подвижными объектами, разрушениями, плавлением, расчетами на видеокарте и т.п, но дальше теоретического фантазирования дело так и не дошло.
P.S. Не нашел информации, OpenCL или CUDA? Будет работать на AMD видеокартах?
Сделал в Юнити, на compute shader. Код шейдера пишется на HLSL, и юнити компилит его на directX или openCL. Так что на вполне AMD работает. А новая версия даже умеет компилить под Metal.
steamcommunity.com/app/1196080
Мне кажется, КДПВ с "сырой" реализацией выглядит гораздо лучше остальных.
Причем, полагаю, именно в GIF, за счет дизеринга. Такой-то веб-панковский вид.
1. Можно ли код интегратора посмотреть?
2. Когда игра будет доступна?
2. Уже доступна на раннем доступе в стиме для винды, в конце поста ссылочка есть.
А контактная модель соударения (взаимодействия) частиц какая используется? У вас при бОльшем шаге dt смещение частиц большое, они перекрываются больше и по закону Гука нормальная составляющая контактной силы F=kx очень большая, а из-за нее, соответственно, ускорение большое и скорость на следующей итерации у частиц очень большая, поэтому частицы улетают «в небеса». Опишите подробнее контактное взаимодействие. Возможно, его можно поднастроить. Хотя бы общая формула. Обычно, нормальная составляющая выражает упруго-пластическое взаимодействие, тангенциальная — силу трения. У вас, наверное, так.
Но поэкспериментировав, я от него отказался. Кажется, потому, что вычисления усложнялись, когда на одном шагу пересекались траектории сразу нескольких частиц, и надо было обрабатывать столкновения всей этой системы.
Так что сейчас используется только сила Леннарда-Джонса. Небольшая доля частиц движется быстро, и, действительно, перекрываются в столкновении, с возникновением неадекватных величин в нормальной составляющей силы взаимодействия. Но я это исправил, обрезав пики у кривой Леннарда-Джонса, оставив плато. Большинство частиц взаимодействуют в области вблизи равновесия между отталкиванием и притяжением, и там значения величины силы корректное. А если экстремальное сближение происходит, сила не растёт.
Из-за редкости такого события, её влияние на модель незначительно, хотя есть случаи, когда оно играет главную роль. Например, в окрестности мощных взрывов материя проминается взрывом, так как сразу много частиц взаимодействуют в области плато из-за большой внешней силы. Или если большой твёрдый кусок материи сталкивается на высокой скорости с землёй или другим куском, столкновение демпфируется именно этим эффектом взаимодействия в области плато в области контакта кусков.
Эти случаи, конечно, ослабляют реализм, но я расцениваю их адекватной платой за повышенную жёсткость материи.
Помимо силы Леннарда-Джонса, есть ещё вязкость. При чём — не помню, из каких соображений — я реализовал только нормальную компоненту вязкости. Пара частиц обменивается долей их относительной скорости, проецирующейся на соединяющую их центры прямую.
Вместо разностной схемы мне на реддите предложили попробовать rk4. Я счёл, что это исправит ситуацию для экстремальных градиентов поля, но за это придётся заплатить большим количеством вычислений, так что выигрыш не гарантирован. Поэтому, я пока не спешу её пробовать. Скрее всего попробую её позже, когда возьмусь за перевод модели с float значений на int, в надежде сделать симуляцию детерминированной.
Преимущества: менее требовательна к железу, больше скорость, а вот недостатки: ее на больших временных шагах нельзя использовать — ошибка быстро нарастает.
А ещё она теряет устойчивость при решении жестких систем уравнений, которые как раз это самое контактное взаимодействие и описывают
Можно использовать неявную схему Эйлера, если система уравнений линейная, то получается вообще шикарно
1. А форма частиц какая? Только круглые? Примените прямоугольники-квадраты — будет более стабильно смотреться. Однако у «движка» скорость упадет — больше вычислений на детектирование коллизий между объектами и вычисление контактных сил.
2. Масса у всех частиц одинаковая? Может некоторым частицам массы добавить — инерция увеличится и не будет заметно «желе»?
SPH симуляции («на круглых частицах») — наиболее эффективно считаются в Soft Body, даже nVidia в nVidia Flex даунсемплит до массивов круглых шариков объекты, чтобы физику мягкого тела можно было считать в realtime
А формы у частиц нет, они как точки взаимодействуют, столкновений не происходит, только взаимные силы с градиентом величины по расстоянию.
Мне кажется стоит смотреть в сторону динамической детализации. Сколько частиц не считай, всё равно будет мало. Важно правильно выбирать детализацию. Нужен LOD для физики.
В Minecraft был мод — LittleBlocks, жаль забросили его уже много лет. Позволял разбить блок на более мелкие детали, но физики там не было. Был мод с физикой(не очень интересной, но всё же), но он не работал с LittleBlocks. Скрестить бы их, уже было бы хорошо. Что-то оставляем в виде плохой детализации, что-то в более хорошей.
Пока лучшее, что я видел с физикой в 3D, это заброшенный проект SoA.
Но перестал следить, может есть что-то более интересное?
Оказывается VoxelFarm, продолжает как-то развиваться.
B AtomontageEngine тоже не совсем мёртв.
Но вообще идея с воксельной физикой почему-то очень медленно развивается.
Я пять лет назад думал, что появится очень быстро много интересных проектов.
Но все мертвы.
Удачи вам хотя бы с 2D.
SoA прикольно выглядит, спасибо за ссылку.
А из интересного я недавно видел вот такую штуку: там тоже материя из частиц, но в 3д и с VR.
Простой пример: дать ограниченое число патронов для мощной пушки. Будет выбор: проломить стену и обойти врага или сохранить их для битвы с боссом. Впрочем, я только начал делать уровни кампании и тестировать задумки. Возможно, многие из них окажутся непрактичны из-за открывающихся коротких путей.
В итоге можно увеличивать шаг(ценой точности) и использовать больше частиц, хотя некоторые soft-core потенциалы могут быть сами по себе сложнее для вычислений, что скажется на FPS.
Почти Библия. Очень вдохновляющий рассказ
кататься по поверхности как-то примитивно, подумайте над тем чтоб соеднить физику полёта в Rokez (https://www.youtube.com/watch?v=SnAIuJsBQKQ) и ваш «мир»
А так конечно получилось забавно, интересная статья, спасибо
Но как минимум я сделаю редактор уровней. И ещё добавлю разные сорта оружия, влияющего на материю. Уже сейчас можно копать в какой-то мере. И это довольно кайфово.
Ну и реализацию molecular dynamics на GPU можно подсмотреть, например тут или тут, может какие-то интересные идеи Вам пригодятся.
Насчёт функции силы я согласен, наверняка есть более эффективная альтернатива. Я поэкспериментирую с предложенным вами вариантом, когда снова возмусь за физику.
А уход от двенадцатой степени не самоценнен, intrinsic вункции языка HLSL на удивление быстрые, видимо там на низком уровне много ускорения математики. Важна в основном кривая в узкой области вблизи равновесия, её вклад в реакцию материи на толчки — наибольший. У функции U=k(x-x0)^2 вблизи точки равновесия иная кривизна, чем у леннарда-джонса, и сложно предсказать, что даст лучшее поведение материи. Так что поэкспериментирую.
Чтобы уйти от желейности поиграть с вязкостью, так как именно она определяет затухание (а не срезка потенциала Л-Д). Если бы поподробнее о текущих формулах вычисления вязкости…
Видел начало этой работы не помню где. Запало в душу ещё тогда. Молодца!
А затухание у меня задаётся вообще читерским способом. Дело в том, что если что-то делать с абсолютной скоростью, то летящие в воздухе куски материи будут неестественно тормозиться. А если через вязкость распространять между частицами доли их относительной скорости, то общая энергия системы не будет падать, а это нужно, чтоб после взрывов всё успокаивалось.
Поэтому, я ввёл систему, которая на каждом шагу выясняет для каждой частицы, является ли она частью большого покоящегося на земле куска или летит в воздухе. И если является. то из её абсолютной скорости вычитается малая доля.
А формулы для вязкости сейчас таковы, что отсутствует обмен тангенциальной компонентой скорости между соседями. Потому что это тормозило вращение небольших кусков материи. Обмен происходит только долями нормальной компоненты скорости.

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

Вместо желе получились вполне нормальные упругие тела.
Чтобы получить такую жесткость действительно пришлось сильно уменьшить шаг интегрирования (100 микросекунд), при большем шаге тела ближе к пудингу. Вообще асимптотика нагрузки на CPU от «жесткости» не знаю какая но очень крутая, надо как-нибудь попробовать вывести… Давно мечтаю придумать что-нибудь чтобы ее улучшить, но идеи пока сырые… ))
Но в такой конфигурации сил тела по крайней мере сохраняют форму. Я тоже пробовал с силой Леннарда-Джонса, но тела тогда расползаются и деформируются, а тут гнутся до предела — потом рвутся. Наверно так можно разные материалы моделировать.
Но я тут подумал, что леннард-джонс вообще-то для трёхмерных тел вычислен. В двумерном случае силы должны быть выше, для достижения того же эффекта. Выяснение оптимальной формы и кривизны кривой сил вблизи точки равновесия — интересный вопрос. Оптимальной — именно с точки зрения количества производительности, затрачиваемой на единицу жёсткости. Я бы подэкспериментировал с этим, но хочется от физики перейти к геймплею, чтоб игру закончить.
Кстати, разрыв связей при привышении порога я тоже сделал. То есть, у меня две системы наложены. Примерно такая, что у вас действует до разрушения, а после — чистый леннард-джонс без запрета на разрыв связи.
Не делал точных замеров но по ощущениям увеличивает эффективную прочность тел.
У меня Верле, хотя и Эйлер не сильно по эффективности отличается (по экспериментам: процентов на 10 примерно уменьшение шага интегрирования компенсирует разницу между ними)
Рунге-Кутта не пробовал, вычислительно сложнее а выигрыш точности явно не скомпенсирует этого. Тут бы придумать что-то для неравномерного интегрирования, чтобы одни частицы чаще другие реже…
Насчёт неравномерного интегрирования я тоже думал, но есть ощущение, что выигрыш упразднится стоимостью вычислений, позволяющих исключить некоторые частицы из обсчёта. По этой дорожке луче идти до конца, и большую часть материи держать в виде полигональных коллайдеров, а там тоже всякие сложности возникают…
Сцена разделена на сегменты ради того, чтоб каждая частица взаимодействовала только с соседями, а не просматривала весь объём частиц в поиске соседей. Но радиус взаимодействия меньше размера просматриваемой в поисках соседей области сетки, так что проблема стыков отсутствует.
Я предполагал что-то вроде разбиения сцены на N не пересекающихся участков и в каждом обсчитывать все частицы в одном потоке. Возникают нюансы синхронизации на стыке этих участков.
И да, у меня десятки тысяч потоков, по числу частиц. А когда текстура рендерится — по потоку на пиксель -> миллион потоков. Архитектура GPU очень развита для работы с таким количеством.
Структура данных, которая хранит ссылки на ближайших соседей, обновляется каждый тик, да. Это занимает ничтожную долю вычислительного времени.
В MD обычно применяют многокомпонентные потенциалы. Близкое взаимодействие происходит от гармонического потенциала и других, а дальнее — леннард-джонс + кулон.
Но тут проблема в том, что высокая крутизна кривой вблизи точки равновесия необхоима, но она уводит величину силы отталкивания слишком быстро в запредельную область. Так что приходится либо уменьшать шаг, либо резать пик силы отталкивания.
То есть, борьба идёт за удешевление жёсткости взаимодействия в валюте производительности. Но борьба эта идёт уже в области высокой ошибки из-за большого шага, так как это неизмежный компромисс. И поэтому признаные оптимальные решения для областей с малым шагом и малой ошибкой могут быть неприменимы в данном случае, так как они могут быть слишком чувствительны к ошибке. Я использовал силу леннард-джонса с крутым коэффициентом, но обрезал пик. Это уже очень грубое решение. Но оно позволяет получить большую жёткость для слабых взаимодействий между частицами. Так что мой случай несколько в стороне от типичных расчётов, и приходится искать оптимальные решения самостоятельно.
На данный момент у меня есть два вопроса: какой интегратор покажет лучшие резальтаты меньшей ценой производительности. И можно ли на что-то заменить силу ланнарда-джонса, с тем же критерием.
Как я понимаю, там все же больше уклон именно в точное моделирование для научных целей. Тут нужно для игры и приемлемы любые хаки, которые сохранят визуальную правдоподобность и не более.
Хотел поделиться парой мыслей насчет развития, хотя, вероятно, изменения слишком радикальные для уже отрелиженной игры.
Вы не думали отойти от стилистики scorched earth в сторону чего-то другого? У вас уже есть отличный движок, но вы пошли по пути дополнения модели, чтобы все хорошо выглядело в выбранной стилистике. Другой путь был бы: если все выглядит как манная каша и желе — то и стилистика должна соответствовать манной каше и желе. Это могут быть зефирки или орешки истребляющие друг друга за место в мороженом, или инопланетные личинки в слизи… ну или что-нибудь еще такое не серьезное, но яркое и интересное.
Мне это напомнило какую-то игру, которая у меня была на Sony Ericsson. Только там нельзя было двигаться, и танки стреляли поочерёдно.
Сделано очень круто! Поздравляю!
Я сейчас работаю над кампанией для одного игрока
Я бы на вашем месте начал с кооператива. Сейчас мало кто играет одиночные игры. Большинство игроков в Steam покупают инди игры для того, чтобы повеселиться с друзьями, а не проходить историю.
Посмотрите хотя бы на "BattleBlock Theater" или "Move or Die". История не так увлекает, как возможность пофаниться с друзьями. А в вашей игре, с написанной вами физикой, фана будет море, судя по всему.
Имхо это была бы не бомба, но весьма востребованной игрой.)
Позволю несколько советов/замечаний:
- Никогда не оправдывайтесь, что игра платная (видел ваши ответы под роликом на ютубе). Любой труд должен быть оплачен.
- Интересно бы было иметь возможно собирать свой танк, как из конструктора(это добавило вариативность в прохождение). Причем не просто из декоративных модулей, а именно функциональных.
- Трейлер не очень. Вроде и неплохо, музыка хорошая, красивые кадры, но он должен интриговать и привлекать внимание с первых же кадров, а вы наоборот весь сок ближе к концу разместили. Ну и таких мелочей в рекламном видеоролики много.
- Свяжитесь с летсплейщиками (тот же куплинов), которые смогут отлично продвинуть игру просто играя на своих каналах. Причем бесплатно для Вас.
- Ну и «Кооператив наше все» (с) десятые годы 2 тысячелетия.
Модульность танка я обдумываю. Сейчас пока есть прямая прокачка. Купил апгрейд двигателя — едет мощнее. Но новые разновидности танков понадобятся, так что скорее всего сделаю конструктор из универсальных деталей.
С летсплейщиками свяжусь когда кампания будет готова, чтобы им было во что поиграть. Пока только hot seat есть, это не так зрелищно.
Мультиплеер — в ближайших планах. Пока есть технические трудности, но вроде решаемые.
С трейлером пока непонятно, как поступать. Я его по сути собрал из гифок, которые привлекли внимание раньше на реддите. Почитаю что-нибудь на эту тему.
(Музыка — из техно-оперы Виктора Аргонова «2032». Не очень подходит по смыслу, но волнующая).
Вот это — очень серьезная ошибка. Есть узкий круг людей, которым такая музыка нравится. Им будет «волнующая». Для всех остальных она будет только «не подходит по смыслу и жанру». Необходимо чувствовать жанр и подбирать музыку под него. Вот другому разработчику нравится Гарри Мур и он тоже б в трейлер вставил волнующую, но не подходящую по смыслу музыку.
В общем, мой вам совет — подберите не то, что вам нравится слушать, а то, что подходит под игру. Потому что сейчас из-за неудачной музыки теряется 80% динамизма трейлера.
Вопрос автору — играл ли ты когда нибудь в Broforce? Нет ли у тебя желания создать что-то подобное, скажем, совместить твои наработки с DeadBoys (не знаю найдется ли еще такая игра в папках интернета), с OpenLieroX и с Soldat'ом? Кооперативка на 4-х игроков с трэшевым Deathmatch)
Разработка игры на основе физической симуляции (для реалистичной разрушаемости игрового мира)