2D світло і тінь

Вступ

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

../../_images/light_shadow_main.png

Усі ресурси цього урока можна знайти в офіційному демо сховищі на GitHub. Пропоную завантажити його перед початком роботи. Крім того, його можна завантажити з Менеджера Проєкта. Запустіть Godot і на верхній панелі виберіть Шаблони та знайдіть "2D Lights and Shadows Demo".

Налаштування

Для цієї демонстрації ми використовуємо чотири текстури: дві для світла, одну для тіні і одну для фону. Я включив тут посилання на всі, якщо ви хочете завантажити їх окремо від демонстрації.

Перша - це фонове зображення (background.png), яке використовується в демонстраційній версії. Вам не обов’язково потрібен фон, але ми використовуємо його для демонстрації.

Друга - це звичайне чорне зображення (caster.png), яке буде використано в якості об'єкта, що відкидає тінь. Для гри зверху вниз це може бути стіна, або будь-який інший предмет, що кидає тінь.

Далі йде саме світло (light.png). Якщо натиснути посилання, ви помітите, наскільки воно велике. Зображення, яке ви використовуєте для світла, повинно охоплювати область, яку ви хочете, щоб ваше світло покривало. Це зображення має розмір 1024x1024 пікселів, тому ви повинні використовувати його для покриття 1024x1024 пікселів у грі.

Нарешті, ми маємо зображення прожектора (spot.png). Демо використовує крапку, щоб показати, де знаходиться світло, і більше світле зображення, щоб показати вплив світла на решту сцени.

Вузли

Демонстрація використовує чотири різні вузли:

CanvasModulate використовується для затемнення сцени.

Sprites використовуються для відображення текстур світлових плям, фону та об'єктів, що відкидають тінь.

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

LightOccluder2Ds використовуються, щоб повідомляти шейдеру, які частини сцени відкидають тінь. Тіні з’являються лише на ділянках, покритих Light2D і їх напрямок залежить від центра Світла.

Освітлення

Світла охоплюють всю протяжність відповідної текстури. Вони використовують суміш добавок, щоб додати колір своєї фактури до сцени.

../../_images/light_shadow_light.png

Світло має чотири Mode (Режими): Add, Sub, Mix, і Mask.

Add додає колір текстури світла до сцени. Він освітлює область під світлом.

Sub віднімає колір світла зі сцени. Він затемнює область під світлом.

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

Mask використовується для маскування ділянок, покритих світлом. Замасковані ділянки приховані або розкриті залежно від кольору світла.

В демонстрації світло має два компоненти: власне Light, яка є зображенням, що показує розташування джерела світла. Нащадок Sprite не потрібен для роботи Light.

../../_images/light_shadow_light_blob.png

Тіні

Тіні створюються перетином Light з LightOccluder2D.

За замовчуванням тіні вимкнені. Щоб увімкнути їх, натисніть на Light і в розділі Тіні поставте галочку Enabled.

У демонстраційній версії ми використовуємо Sprite. Сам по собі LightOccluder2D виглядає темною плямою, і в цій демонстрації Sprite - це просто чорний квадрат.

Крок-за-кроком

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

Спочатку додайте Sprite і встановіть його текстуру як фонове зображення. Для вашої гри це може бути будь-який фон, який ви оберете. Для цього стилю тіней це, швидше за все, текстура підлоги.

../../_images/light_shadow_background.png

Далі створіть три Light2D і встановіть їх текстуру на зображення світла. Ви можете змінити їх колір у верхньому розділі. За замовчуванням тіні вимкнені, а mode встановлений на значенні add. Це означає, що кожне світло додає свій колір усьому, що знаходиться під ним.

../../_images/light_shadow_all_lights_no_blob.png

Далі додайте Sprite кожному вузлу Light в нащадки і встановіть текстуру спрайта на зображення плями світла. Кожен спрайт має залишатися в центрі вузла Light. Картинка плями є зображенням самого світла, тоді як Light показує ефект цього світла на сцену. LightOccluder2D's, тому нам треба, щоб зображення світла було центроване на батьківському вузлі Light.

../../_images/light_shadow_all_lights.png

Примітка

Анімація цієї демонстрації не буде розглядатися тут. Щоб отримати відомості про створення анімації, перегляньте Вступ до функцій анімації.

Зараз сцена повинна виглядати занадто яскраво. Це тому, що всі три джерела світла додають кольору сцені. Ось чому демонстрація використовує CanvasModulate в цій сцені. CanvasModulate перемножує всю область перегляду на певний колір.

Додайте до сцени CanvasModulate і встановіть його колір на rgb(70, 70, 70). Це зробить сцену досить темною, щоб чітко бачити ефекти світла.

../../_images/light_shadow_ambient.png

Тепер додаємо тіні.

