2D система освітлення, що працює на GPU, для Unity3D



Всім привіт. Як відомо, Unity3D відсутня підтримка освітлення для 2D ігор. В Asset Store можна знайти на таку систему, але у неї є один недолік — вона працює на CPU і споживає досить багато ресурсів (64-4096 рейкастов за кадр на кожне джерело світла). Тому я вирішив зробити своє висвітлення, продуктивності якого вистачило б для мобільних пристроїв. Для цього обчислення були перенесені на GPU. Вийшло щось схоже світло Terraria або Starbound.

Посилання на демку. Скріншоти взяті з неї.

Все освітлення вважається на невеликих текстурах, у прикладі використовуються 160х88 пікселів. При підвищенні дозволу можна домогтися дуже дрібної сітки, яку буде складно помітити, правда це вже не для мобільних платформ. З-за того, що обчислення проводяться на таких невеликих текстури можна використовувати досить важкі шейдери.

Для роботи освітлення використовуються 3 камери, кожна з яких відповідає за свою частину системи: джерела світла, перешкоди світла, світло оточення. Потім джерела світла та світло оточення змішуються і накладаються на ігрову камеру.

Тепер докладніше, в порядку відтворення.

Перешкоди світла

Текстура перешкод світла. RGB-канали. Ця і наступні схожі текстури мають масштаб 400%

Ось таку текстуру видає камера. Чорні області повністю прозорі, білі — повністю непрозорі. Також підтримуються кольорові області, наприклад, повністю червоний піксель буде блокувати червону частину світу і пропускати зелену і синю.

Світло оточення

Джерела світла оточення


Джерела світла оточення. Альфа-канал


Ітеративне генерується текстура світла оточення


Так виглядає трохи посилений світло оточення, без звичайних джерел освітлення

Тут все трохи складніше. Такий тип освітлення я реалізував для того, щоб додати слабкий світло на той простір, де немає джерел світла. У прикладі з допомогою нього реалізована неяскрава підсвічування всього вільного простору. RGB канал керування кольором, альфа-канал силою світіння. Головна відмінність цього типу світла від звичайних джерел полягає в тому, що він вважається ітеративне і не має напрямку.

Алгоритм розрахунку для одного пікселя:

  1. Беремо початкове значення пікселя з попередньої ітеративної текстури.
  2. Віднімаємо з пікселя силу перешкоди текстури перешкод.
  3. Додаємо до пікселя силу світіння з текстури джерел світла оточення.
  4. Додаємо до пікселя усереднене значення сусідніх пікселів


Джерела світла

Джерела світла

Звичайні джерела — головна частина системи освітлення. Для їх малювання використовується щось схоже на спрайт. Весь колір виходить з центру, хоча при бажанні точку можна перенести куди завгодно.
Для джерел світла є кілька шейдерів з трасуванням шляху і один без неї. Шейдери з трасуванням розрізняються за кількістю трассируемых точок. Я використовую два таких — один на 9 точок, що працює з Shader Model 2.0, інший на 20 точок для Shader Model 3.0. Шейдер без трасування шляху використовується для систем частинок, так як йому не потрібна якась додаткова інформація для роботи.

Алгоритм трасування шляху:

  1. Беремо яскравість пікселя з текстури.
  2. Знаходимо позицію джерела світла і поточного пікселя в текстурі перешкод.
  3. Зменшуємо поточну яскравість на значення пікселів перешкод, які лежать між двома точками з попереднього кроку.


Змішування та накладання світла

Світло джерел + світло оточення

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


Скріншоти результату, більшу роздільну здатність по кліку.

І наостанок плюси і мінуси
Плюси:
  • Обчислення відбуваються на GPU.
  • Джерелами світла є звичайні спрайт, відповідно можна робити джерело світла будь-якої форми.
  • Кожне джерело світла споживає дуже мало ресурсів.
  • Працює на мобільний пристроях, споживаючи ~8 мс за кадр на Nexus 4.
  • Повністю динамічне освітлення. Перешкоди можна створювати і знищувати на льоту без всякої втрати продуктивності.
  • Підтримка світла оточення.
  • Сама по собі система генерує 6 DrawCalls, всі джерела світла можна вмістити один плюс ще один для світу оточення.
  • Різнокольорові джерела світла і перешкоди.
  • Можливість эмитить джерела світла в системі частинок. Продуктивність майже не відрізняється від звичайних партиклов.
  • Гнучкі налаштування якості.
Мінуси:
  • Система висвітлює по сітці, в слідстві чого дрібні перешкоди можуть ігноруватися. На потужних платформах можна зробити сітку дуже дрібною.
  • Необхідно генерувати меші для світла оточення і перешкод.
  • Розмір камер, в яких створюється освітлення повинен бути більше розміру ігровий камери, щоб коректно відображалися джерела світла за екраном.
  • Обчислювальна складність системи майже не залежить від кількості джерел. Це означає, що якщо вона споживає 8 мс за кадр з 10 джерелами світла, то без джерел вона так і буде споживати близько 8 мс.


P. S. При наявності інтересу спільноти допрацюю і викладу в Asset Store.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.