Ілюзія простору: як новий Spiderman рендерить приміщення без геометрії


У нещодавно випущеної грі Marvel’s Spider-Man у багатьох будівлях за вікнами є інтер’єри. Вони виглядають чудово, але схоже, що їх реалізували за допомогою хитрого рендеринга — геометрії інтер’єрів насправді не існує і вона згенерована шейдером. Я не бачив ніяких офіційних заяв Insomniac про те, як вони це зробили, але виходячи з того, як виглядає ефект, тут з великою ймовірністю реалізована техніка interior mapping, яку я придумав у 2007 році у процесі роботи над дисертацією. Раніше я не писав про неї в блозі, тому зараз підходящий момент для пояснення цікавого невеликого шейдера, який я придумав.

Давайте почнемо з перегляду геймплея Marvel’s Spider-Man. Гра виглядає просто приголомшливо. Сайт Kotaku записав окремий ролик, присвячений вікон:

https://www.youtube.com/embed/YQVHtlVEirs
Як можна помітити приблизно на 40 секунді відео, насправді кімнати не є частиною геометрії: там де очевидно має бути вікно, двері. Крім того, дивлячись в одну кімнату з різних кутів будівлі, ми бачимо різний інтер’єр. У деяких випадках за рогом будівлі навіть знаходиться стіна. Все це дає нам зрозуміти, що кімнати імітуються. Тим не менш, з точки зору перспективи вони відображаються правильно і володіють реальною глибиною. Думаю, недоліки таких кімнат при грі не дуже важливі, тому що гравці зазвичай не вивчають кімнати настільки пильно: інтер’єри — це просто фон, а не предмет уважного дослідження. Я вважаю, що такий спосіб створення кімнат додає місту глибини і життя, не витрачаючи при цьому занадто багато ресурсів.


Для економії ресурсів будівлі в іграх часто не мають інтер’єрів, як це можна побачити на скріншоті з GTA V

Насамперед хочу пояснити, що мій пост не є скаргою: я в захваті від того, що мою техніку використовували у такій масштабній грі і ні в якому разі не звинувачую Insomniac у крадіжці. Як я говорив у першій публікації про interior mapping, для мене буде честю, якщо хтось використовує цю техніку. Якщо Insomniac дійсно скористалася в своїй техніці моєю ідеєю, то я вважаю, що це чудово. Якщо не скористалася, то, схоже, вона придумала щось до дивацтва схоже. Тоді мені було б цікаво, як це було зроблено.

Читайте також  Як використовувати діаграми Вороного для управління штучним інтелектом

Так як же працює interior mapping? Ідея полягає в тому, що сама будівля не містить ніякої додаткової геометрії. Інтер’єри існують тільки в шейдере. Цей шейдер виконує raycasting зі стінами, стелею і підлогою, щоб вирахувати, що гравець повинен бачити в інтер’єрі.


Зліва направо: тільки вікна з відбитками, вікна з Interior Mapping, каркасна модель — Interior Mapping не додає ніяких полігонів.

Використовується для raycast промінь — це просто промінь з камери до пікселя. Піксель, який ми рендерим, знаходиться на зовнішній частині будівлі, тому ми використовуємо тільки частина променя за пікселем, тому що це саме та частина, яка насправді знаходиться всередині будівлі.

Raycasting (випущення променів) може здатися складною і витратною операцією, але в цьому конкретному випадку вона насправді дуже проста і швидка. Хитрість у тому, що можна додати просте обмеження: при interior mapping стелі і підлоги перебувають на незмінній відстані. Знаючи це, ми можемо легко обчислити, в якій кімнаті знаходимося, і де в цій кімнаті розташовані підлога і стеля. Самі по собі стелі і підлоги є нескінченними геометричними площинами. Обчислення перетину між нескінченною площиною і променем займає всього кілька кроків і витрачає мало ресурсів.


У кімнати є 6 площин: стеля, підлога і 4 стіни. Однак нам потрібно враховувати тільки три з них, тому що ми знаємо, в якому напрямку дивимося. Наприклад, якщо ми дивимося вгору, то нам не потрібно перевіряти підлога внизу, тому що ми будемо бачити стелю нагорі. Аналогічним чином замість 4 стін нам потрібно враховувати тільки дві в тому напрямку, в якому ми дивимося.

