20К картоплин у Starfield. Як працюють зіткнення в іграх
Всім привіт, мене звуть Микита Лужанський і я Unreal Engine розробник у Pingle Studio. На початку вересня мережу сколихнуло відео, у якому з шлюзу космічного корабля вивалювалось, як стверджував користувач, 20 000 картоплин. Хоч це і виглядає сумнівно, проте є гарним приводом поговорити про те, як працюють зіткнення в іграх.
Комп’ютерні ігри використовують фізичні закони та математичний апарат, який дала нам сучасна наука, для досягнення ефекту реалізму. По суті, комп’ютерна гра — це звичайна комп’ютерна програма, що відкликається на дії користувача. Гравець надає якісь дані (натискання клавіш клавіатури, рух миші), а на виході отримує результат: картинку, що реалістично виглядає, звук, який не відрізняється від природного і, найголовніше, задоволення від гри та відчуття реальності. Завдання програміста — досягти найкращої якості всіх цих і багатьох не проговорених параметрів для користувача.
Тут є серйозна проблема. Комп’ютери користувачів обмежені за потужністю обчислень і сильно різняться за своїми характеристиками. Ми знаємо, що ця сама потужність одного обчислювального центру компанії Google або CERN незмірно більше ніж одинокий комп’ютер в кімнаті гравця (навіть з урахуванням останніх досягнень компаній Intel і NVIDIA, що стосуються зменшення розмірів напівпровідникових елементів в центральних процесорах і відеокартах).
Обмеження потужності ПК призводить до появи верхньої межі кількості операцій, що виконуються за секунду. Чим вища ця межа, тим більше обчислень може зробити комп’ютер, і тим якісніший результат отримується. Тут ми говоримо про відтворення (рендер) картинки на екрані монітора або прорахунок зіткнень об’єктів. Всіми цими та іншими завданнями займаються окремі підпрограми ігрового рушія.
Кожен розробник прагне, щоб гра йшла настільки плавно, наскільки це можливо. Зазвичай оперують поняттям «кадри в секунду» (FPS). Коли кажуть, що в грі 60 FPS, це означає, що рушій повинен обробити вхідні дані від гравця, застосувати їх до ігрового світу, розрахувати взаємодію об’єктів і систем у грі та відрендерити картинку на екрані — все це 60 разів на секунду.
Коли ми говоримо про фізичну взаємодію об’єктів в ігровому світі, мусимо пам’ятати, що чим більше об’єктів задіяно, тим більше перевірок рушій має зробити, щоб отримати результат взаємодії.
Але це палиця на два кінці. З одного боку, хочеться отримати максимально реалістичний результат, що вимагатиме великої кількості обчислень. З іншого боку, є обмеження частоти кадрів, щоб не гальмувати гру, адже гравці цього не люблять. Думаю, всі бачили ігри, в яких раптово з’являється купа об’єктів, які починають стикатися. Гра, в кращому випадку, гальмує (відбувається просідання FPS), а в гіршому — вилітає. На відео 1 хороший приклад того, про що йде мова:
Відео 1 — Приклад падіння FPS через велику кількість об’єктів, для яких потрібно розраховувати зіткнення
Тепер поговоримо про завдання зіткнення двох тіл, яке має бути вирішене комп’ютером для отримання реалістичного результату. Уявімо два абсолютно твердих тіла (об’єкти), один з яких нерухомий, а другий рухається по прямій до першого. У об’єкта, що рухається, є ненульові маса і імпульс; у стаціонарного об’єкта імпульс дорівнює нулю, але маса ненульова (Малюнок 1).
Мал. 1 — Два абсолютно тверді об’єкти до зіткнення. Лівий стаціонарний, правий рухається у бік лівого.
Що відбувається, коли об’єкт, що рухається, стикається з нерухомим. Починають працювати одразу кілька законів (вони працювали і раніше, але з метою опису ми це опустимо): закон збереження енергії і закон збереження імпульсу.
Тепер по порядку.
Перший закон дає чіткі правила взаємодії двох об’єктів. Кожне тіло має певну величину, яку не можна втратити або знищити, а можна тільки передати або трансформувати. Цю величину називають енергією. І нерухомий, і рухомий об’єкти мають цю енергію, вона у них різна. Об’єкт, що рухається, має більшу енергію, тому що, щоб привести тіло в стан руху, потрібно передати йому енергію для цього. Оскільки до взаємодії об’єктів і після взаємодії (зіткнення) енергія не може зникнути, вона повинна передатися від одного об’єкта до іншого, або бути перетворена з однієї форми на іншу. Наприклад, під час деформації енергія може перейти в тепло (не наш випадок, тому що ми домовилися, що тіла абсолютно тверді, тобто не деформуються). На малюнку 2 показано ситуацію після зіткнення.
Мал. 2 — Ситуація після зіткнення двох об’єктів. Порівняйте з Мал. 1, де лівий об’єкт почав рухатися, а правий відскочив у протилежний бік від початкового напрямку.
Другий закон говорить, що сумарний імпульс системи — до зіткнення і після — також не може бути змінений. М’яч, кинутий у стіну з нескінченною масою, відскочить від неї з тим самим імпульсом, що й до зіткнення. Зміниться напрям вектору швидкості м’ячика.
На малюнку 3 зображені підсумкові правила для правильного розв’язання задачі.
Мал. 3 — Закон збереження енергії та імпульсу для завдання зіткнення двох частинок. У лівій частині сумарна енергія та сумарний імпульс системи до зіткнення, у правій частині — після зіткнення
Для двох об’єктів потрібно вирішити цю задачу — з усіма обмеженнями та із застосуванням законів. На папері задача вирішується просто, подібні ставлять у старших класах середньоосвітньої школи. Але комп’ютер оперує проміжками часу — тіками процесора. Через це потрібно застосовувати певні алгоритми для розрахунку переміщення об’єкта між тіками.
У кожен тік об’єкт зсувається на невелику відстань, в залежності від його прискорення та швидкості, відбувається пошук об’єктів, з якими об’єкт міг перетнутися. Якщо вони знайдені, застосовуються алгоритми для виштовхування одного об’єкта з іншого. Ось тут і уся проблема. Для тисячів об’єктів за один тік потрібно розрахувати положення кожного, для кожної пари об’єктів перевірити, чи не перетинаються вони, і, якщо перетинаються, виштовхнути один з іншого.
Однак, якщо один об’єкт був виштовхнутий з іншого, то немає жодної гарантії, що при виштовхуванні він не потрапив в інший об’єкт, тому потрібно перевіряти перетин між об’єктами по кілька разів. Через це й виходить, що для досягнення реалістичних зіткнення сотень і тисяч об’єктів потрібне написання такого коду, який би працював досить швидко і видавав реалістичну картину за час одного кадру. Такі алгоритми можуть застосовувати певні оптимізації в розрахунках, вони будуть задовольняти вимоги законів збереження з такою точністю, яка буде задовільною для отримання бажаної картинки.
Ми поговорили про зіткнення в іграх, які працюють в реальному часі і де потрібен миттєвий розрахунок параметрів. Однак це не завжди працює саме так. Наведу приклад з реальної фізичної задачі, де точність розрахунку була набагато важливіша за швидкість його отримання. Ці розрахунки проводилися із залученням суперкомп’ютерних обчислювальних потужностей. Опромінення високошвидкісними нейтронами приповерхневого шару сталі. Це те, що відбувається в атомних реакторах під час їхньої роботи.
Відео 2 — Опромінення високоенергетичними частинками приповерхневого шару сталі
Я не сильно вдаватимуся в пояснення того, що відбувається, проте спробую пояснити, чому точність важливіша за швидкість. Під час роботи реактора внутрішні стінки трубок, в яких містяться таблетки з ураном, постійно піддаються впливу високошвидкісних частинок (частинок з високою енергією). При попаданні по матеріалу трубки (у цьому випадку певної марки сталі), відбувається каскадоподібне утворення дефектів.
Мал. 4 — Каскади в приповерхневому шарі сталі через попадання однієї високоенергетичної частинки
Дефекти можуть призводити до утворення тріщин і пор у матеріалі, а також до потрапляння радіоактивних елементів з контрольованого середовища в не призначене для цього середовище у реакторі. Вся довжина гіфки — це кілька сотень пікосекунд, для розуміння слід уточнити, що відношення пікосекунди до секунди — це як відношення секунди до ± 30000 років. Тому вчені фізики повинні розробляти такі матеріали, які протягом багатьох місяців і років роботи реактора витримували б вплив таких частинок. Саме тому в таких дослідженнях точність набагато важливіша за швидкість.
На закінчення хочу сказати, що розробка комп’ютерних ігор схожа на вирішення реальних фізичних завдань, що їх постійно вирішують в інститутах та дослідницьких центрах. Всім, хто цікавиться роботою фізичної системи, рекомендую прочитати чудову книгу Game Engine Architecture від Jason Gregory.
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів