Динамическое освещение и тени в Godot 2D

Динамическое освещение и тени могут существенно улучшить визуальное качество и вовлечённость игроков. Они добавляют глубину, атмосферу и ощущение реализма, делая мир игры более захватывающим.
В Godot для этого есть удобные инструменты: CanvasModulate, PointLight2D, LightOccluder2D и несколько сопутствующих приёмов. Ниже — подробно, с примерами кода, рабочими шаблонами и практическими рекомендациями.
Быстрая подготовка сцены в Godot
Прежде чем приступать к освещению, создайте базовую 2D-сцену в Godot и добавьте CharacterBody2D для игрока. Внутри CharacterBody2D добавьте CollisionShape2D с прямоугольной формой и Sprite2D для визуализации персонажа. Платформы можно сделать через StaticBody2D.
Исходный код, использованный в статье, доступен в репозитории на GitHub и распространяется под MIT-лицензией.
Пример простого скрипта движения (GDScript):
extends CharacterBody2D
var speed = 200
func _physics_process(delta):
var velocity = Vector2()
if Input.is_action_pressed('ui_right'):
velocity.x += 1
if Input.is_action_pressed('ui_left'):
velocity.x -= 1
if Input.is_action_pressed('ui_down'):
velocity.y += 1
if Input.is_action_pressed('ui_up'):
velocity.y -= 1
velocity = velocity.normalized() * speed
move_and_collide(velocity * delta)Этот код обеспечивает движение игрока в четырёх направлениях. Для реальной игры рекомендуется дописать контроль границ экрана и обработку столкновений.

Затемнение сцены: CanvasModulate
Чтобы создать эффект локального освещения, затемните всю сцену, а области вокруг источников оставьте светлыми. Для этого удобно использовать CanvasModulate.
extends Node2D
const DARKNESS = 0.7
func _ready():
var canvas_modulate = CanvasModulate.new()
canvas_modulate.color = Color(0, 0, 0, DARKNESS)
add_child(canvas_modulate)Прикрепите этот скрипт к новому Node2D на корне сцены. CanvasModulate наложит полупрозрачный чёрный слой, который затемнит всё, кроме областей, освещённых светильниками.
Пара советов:
- DARKNESS = 0 полностью отключает затемнение, 1 делает сцену полностью чёрной под наложением. Подбирайте значение по настроению сцены.
- Можно анимировать alpha CanvasModulate для плавных смен времени суток.

Тени: LightOccluder2D
Чтобы объекты отбрасывали тени, добавьте LightOccluder2D туда, где объекты должны блокировать свет. Подходы:
- Для платформ и стен используйте простой полигональный occluder, повторяющий силуэт объекта.
- Для сложных форм — упрощённый контур (менее вертексов), чтобы не падала производительность.
Пример: добавьте LightOccluder2D в качестве дочернего узла к StaticBody2D и задайте полигон в свойствах polygons.
Совет: используйте консервативные контуры — чуть меньше вертексов, чем фактическая спрайтовая форма, но достаточно, чтобы тень выглядела правдоподобно.
Точечные источники: PointLight2D
PointLight2D излучает свет во всех направлениях. Его свойства — energy, color, range, texture и т.д.
extends PointLight2D
var light_color = Color(1, 1, 0.8)
func _ready():
energy = 2.5
color = light_colorЧтобы придать источнику форму, используйте свойство Texture в инспекторе: круг, градиент или произвольная маска.
Инструкция по применению текстуры:
- Выберите PointLight2D в дереве сцены.
- В Inspector найдите секцию Texture.
- Загрузите файл текстуры через файловый браузер.
Пара рекомендуемых настроек:
- energy: 0.5–3.0 — регулирует яркость; для ночных сцен обычно 1.0–2.5.
- range (если доступно в версии): контролирует радиус освещения.
- shadow_enabled: включайте только при необходимости — тени дороже в производительности.
Дополнительные фишки и примеры реализации
Ниже — набор практических расширений, которые легко интегрировать.
Анимация свечения (flicker)
Пример простого эффекта мерцания для факела:
extends PointLight2D
var base_energy = 1.8
var flicker_range = 0.4
var flicker_speed = 12.0
func _process(delta):
var t = OS.get_ticks_msec() / 1000.0
energy = base_energy + sin(t * flicker_speed) * flicker_range * randf()Этот код даёт нелинейное мерцание без ключевых анимаций.
Плавное появление и исчезновение света
Используйте Tween или AnimationPlayer для плавных переходов яркости. Пример с Tween:
var tween: Tween
func _ready():
tween = Tween.new()
add_child(tween)
func fade_to(target_energy, time_sec=0.6):
tween.stop_all()
tween.interpolate_property(self, "energy", energy, target_energy, time_sec, Tween.TRANS_SINE, Tween.EASE_IN_OUT)
tween.start()Реализация цикла день/ночь
Подход: хранить глобальное время (0..24), и по нему регулировать CanvasModulate.color и силу/цвет отдельных источников.
Мини-алгоритм:
- Инкрементируйте игровое время в _process(delta).
- Интерполируйте цвет неба и CanvasModulate.alpha между дневным и ночным состояниями.
- Меняйте цвет/energy ночных и дневных источников.
Динамические тени для подвижных объектов
Для движения персонажа с корректными тенями используйте LightOccluder2D, привязанные к телу персонажа. Недостаток: много окклюдеров рядом может стать дорогим. Балансируйте по количеству активных источников и видимости.
Когда это не сработает (контрпримеры)
- Мобильные устройства очень низкого класса часто не вытянут большое количество активных источников и сложных окклюдеров.
- Если сцена полностью статична, динамическое освещение — лишняя нагрузка; лучше запечь (bake) свет.
- Очень мелкие объекты с миллионами вершин в окклюдере создадут просадки FPS.
Альтернативные подходы
- Light baking: для статичных сцен — лучшее решение по производительности.
- Пол- или тайл‑атлас освещения: подготовленные спрайты с подсвеченными областями для фиксированных кусков уровня.
- Normal maps + 2D-lighting shaders: для более сложных эффектов объёмности.
Умственные модели и эвристики
- “Свет как персонаж” — думайте о каждом источнике света как о персонаже: он должен иметь цель и влияние на геймплей.
- Минимум источников с большим радиусом vs. много мелких источников: выбирайте в зависимости от настроения и производительности.
- Упрощай окклюдеры до необходимого уровня — 80% реализма за 20% затрат.
Мини-методология: шаг за шагом
- Создайте базовую сцену и персонажа.
- Подключите CanvasModulate, определите базовую DARKNESS.
- Добавьте PointLight2D(ы) и привяжите текстуры света.
- Добавьте LightOccluder2D к основным препятствиям.
- Проверьте производительность на целевых устройствах.
- Оптимизируйте: упрощайте occluder’ы, уменьшайте количество одновременно активных светов, бейкьте неактивные источники.
Шпаргалка настроек (cheat sheet)
- CanvasModulate.color.alpha: 0.0–1.0 — базовое затемнение.
- PointLight2D.energy: 0.2–3.0 — настройка яркости.
- PointLight2D.color: меняет атмосферу (теплый — жёлтый, холодный — голубой).
- LightOccluder2D.polygons: используйте простые полигоны, меньше вертексов — лучше производительность.
- Shadow enabled: включает тени (дороже), отключайте на слабых устройствах.
Роль‑ориентированные чеклисты
Разработчик:
- Добавить CanvasModulate и проверить DARKNESS.
- Разместить PointLight2D и подключить текстуры.
- Добавить LightOccluder2D для ключевых объектов.
- Замерить FPS и профилировать рендер.
Художник:
- Подготовить текстуры света (круг, градиент, маски).
- Нарисовать упрощённые контуры для окклюдеров.
- Согласовать цветовую палитру света с миром.
Тестировщик (QA):
- Проверить корректность теней при движении персонажа.
- Тестировать на целевых устройствах/разрешениях.
- Проверить переходы света (fading) на баги.
Продюсер:
- Принять визуальный стиль (настройки цвета и DARKNESS).
- Утвердить целевое TDP/производительность для платформ.
Критерии приёмки
- На целевых устройствах средний FPS не ниже установленного порога (по договорённости команды).
- Визуальные артефакты теней отсутствуют в основных зонах игры.
- Плавность переходов света подтверждена на 3 типах устройств.
- Потребление памяти и CPU в пределах допустимых значений при включённых светах.
Риск‑матрица и смягчения
- Производительность падает при множестве источников — смягчение: culling, LOD для света, отключение shadow_enabled.
- Артефакты на разных устройствах — смягчение: унифицировать текстуры света и тестировать на эмуляторах и реальных девайсах.
- Неправильные контуры окклюдеров — смягчение: инструмент для визуализации окклюдеров в редакторе (включать для ревью).
Технические советы по оптимизации
- Culling: отключайте или удаляйте PointLight2D вне видимой области камеры.
- Layering: используйте слои видимости (Light masks) чтобы ограничить, какие объекты освещаются каким светом.
- Batch: минимизируйте смены материалов/шейдеров и количество draw calls, упрощая геометрию окклюдеров.
- Bake: для статичных элементов — бейкнутые карты освещения сохраняют ресурсы для динамичных объектов.
Краткий глоссарий
- CanvasModulate — глобальный цветовой фильтр сцены.
- PointLight2D — точечный источник света в 2D.
- LightOccluder2D — объект, который блокирует свет и формирует тени.
- Baking — предрасчёт освещения, сохранение результата в текстуры.
Примеры тест-кейсов и приёмка
- Включить 3 источника света, пройти по сцене: тени должны корректно обновляться.
- Установить DARKNESS = 0.9: вне зон света сцена должна быть значительно затемнена.
- Отключить shadow_enabled для всех точечных светов: сравнить производительность.
Заключение
Динамическое освещение и тени — мощный инструмент для повышения вовлечённости игроков и усиления визуальной истории. Баланс между эстетикой и производительностью достигается путём упрощения окклюдеров, ограничения активных источников света и использования бейкинга для статичных сцен. Экспериментируйте с цветом, текстурами света и анимацией, но всегда проверяйте результат на целевых платформах.
Краткое резюме ниже.
Краткое резюме:
- Используйте CanvasModulate для базового затемнения.
- PointLight2D + текстуры дают привлекательную форму света.
- LightOccluder2D отвечает за тени — упрощайте его форму.
- Оптимизируйте: culling, bake, ограничьте количество активных источников.
Похожие материалы
Как настроить и использовать Face ID на iPhone и iPad
Echo Buttons: игры, настройка и советы
Команда split в Linux: разделение и объединение файлов
Как попросить повышение: пошаговый план
Предзаказ PS5 Marvel's Spider-Man 2 — где купить