Щоб визначити, що ж ми бачимо, потрібно обчислити перетин променя з кожної з цих трьох площин. Найближчим до камери перетин з променем повідомляє нам, яку з площин ми бачимо в цьому пікселі. Потім ми використовуємо точку перетину як координату текстури, щоб знайти колір пікселя. Наприклад, якщо промінь перетинається в позиції (x,y,z) з стелею, то ми використовуємо в якості координат текстур (x,y) і ігноруємо z.

Читайте також  Стань професіоналом. Корисні звички UX-дизайнерів

Тут я додав гарну оптимізацію: частина обчислень перетинів для кожної з трьох площин можна виконувати одночасно. Використовувані шейдери працювали з float4 з такою ж швидкістю, як і з float, тому завдяки розумній упаковці змінних можна було виконувати перетину всіх трьох променів з площинами одночасно. Це заощадило мені трохи ресурсів і допомогло досягти високої частоти кадрів при interior mapping навіть в 2007 році. Мені говорили, що сучасні відеокарти з float працюють швидше, ніж з float4; отже, на нинішньому залозі ця оптимізація більше не працює.


Interior Mapping без текстур вікон показує, що кімнати рендеряться з правильною перспективою і з текстурами, хоча додаткова геометрія і не потрібно.

Детальніше про роботу interior mapping можна дізнатися в моїй статті. Ця стаття була опублікована на Computer Graphics International Conference 2008. Наявність цієї рецензованого публікації — це моя перша (і єдина) заявка на горде звання вченого. У цій статті також описуються додаткові експерименти по додаванню деталей, наприклад, зміна відстані між стінами для кімнат неоднакового розміру і випадковий вибір текстур з текстурного атласу для більшої варіативності кімнат. Також у ній докладно описуються дві варіації, показані на зображеннях нижче.


Освітлення в кімнатах можна динамічно включати і відключати для імітації зміни дня і ночі. Це виконується за допомогою текстури шуму, з якої ми виконуємо читання, використовуючи в якості координат текстури індекс кімнати.

Так як ми лише зробімо місце для радісного промені у площині, всі кімнати є простими квадратами з текстурами. Всі меблі в кімнаті буде перебувати на текстурі, а значить залишатися плоскою. У Spiderman це помітно у випадку наближення камери: столи в кімнатах насправді є плоскими текстурами на стінах. Як видно на наведеному нижче зображенні, можна доповнити нашу техніку з допомогою однієї або декількох додаткових шарів текстур на кімнату, але це пов’язано з додатковими витратами продуктивності.

Читайте також  10 корисних порад щодо реалізації Pixel Perfect дизайну під Front-end розробці (на прикладі роботи з редактором Sketch)


Виконуючи трасування променів (raytracing) ще одній площині, паралельній до зовнішньої поверхні будівлі, можна додати в кімнату меблі і людей. Тим не менш, вони все одно залишаться плоскими.

Після публікації цього поста один з програмістів Simcity (2013) розповів мені, що техніка interior mapping використовувалася і в цій грі. У ній вона виглядає дуже здорово, і розробники записали про це відмінне відео. Вони удосконалили мою вихідну ідею, зберігши всі текстури в одну текстуру і додавши кімнати різної глибини. Частина, присвячена interior mapping, починається з моменту 1:00:

Якщо ви працюєте в Unreal Engine 4, то можете знайти interior mapping як стандартну функцію рушія у вигляді функції InteriorCubeMap.

Через стільки років дуже здорово нарешті побачити, що техніку interior mapping використовують при виробництві масштабної відеоігри! Якщо вам знайомі ігри, в яких застосовується щось подібне, то напишіть про це.

Степан Лютий

Обожнюю технології в сучасному світі. Хоча частенько і замислююся над тим, як далеко вони нас заведуть. Не те, щоб я прям і знаюся на ядрах, пікселях, коллайдерах і інших парсеках. Просто приходжу в захват від того, що може в творчому пориві вигадати людський розум.

Вам також сподобається...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *