Рубить и кромсать: как работает разрезание объектов в играх

На примере Metal Gear Rising: Revengeance, Tiny & Big и Hardspace: Shipbreaker.

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

Рубить и кромсать: как работает разрезание объектов в играх

Взять, к примеру, недавнюю Ghostrunner: несмотря на реки крови, киберниндзя кромсает врагов на части крайне редко, а зачастую меч движется настолько быстро, что мы даже не видим, куда именно и под каким углом он попадает в противника. Разработчики используют это, чтобы сэкономить ресурсы, и предлагают нам всего два варианта: либо Тень отрубает противнику голову, либо разрубает пополам. Ну, или взрывает его, оставляя только кровавое облачко.

Игрок задирает голову и, соответственно, катану, вверх и чуть в сторону, но удар все равно приходится ровно в пояс противнику

Однако есть разработчики, которые по тем или иным причинам хотят сделать максимально достоверные взрывы, разрезы и разрушения в своих играх. В 2012 году вышла Metal Gear Rising: Revengeance, и одной из главных её фишек была возможность разрезать почти все объекты на локации под каким угодно углом.

Фича настолько потрясла геймеров и разработчиков того времени, что до сих пор на Reddit то тут, то там всплывают темы вроде «A как сделать динамическое разрезание сетки как в MGR, только в %вставить название движка%?».

Ещё во время демонстрации MGS: Rising Хидео Кодзима показывал вдохновляющий отрывок, в котором Райден в режиме реального времени кромсал арбузы на мелкие кусочки своей катаной… Стол при этом почему-то не пострадал. А о том, при чём же здесь на самом деле арбузы, мы поговорим немного позже.

Ни один стол не пострадал! Чего, впрочем, не скажешь о кеглях…

Некоторой проблемой и, соответственно, пространством для спекуляций на форумах было то, что PlatinumGames отказалась от предложенного им Fox Engine или популярного в то время Unreal Engine 3.

Вместо этого студия делала игру на своих внутренних ресурсах, подключив мощности популярного в ранние 2010-е физического движка Havok. А в марте этого года и вовсе официально заявила, что полностью отказываются от Unreal Engine и Unity в дальнейшем: Platinum Engine, по словам разработчиков, и гибче, и картинку выдает детальнее, и удобнее, и вообще лучше во всех отношениях.

Уже в год своего выхода Metal Gear Rising: Revengeance не могла похвастаться передовой графикой. Но из движка Havok PlatinumGames выжала максимум возможностей. Обратите внимание на то, что какие-то части разрубленного ящика отваливаются, а какие-то остаются висеть в воздухе. Это будет важно в дальнейшем.

Единственной проблемой и консолей, и старой версии движка была невозможность просчитывать взаимодействие персонажей и порубленных частиц, из-за чего уже через 10-20 секунд результаты истерической шинковки исчезали прямо на глазах Райдена.

В один год с MGR вышла ещё одна игра с проработанной механикой расчленения: Tiny & Big: Grandpa’s Leftovers. Инди-платформер с простенькой графикой и геометрией, однако той же killing feature — режь всё, что хочешь! Разработчики игры охотно поделились на Reddit тем, как они решали проблему «расчленёнки в реальном времени».

Мы настроили Булевы состояния для объектов CSG (Constructive Solid Geometry или Конструктивная Блочная Геометрия: способ формирования объектов в трехмерном пространстве из простых геометрических форм — DTF). Для примитивных геометрических форм (шар, пирамида, куб и так далее) это довольно просто: ты отделяешь одну часть вершин объёмной сетки от другой, при этом создаются новые вершины, которые формируют фигуру сечения.

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

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

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

harvester, разработчик Tiny&Big: Grandpa’s Leftovers

И вот в 2020 году в ранний доступ выходит Hardspace: Shipbreaker. Игра симулирует разборку космического корабля в безвоздушном пространстве. Сам игрок при этом орудует плазменным резаком — прямо как в Dead Space. Однако разница очевидна: вместо заскриптованных попаданий и заранее отрисованных разрезов и взрывов, здесь мы вольны резать всё так, как нам вздумается. Главное при этом — ничего не взорвать.

Разработчики из BlackBird Interactive постарались сделать все разрушения, разрезы и взрывы в игре генерируемыми в реальном времени, а не отрисованными заранее. В рамках конференции GDC Summer 2020 технический директор BBI Ричард Харрисон подробно рассказал о том, как работает геометрия в Unity, при чём же здесь арбузы и как связана с космическими кораблями The Legend of Zelda.

Одна из первых проблем, с которой столкнулись в BBI, — это необходимость работать с объёмными сетками (convex meshes). Несмотря на то, что по ним движок может наиболее точно разделять объекты, впоследствии ему может быть слишком сложно просчитывать свободный полёт и столкновения вновь полученных сеток. А объектов получается много, и просто убрать их нельзя — абсолютно всё в Hardspace Shipbreaker можно продать как вторсырье.

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

Рубить и кромсать: как работает разрезание объектов в играх

Первое же, на что обращает внимание разработчик, — это количество вершин. В школе нас учат, что у куба их восемь, однако в геометрии Unity их 24 — по одной на каждую грань. Также куб состоит из 12 треугольников: каждая из шести граней разделяется на два треугольника.

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

Рубить и кромсать: как работает разрезание объектов в играх

Важно помнить: то, что было объёмным и выпуклым изначально, остается объёмным и выпуклым.

Рубить и кромсать: как работает разрезание объектов в играх

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

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

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

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

Что касается заполнения образовавшейся грани. Объёмные сетки похожи на папье-маше — они полые, и после рассечения нам также нужно их заполнить вершинами и треугольниками. Здесь нам понадобятся вершины, образовавшиеся в середине ребер и сторон треугольников. Из них мы произведем веерную триангуляцию (Centroid fan-fill triangulation) внутренней части сетки.

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

Весь процесс разработчики назвали «Арбузированием» (watermeloning), потому что такую модель, при которой объёмная сетка разрезается, а её содержимое отренедеривается на ходу, они тестировали на объектах, похожих на арбуз, с разными и чётко различимыми текстурами изнутри и снаружи. Также для создания иллюзии обёмности изображения внутри сетки, BBI использовали карты перспективы (Parallax Maps).

Рубить и кромсать: как работает разрезание объектов в играх

Теперь подробнее о том, как работает эффект разрезания арбуза.

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

Рубить и кромсать: как работает разрезание объектов в играх

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

Благодаря объёмным сеткам команда BBI разобрались, как разрезать модель и заполнять её текстурой. Но для каждого нового объекта нужно заново просчитывать его объём, параметры и массу. Это очень ресурсоёмкий процесс, который создателям игры нужно было упростить.

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

Чтобы понять, как это работает, представьте, что вы хотите разделить на две части отрезок длиной в десять сантиметров, а затем замерили полученные отрезки тремя разными приборами. Линейка скажет, что вы разделили отрезок на отрезки 5,1 и 4,9 см, штангенциркуль — 5,12 и 4,88 см, а микрометр — 5,116 и 4,884 см соответственно.

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

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

Для сборки модулей корабля из отдельных объектов Харрисон и команда разработали концепцию «космического клея». Её суть на словах довольно проста: если после разрезания объект остается присоединенным к кораблю, он не должен отваливаться, и наоборот. Но реализовать концепцию оказалось довольно сложно.

Для каждых двух объектов, один из которых может быть отсоединен от другого, разработчики добавили систему «точек соединения» или «общих точек» (joint points). И если общие точки оказались отделены секущей плоскостью от того или иного объекта, это означало, что разделена вся система. Также благодаря таким местам соединения было проще просчитывать объемы и параметры объектов так, чтобы они продолжали соответствовать друг другу.

Рубить и кромсать: как работает разрезание объектов в играх

