Чи можна досягти ефекту факела (світліша область навколо джерела світла) у 2D грі?


16

Я думаю про те, щоб написати собі просту 2D гру. Спочатку це не буде блищати ідеальною графікою чи геймплеєм, але я вважаю це своїм першим кроком у розробці комп'ютерних ігор. Отже, уявіть собі таку просту 2-гру-спрайт-гру (наприклад, Heroes IV або Startcraft BroodWar).

Я хочу, щоб геймплей підтримував день / ніч відповідно до змін освітлення, і в той же час буде безумство створювати спрайти для кожного нюансу освітлення. Отже, я вирішив додати напівпрозорий шар поверх інших об’єктів буде достатньо.

Проблема з цим рішенням полягає в тому, що якщо в грі у мене є предмет джерела світла (наприклад, герой, що носить факел, або палаюча будівля), навколо має бути світліша область, правда? Оскільки я наношу свій напівпрозорий шар поверх усього, як би ви запропонували досягти візуального ефекту факелу? Можливо, перемалюйте цей шар, додаючи «прогалини» або кольори різного кольору, виходячи з ефекту освітлення?


2
Маска може стати дорогою
Густаво Масіель

5
"Факел" у назві може бути заплутаним через гру під назвою Torchlight.
Тетрад

4
@Tetrad Повинен бути добре, доки його не мають великої літери. Щодо мене, Torchlight взагалі не прийшов до тями, поки не прочитав ваш коментар.
знаменитийГаркін

Тим не менш, я запропонував редагування, щоб зробити назву більш конкретною.
знаменитийГаркін

Відповіді:


12

Я не знаю, для чого ви програмуєте, але ось як я обробляв це в XNA:

  1. Під час виклику малювання List<Light>об'єкт створюється / очищається.
  2. Під час циклу малювання плитки кожну плитку перевіряють, чи немає у неї пов'язаних вогнів. Якщо це так, Lightоб'єкти додаються до List<Light>.
  3. Плитку малюють самостійно RenderTarget2D.
  4. Після циклу плитки список Lights переглядається і складається самостійно, RenderTarget2Dвикористовуючи текстуру, яку я створив так:
    Легка текстура(Примітка: тут я використовував значення R, G і B, але, ймовірно, ви повинні використовувати альфа-канал у своєму фактична текстура.)
  5. Використовуючи користувальницький шейдер, я повертаю поверхню плитки до екрану і передаю в освітлювальну поверхню як параметр, який отримує вибірку для значення "темряви" на кожному пікселі.


Тепер слід зазначити кілька речей:

Щодо пункту 4:

Насправді у мене є два користувальницькі шейдери, один для малювання вогнів до цілі відображення освітлення (крок 4) та інший для малювання цілі візуалізації плитки на екран за допомогою цілі візуалізації освітлення (крок 5).
Шейдер, що використовується в точці 4, дозволяє мені додати (те, що я називаю) значення "світності". Це значення - це floatкоефіцієнт, що множиться на кожен піксель текстури, перш ніж він буде доданий до цілі візуалізації, щоб я міг зробити світло яскравішим або темнішим.
На цьому етапі я також враховую значення "масштабу" світла, що означає, що я можу мати великі або маленькі вогні, використовуючи лише одну текстуру.

Щодо пункту 5:

Подумайте, що ціль відображення освітлення є як такою, що має значення для кожного пікселя від 0 (чорний) до 1 (білий). Шейдер, по суті, множує це значення на RGB-значення для пікселя в цілі відображення плитки, щоб зробити остаточне намальоване зображення.

У мене також є ще якийсь код, де я передаю (у шейдер) значення, яке використовуватиметься як колір накладення день / ніч. Це також множиться на значення RGB і включається в розрахунки цільового освітлення.


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

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

О, і ось дивіться на це в моєму редакторі карт:введіть тут опис зображення


Створити та очистити список, кожен кадр може бути не надто дорогим?
Густав Масіель

@Gtoknu Не робить помітної різниці в моїй грі. У списку є лише посилання на об'єкти, які вже є в пам'яті, так що це не так, як відтворюється кожне світло, або щось інше, лише один список.
Річард Марскелл - Дракір

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

@Gtoknu Звичайно, ви можете оголосити цей список де завгодно, але справа в тому, що фари асоціюються з плитками. Метод плитки Draw- це те, де ви дізнаєтеся, чи є у плитки світло чи ні. Я не переглядаю всі намальовані плитки Updateметоду, тому я б додав додаткові накладні витрати для цього. Крім того, XNA намагається гарантувати, що Updateвін буде викликаний 60 разів на секунду, щоб він міг пожертвувати Drawвикликами для цього, а це означає, що цей код насправді отримуватиме дзвінки рідше.
Річард Марскелл - Дракір

Все, що було сказано, це суперечка, тому що я врешті-решт перемістив вогні у свої власні списки на основі просторового розподілу і просто намалював усі вогні в розділах, що перетинаються екраном. Я не говорив про це у своєму пості через брак часу, але це згадується у другій публікації блогу, яку я пов’язав.
Річард Марскелл - Дракір

9

Зазвичай, освітлення в 2D іграх відбувається за допомогою нормальної карти для всіх ваших спрайтів, після чого обчислюйте 3D-освітлювальні ефекти на ваших 2D спрайтах. Це вільно відомо як "2.5D". Однак я б не рекомендував робити це у своїй першій грі, оскільки це складно.

Ось дивовижне відео того, хто це зробив у XNA: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

Однак, мабуть, існують способи обдурити і отримати систему псевдосвітлення, яка може працювати з різними припущеннями.


Вже бачили це відео раніше, +1 за згадування такої неймовірної техніки.
Gustavo Maciel

Дякую за пораду та відео посилання. Дійсно, карта здається рішенням. Я сам спробував би використати карту на своєму верхньому шарі, щоб створити "пробіл" або змінити ефект, який він надає на основні об'єкти.
Івайло Славов

5

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

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

введіть тут опис зображення

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

Редагувати

Каталін посилається на іншу статтю, яку він використовував як посилання, але посилання розірвана. Ось оновлене посилання .


Дякую, я думаю, що це не той ефект, на який я переживаю, але все ж дякую, що поділився :)
Івайло Славов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.