Iluminação 2D no Godot 4: Luz, Sombra e Clima na Cena

Iluminação 2D no Godot 4 com CanvasModulate, PointLight2D, DirectionalLight2D, sombras com LightOccluder2D e como animar a luz por código para clima real.
Iluminação 2D no Godot 4: Luz, Sombra e Clima na Cena
Iluminação 2D no Godot 4 é o que separa uma cena que parece um mapa de sprites de uma cena que parece um lugar. O mesmo cenário desenhado por você muda completamente quando você apaga a luz ambiente, acende uma tocha numa parede e deixa a sombra dela cair no chão. O jogador sente frio, sente que é noite, sente que tem algo escondido no escuro. É justamente esse controle da penumbra que ajuda a criar um jogo de terror com atmosfera, onde o que não se vê assusta mais do que o que aparece. E o melhor: o Godot 4 já traz todas as peças para isso sem você precisar de plugin externo nem de motor pago. Neste tutorial você vai montar uma cena 2D iluminada do zero, entender cada nó envolvido e ainda dar vida à luz animando energia e cor por código.
Faço software há mais de 20 anos e a lição que carrego para gamedev é simples: efeito que impressiona quase sempre é a soma de coisas pequenas bem encaixadas. Luz 2D é exatamente isso. Você empilha uns poucos nós, ajusta umas propriedades e o clima aparece.
Como a iluminação 2D no Godot 4 funciona por baixo
Antes de sair clicando, vale entender o modelo mental. No 2D do Godot, por padrão tudo é desenhado com sua cor cheia, como se houvesse luz infinita em todo lugar. Não existe noite, não existe sombra, existe só o pixel do jeito que você pintou. Para ter iluminação de verdade, você precisa primeiro escurecer o mundo e depois adicionar fontes de luz que devolvem a claridade onde você quer.
Esse escurecimento global é trabalho do nó CanvasModulate. Ele aplica uma cor que multiplica todo o conteúdo do canvas. Se a cor é branca, nada muda. Se a cor é um azul bem escuro, a cena inteira fica com cara de noite. É a sua luz ambiente.
Por cima do ambiente entram os nós de luz. Cada luz tem uma textura que define o formato e o alcance da claridade, e essa luz é somada ao que o CanvasModulate deixou. O resultado final de cada pixel é a luz ambiente mais a contribuição de cada fonte que alcança aquele ponto. Entender isso resolve a dúvida número um de quem começa: a luz não pinta por cima, ela soma. Por isso uma cena bem iluminada começa sempre por escurecer o ambiente, e não por adicionar luz num mundo que já está claro.
Montando a luz ambiente com CanvasModulate
Comece pela base. Adicione um CanvasModulate à sua cena e escolha uma cor escura. Um tom de azul ou roxo bem fechado funciona bem para noite, porque sombra real raramente é preto puro, ela puxa para a cor do céu. Algo como um azul marinho profundo dá um ar de luar sem deixar a cena ilegível.
Se você quiser controlar isso por código, por exemplo para transicionar do dia para a noite, basta guardar a referência e mudar a cor:
@onready var ambiente: CanvasModulate = $CanvasModulate
func definir_noite() -> void:
ambiente.color = Color(0.12, 0.14, 0.28)
func definir_dia() -> void:
ambiente.color = Color(1.0, 1.0, 1.0)
Com a cor escura aplicada, sua cena fica penumbra. Esse é o estado certo: agora o jogador só vai enxergar o que você decidir iluminar. É aqui que a direção de arte começa, porque o que fica no escuro é tão importante quanto o que fica na luz.
PointLight2D: a luz que nasce de um ponto
A fonte de luz mais usada em 2D é o PointLight2D. Ele representa uma luz que parte de uma posição e se espalha em volta, perfeita para tochas, lampiões, velas, magias e qualquer brilho localizado.
O PointLight2D precisa de uma textura, que você define na propriedade texture. Essa textura é o desenho da luz: um borrão circular branco com bordas suaves é o clássico, porque dá aquele degradê natural do centro forte para a borda fraca. O Godot interpreta o brilho da textura como intensidade, então as áreas claras da textura iluminam mais e as escuras iluminam menos. Trocar a textura troca completamente o formato da luz, e você pode usar isso para criar feixes, cones ou padrões.
As propriedades que você mais vai mexer são a energy, que controla a intensidade, e a color, que tinge a luz. Uma tocha pede uma color puxada para laranja e uma energy na casa de um. Uma luz mágica pede um ciano ou roxo. No editor você arrasta os controles, mas a graça está em controlar isso por código:
@onready var tocha: PointLight2D = $PointLight2D
func _ready() -> void:
tocha.color = Color(1.0, 0.6, 0.25)
tocha.energy = 1.2
Posicione esse nó como filho da parede onde a tocha está desenhada e ajuste o alcance pela escala da textura ou pelas propriedades de altura e raio da luz. O alcance é o quanto a claridade se estende antes de sumir, e calibrar isso é metade do trabalho de fazer a cena parecer crível.
Animando a luz por código: tocha tremeluzente e pulso
Luz parada parece falsa. Fogo treme, vela balança, runa mágica respira. O jeito de dar vida é animar a energy e a color a cada quadro, dentro do _process. O exemplo mais direto usa um seno para oscilar suavemente a intensidade:
@onready var luz: PointLight2D = $PointLight2D
func _process(delta: float) -> void:
luz.energy = 1.0 + sin(Time.get_ticks_msec() * 0.01) * 0.1
Esse código faz a energy oscilar de forma regular em torno de um valor base. É um pulso limpo e previsível, ótimo para luzes mágicas, cristais e portais, onde você quer uma respiração calma e hipnótica.
Para uma tocha de verdade, o pulso regular não convence, porque chama é caótica. O truque é somar duas oscilações de frequências diferentes para quebrar a regularidade, ou usar ruído. Veja a versão com duas senoides combinadas, que já dá um tremor bem mais orgânico:
@onready var tocha: PointLight2D = $PointLight2D
var _base: float = 1.2
func _process(delta: float) -> void:
var t: float = Time.get_ticks_msec() * 0.001
var tremor: float = sin(t * 11.0) * 0.06 + sin(t * 27.0) * 0.04
tocha.energy = _base + tremor
Como as duas frequências não batem certinho, o padrão demora muito para se repetir e o olho não percebe o ciclo. O resultado é uma chama que treme de leve, do jeito que tocha treme. Se você quiser ir além, dá para variar também a color no mesmo embalo, puxando o laranja para um amarelo mais quente nos picos de intensidade, o que reforça a sensação de fogo vivo.
Um detalhe de disciplina: como esse código roda todo quadro, mantenha a conta enxuta. Animar energia e cor de algumas luzes é barato, mas evite criar nós ou alocar coisas dentro do _process. Calcule e atribua, só isso.
DirectionalLight2D: o sol e a lua da sua cena
Nem toda luz parte de um ponto perto do jogador. O sol está longe e ilumina tudo do mesmo ângulo. Para isso existe o DirectionalLight2D, que joga uma luz uniforme em toda a cena, sempre na mesma direção, como se viesse do infinito.
Esse nó é perfeito para simular luz do dia, luar ou uma claraboia distante. Você ajusta a rotação dele para definir de onde a luz vem e isso muda para que lado as sombras caem. Assim como o PointLight2D, ele tem energy e color, então um DirectionalLight2D com cor levemente azulada e energia baixa faz um luar convincente, enquanto um amarelo claro com energia alta vira um meio-dia.
Na prática, muitas cenas combinam os dois tipos. Um DirectionalLight2D fraco dá a claridade geral do ambiente noturno, e os PointLight2D espalhados pelas tochas criam os pontos quentes onde o jogador realmente enxerga. Essa mistura de luz global com luzes locais é o que dá profundidade a um mapa 2D. Quem já pensa em fazer o céu mudar ao longo da partida vai querer ligar tudo isso a um ciclo de dia e noite controlado por código, onde a cor do ambiente e a energia do sol mudam com a hora do jogo.
Sombras com LightOccluder2D
Luz sem sombra parece um adesivo. A sombra é o que prova que existe um objeto sólido no caminho da claridade. No Godot 4, sombra 2D nasce do nó LightOccluder2D.
O LightOccluder2D carrega um recurso OccluderPolygon2D, que é simplesmente o contorno do objeto que bloqueia a luz. Você desenha esse polígono em volta da forma que deve fazer sombra, como uma caixa, uma coluna ou uma parede. Quando uma luz com sombras ativadas incide sobre esse occluder, ela é bloqueada e projeta uma sombra na direção oposta à fonte.
O passo que muita gente esquece é ativar a sombra na luz. Adicionar o LightOccluder2D sozinho não faz nada visível: você também precisa marcar a opção de sombras habilitadas no PointLight2D ou no DirectionalLight2D que deve gerar a sombra. São duas pontas que se encontram: o occluder diz o que bloqueia, e a luz diz que quer projetar sombra. Com as duas ligadas, mover a luz move a sombra, e é aí que a cena ganha vida, porque uma tocha balançando faz a sombra da coluna dançar na parede.
Vale lembrar que cada occluder e cada luz com sombra têm um custo. Para uma cena com dezenas de objetos, escolha quais realmente precisam projetar sombra. Nem toda pedrinha precisa de occluder. Reserve as sombras para o que conta a história da luz: colunas, personagens, objetos grandes.
Normal map: dando relevo ao sprite plano
Aqui está o detalhe que transforma arte boa em arte que parece esculpida. Um sprite comum é plano: a luz bate nele igual em todo lugar, então ele acende inteiro de uma vez, sem volume. O normal map muda isso.
O normal map é uma segunda textura, do mesmo tamanho do sprite, onde cada pixel guarda a direção para a qual aquela parte do desenho está virada. Onde o desenho deveria ser uma saliência, o normal map aponta para fora; onde deveria ser um sulco, aponta para dentro. O Sprite2D tem um espaço próprio para você atribuir esse mapa de normais junto da textura principal.
Com o normal map no lugar, a luz 2D passa a tratar o sprite como se ele tivesse relevo. Quando o PointLight2D se move, o brilho escorrega pela superfície: as partes que apontam para a luz acendem, as que apontam para longe escurecem. Uma parede de pedra plana ganha rachaduras que parecem fundas, uma moeda ganha borda metálica, um personagem ganha volume no rosto. E tudo isso reage em tempo real à luz que você animou nos passos anteriores, então a chama tremeluzente faz o relevo do sprite tremer junto.
Gerar normal map para pixel art é um assunto à parte, com ferramentas dedicadas, mas o importante para este tutorial é a ideia: a luz só sabe que seu sprite tem relevo se você der a ela o normal map. Sem ele, a iluminação continua linda, só que chapada.
Juntando tudo numa cena que respira
Com as peças na mão, a montagem de uma cena noturna fica clara. Você coloca um CanvasModulate azul escuro para virar a noite. Joga um DirectionalLight2D fraco e azulado para o luar geral. Espalha PointLight2D laranja nas tochas e anima a energy de cada uma com a combinação de senos para o tremor. Adiciona LightOccluder2D nas colunas e paredes principais e liga as sombras nas luzes. Por fim, dá normal map aos sprites de pedra para o relevo aparecer quando a luz da tocha passa.
O resultado é uma cena onde nada está parado: a sombra da coluna oscila com a chama, o relevo da parede pulsa, o canto escuro guarda mistério. E quase tudo isso é um punhado de nós mais umas poucas linhas de GDScript tipado rodando no _process.
A iluminação 2D no Godot 4 recompensa quem experimenta. Mexa na cor do CanvasModulate, troque a textura da luz, mude as frequências do tremor. Cada ajuste muda o clima inteiro. Quando você quiser ir além do que os nós entregam de fábrica, o caminho natural é mergulhar em shaders no Godot para iniciantes, porque é com shader que você cria efeitos de luz que nenhum nó faz sozinho, como névoa volumétrica ou distorção de calor. E se o seu projeto for migrar para três dimensões, os mesmos conceitos de luz, sombra e ambiente reaparecem, com outros nós, na iluminação 3D no Godot.
O próximo passo é prático: abra o Godot, monte a cena noturna deste tutorial e anime sua primeira tocha. Depois ligue essa luz a um ciclo de dia e noite e comece a brincar com shaders. É assim, empilhando peça por peça, que a sua cena 2D para de parecer um mapa de sprites e passa a parecer um mundo. E se você quer trilhar esse caminho com ordem e projeto guiado, é exatamente isso que a gente aprofunda no curso da CursoGame.Dev.
Perguntas frequentes
Como funciona a luz 2D no Godot 4?
A luz 2D no Godot 4 usa um CanvasModulate como luz ambiente global e nós de luz como PointLight2D e DirectionalLight2D que somam claridade por cima. Cada luz tem uma textura que define o formato e o alcance da iluminação. O resultado é a soma da luz ambiente com cada fonte de luz que atinge o sprite.
Para que serve o CanvasModulate?
O CanvasModulate define a cor base que multiplica tudo na cena, funcionando como a luz ambiente do mundo 2D. Se você escurece o CanvasModulate, a cena inteira fica mais escura e só as luzes que você adicionar passam a iluminar de fato. É a base de qualquer cena noturna ou de caverna.
Como faço uma tocha tremeluzente no Godot 4?
Você anima a propriedade energy de um PointLight2D por código dentro de _process, oscilando o valor com uma função seno ou com ruído. Variar levemente a energia e a cor a cada quadro dá a sensação de chama viva. Um pulso lento e regular serve para luzes mágicas, e um tremor irregular serve para fogo.
Como criar sombras na iluminação 2D?
Você adiciona um LightOccluder2D com um OccluderPolygon2D que descreve o contorno do objeto que bloqueia a luz. Depois ativa as sombras na própria luz, marcando a opção de sombra no PointLight2D ou DirectionalLight2D. A luz então é bloqueada pelo polígono e projeta a sombra na direção oposta à fonte.
O que é normal map em sprite 2D?
O normal map é uma textura que informa para qual direção cada pixel do sprite está virado, dando a ele relevo falso. Quando a luz 2D incide sobre um sprite com normal map, partes do desenho parecem altas e outras baixas, com brilho e sombra que mudam conforme a luz se move. É o que faz arte plana ganhar volume sem virar 3D.
PointLight2D ou DirectionalLight2D, qual usar?
Use PointLight2D para luzes que partem de um ponto, como tochas, lampiões e magias, porque a claridade nasce em um lugar e se espalha em volta. Use DirectionalLight2D para simular uma fonte distante e uniforme, como o sol ou a lua, que ilumina a cena inteira sempre na mesma direção. Muitas cenas usam as duas juntas.