Однако у этой системы были свои проблемы: во-первых, расставить такие точки по всему кораблю требовало очень много времени, и эта работа выполнялась вручную. Более того, после каждого отделения нужно было восстанавливать точки соединения для новых систем объектов, и это могло перегрузить любую систему, да и файлы игры из-за этого «весили» слишком много.

Чтобы ускорить разработку и оптимизировать процесс сочленения команда разработала «автоматический соединитель» (automatic jointer) — инструмент, который самостоятельно определял текущие и будущие точки соединения и тут же наносил их на поверхности. Это ускорило процесс разработки, однако количество оперируемых данных всё ещё оставалось неоправданно высоким.

Поэтому разработчики решили рассматривать места сочленения объектов не как совокупность точек, а как полигоны. На месте пересечения полигонов двух разных объектов создавался третий полигон, который Харрисон назвал «зоной слияния» или «клейкой лентой» (joint strip).

Рубить и кромсать: как работает разрезание объектов в играх

Получившийся Automatic Jointer V2.0 значительно ускорил процесс соединения частей космического корабля. Также чтобы ускорить процесс сборки корабля из ассетов BBI задействовали Unity Compiler.

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

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

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

Рубить и кромсать: как работает разрезание объектов в играх

Для этого в BBI выстроили иерархическую модель, в которой каждый из объектов был частью более сложного тела, из этих тел формировался модуль, а из модулей — корабль. Каждый объект — это нода, которая соединяется с другими такими же нодами, общая плоскость является при этом соединительной и образующей так называемое «твёрдое тело» (Rigidbody), из которых состоят все модули корабля.

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

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

Рубить и кромсать: как работает разрезание объектов в играх

Также летящие детали могли спровоцировать цепную реакцию, в результате которой объекты в помещении и сам игрок получали бы стихийный урон. Создавая систему стихийного урона, Харрисон и команда отталкивались от системы химии в The Legend of Zelda: Breath of the Wild, где удар молнии мог поджечь траву, а горящая трава, если её не потушить, — устроить лесной пожар. Эта система интуитивно понятна, логична и зрелищна, и создатели Hardspace: Shipbreaker взяли её за основу, когда прорабатывали урон огнем, холодом и электричеством в игре.

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

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

Чтобы избежать перегрузки системы и возможных конфликтов при цепных реакциях, разработчики прибегли к кластерному распределению оперативной памяти (Contiguous Memory Allocation), при котором каждому процессу в игре выделяется своя ячейка в оперативной памяти компьютера. Это решение снизило нагрузку на систему и уменьшило количество багов при цепных реакциях. Также при таком построении цепных реакций разработчики четко видели начало и окончание каждого процесса и то, как они будут работать одновременно, что позволяло им лучше просчитать физику разрушений.

Игрок разрезает топливный элемент и провоцирует взрыв, который вызывает декомпрессию в других отсеках —«Та-дам! Он испарился…»

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

Взрывы тоже относятся к горящим объектам. Взрыв в Hardspace: Shipbreaker — это разрастающаяся совокупность секущих плоскостей со статусом «горящий», распространяющих этот статус на всё «горючие» объекты, с которыми они соприкасаются и разбивающих на мелкие детали все негорючие.

В итоге мы получаем разные подходы к симуляции одного и того же процесса. Каждый из них продиктован тем, какую цель ставили перед собой разработчики: для кого-то это основополагающая часть геймплея, а для кого-то — просто еще одна из selling features. С точки зрения геймдизайна важно только то, насколько каждый из принятых подходов функционален и полезен для итогового продукта.

203203
49 комментариев

Комментарий недоступен

46

Но почему не 
RULES OF NATURE 

30

Rules of Nature в народе больше замемилась. 

4

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

3

Metal Gear Risng шоле перепройти...

8

Всем рекомендую Tiny & Big, проходится за вечер, там еще помимо резака есть ракеты(чтобы толкать объект вперед/назад), и кошка чтобы тащить объект.
А ну еще там можно резать просто гиганские объекты, и соответственно прокладывать себе путь из них.

10