Демонстрація використовує вузол Node під назвою "casters" для об'єднання всіх об'єктів, що відкидають тінь. Додайте Node2D до сцени. Згруповані на ньому об'єкти можна буде показати й приховати всі одночасно.

Кожен відкидаючий тінь об'єкт складається з Sprite та його нащадка LightOccluder2D. В демонстрації Sprite має текстуру чорного квадратика і нічого більше. У грі спрайт може бути більшим за маленький квадратик; це може бути зображення будь-якого об'єкта, який кидає тінь: стіни, чарівної скрині, або чогось іншого. Справжня магія відбувається в нащадку LightOccluder2D.

../../_images/light_shadow_sprites.png

LightOccluder2D-ри повідомляють грі, яку форму має оклюдер. Вони містять OccluderPolygon2D,який є контейнером для багатокутника і деякої іншої інформації. Для цієї демонстрації, оскільки наша стіна є квадратом, ми встановлюємо Polygon на квадрат. Інші параметри залишаємо за замовчуванням.

Перша настройка , Closed (Замкнутий), може бути on, або off. Замкнутий багатокутник затуляє світло, що надходить з усіх сторін. Відкритий -- лише з одного напрямку.

Cull Mode (Режим вилучання) дозволяє вибрати які напрямки будуть вилучені. За замовчуванням встановлено Disabled (Відключено), тобто затінювач відкидатиме тінь незалежно від того з якої сторони світло. Clockwise (За годинниковою стрілкою) і Counter-Clockwise (Проти годинникової) використовується для визначення того, яка сторона лінії знаходиться всередині багатокутника. Тінь відкидають лише зовнішні лицьові сторони лінії.

Щоб проілюструвати різницю, ось зображення LightOccluder2D з Closed встановленим на off у відповідному OccluderPolygon2D, щоб можна було побачити лінії багатокутника:

../../_images/light_shadow_cull_disabled.png

Примітка

Cull Mode встановлено на Disabled. Всі три лінії відкидають тіні.

../../_images/light_shadow_cull_clockwise.png

Примітка

Cull Mode встановлено на Clockwise. Тільки верхня і права лінії відкидають тіні.

../../_images/light_shadow_cull_counter_clockwise.png

Примітка

Cull Mode встановлено на Counter-Clockwise. Тільки нижня лінія кидає тінь. Якби Closed був встановлений на on там була би додаткова вертикальна лінія зліва, яка б також відкидала тінь.

Після додавання вузлів LightOccluder2D тіні все одно не з'являться. Вам потрібно повернутися до вузлів Light2D <class_Light2D>`і в розділі Shadow *(Тінь)* встановити ``Enable` на on. Це увімкне тіні з твердими краями, як на зображенні нижче.

../../_images/light_shadow_filter0_pcf0.png

Щоб надати тіням приємних, м'яких країв, ми встановлюємо змінні filter, filter smooth, та gradient length. Godot підтримує Percentage Closer Filtering (PCF), яка бере кілька зразків карти тіней навколо пікселя і розмиває їх, щоб створити плавний тіньовий ефект. Чим вища кількість зразків, тим плавніше буде виглядати тінь, але тим повільніше вона буде працювати. Саме тому Godot надає 3-13 зразків за замовчуванням і дозволяє налаштування. Демонстрація використовує PCF7.

../../_images/light_shadow_normal.png

Примітка

Це тінь, відтворена з налаштуваннями демонстрації. gradient length встановлено на 1.3, filter smooth на 11.1, і filter на PCF7.

../../_images/light_shadow_pcf13.png

Примітка

filter встановлено на PCF13. Запримітьте, що тінь стає ширшою, це тому, що відстань між зразками базується на змінній filter smooth.

Для того щоб скористатися фільтрацією потрібно встановити змінну filter smooth. Вона визначає, наскільки далеко один від одного зразки знаходяться. Якщо ви хочете, щоб м'яка область простягалася досить далеко, ви можете збільшити розмір filter smooth. Однак, з невеликою кількістю зразків (PCF) і великим filter smooth, ви можете побачити лінії, що утворюються між зразками.

../../_images/light_shadow_filter30.png

Примітка

filter smooth встановлено на 30.

Різні світлові вузли Light в демонстрації використовують різні значення для плавного фільтрування. Експериментуйте з ними, щоб знайти ті, які вам подобається.

../../_images/light_shadow_filter0.png

Примітка

filter smooth встановлено на 0.

Нарешті змінна gradient length. Деяким гладким тіням краще не починатися відразу на об'єкті, бо це дає жорсткий край. Змінна довжини градієнта gradient length створює плавний градієнт на початку тіні, щоб зменшити ефект жорсткого краю.

../../_images/light_shadow_grad0.png

Примітка

gradient length встановлено на 0.

../../_images/light_shadow_grad10.png

Примітка

gradient length встановлено на 10.

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