Voltar para o Blog
Quest Log

Luz 2D na Unity: Light 2D, Sombras e Normal Map

Masmorra em pixel art escura iluminada por uma tocha laranja, com sombras longas projetadas pelas paredes

Unity 2D light no URP passo a passo: Global Light 2D escura, tocha com Spot Light 2D, Shadow Caster 2D nas paredes e normal map no sprite para dar relevo.

Ferramenta:Unity

Luz 2D na Unity: Light 2D, Sombras e Normal Map

Para usar Unity 2D light você precisa do URP com o 2D Renderer, uma Global Light 2D para a luz ambiente e luzes locais (Spot, Freeform ou Sprite) para tochas, janelas e magias. Com isso, mais o Shadow Caster 2D nas paredes e um normal map no sprite, uma masmorra em pixel art ganha profundidade sem nenhum modelo 3D.

Aqui você monta a cena clássica: ambiente quase escuro, tocha laranja tremulando, paredes projetando sombra e pedras com relevo quando a luz passa. Tudo no Unity 6.3 LTS com URP.

Luz 2D na Unity: o que precisa

Três coisas, nessa ordem:

  1. URP com 2D Renderer. A iluminação 2D é um recurso do Universal Render Pipeline. Não existe na Built-In Render Pipeline, que está descontinuada desde o Unity 6.5.
  2. Sprites com material lit. O material padrão do 2D Renderer, Sprite-Lit-Default, reage à luz. O Sprite-Unlit-Default ignora a luz e sempre aparece com a cor cheia, o que é útil para UI e efeitos que devem brilhar.
  3. Luzes 2D na cena. Elas são componentes Light2D e só afetam sprites, Tilemaps e outros renderers 2D.

Configurando o 2D Renderer no URP

Se você criou o projeto com o template Universal 2D no Unity Hub, já está tudo pronto: o 2D Renderer está ligado e a cena inicial vem com uma Global Light 2D.

Se o projeto nasceu com o template 3D do URP, faça a troca:

  1. No Project, clique com o botão direito e vá em Create > Rendering > URP Asset (with 2D Renderer). Dê um nome. A Unity cria dois arquivos: o URP Asset e o asset do renderer 2D (com "_Renderer" no fim do nome), já ligados um ao outro.
  2. Em Edit > Project Settings > Graphics, coloque esse novo URP Asset como pipeline padrão. Se o projeto usa níveis de qualidade com assets próprios, troque também em Edit > Project Settings > Quality.
  3. Confira se os sprites estão com o material Sprite-Lit-Default. Sprites criados depois da troca já vêm com ele.

O asset do 2D Renderer é onde ficam os Blend Styles (Multiply, Additive e as versões com máscara) e opções de sorting que aparecem em outros posts desta série.

Global Light 2D e Spot Light 2D

No Unity 6.3, a Light 2D tem quatro tipos, escolhidos no campo Light Type:

  • Global: ilumina todos os objetos 2D por igual, sem queda de intensidade. Só pode haver uma por blend style e Sorting Layer.
  • Spot: emite de um ponto, dentro de um cone. Com ângulo 360 vira a luz redonda de tocha.
  • Freeform: um polígono que você desenha com Edit Shape. Bom para o feixe que entra por uma janela.
  • Sprite: usa a forma de um sprite como luz. Bom para vitrais, raios estilizados e máscaras.

Monte a masmorra:

  1. Selecione a Global Light 2D e baixe Intensity para algo entre 0,1 e 0,2. Puxe a cor para um azul escuro. É a luz ambiente: o jogador ainda enxerga o cenário, mas ele parece noturno.
  2. GameObject > Light > Spot Light 2D. Arraste para cima da tocha.
  3. Em Radius, coloque Inner perto de 0,5 e Outer perto de 4. Inner é a área de intensidade máxima; Outer é onde a luz acaba.
  4. Deixe Inner Spot Angle e Outer Spot Angle em 360 para luz redonda.
  5. Cor laranja, Intensity entre 1 e 1,5. Acima de 1 a luz estoura o sprite nos blend styles Multiply, o que pode ser exatamente o brilho de fogo que você quer.

Agora o tremor da tocha, que vende a cena. Crie o script abaixo.

Arquivo TorchFlicker.cs:

using UnityEngine;
using UnityEngine.Rendering.Universal;

public class TorchFlicker : MonoBehaviour
{
    [SerializeField] private Light2D torchLight;
    [SerializeField] private float baseIntensity = 1.2f;
    [SerializeField] private float intensityVariation = 0.25f;
    [SerializeField] private float baseOuterRadius = 4f;
    [SerializeField] private float radiusVariation = 0.3f;
    [SerializeField] private float flickerSpeed = 3f;

    private float noiseOffset;

    private void Awake()
    {
        if (torchLight == null)
        {
            torchLight = GetComponent<Light2D>();
        }
        noiseOffset = Random.Range(0f, 100f);
    }

    private void Update()
    {
        float t = Time.time * flickerSpeed + noiseOffset;
        float noise = Mathf.PerlinNoise(t, 0f) * 2f - 1f;

        torchLight.intensity = baseIntensity + noise * intensityVariation;
        torchLight.pointLightOuterRadius = baseOuterRadius + noise * radiusVariation;
    }
}

O Mathf.PerlinNoise dá uma variação suave, que lembra chama de verdade. Random.Range a cada frame dá um piscar nervoso, que parece lâmpada com defeito. O noiseOffset aleatório faz cada tocha da fase tremer diferente, mesmo usando o mesmo script. A propriedade pointLightOuterRadius mantém esse nome na API mesmo com o tipo chamado Spot no Inspector.

Sombras com Shadow Caster 2D

Sombra 2D exige duas coisas: a luz precisa ter Shadows ligado, e o objeto precisa de um Shadow Caster 2D.

  1. Na Spot Light 2D da tocha, marque Shadows. Ajuste Strength (0 a 1) e Softness para a borda ficar menos dura.
  2. Na parede, Add Component > Shadow Caster 2D.
  3. Escolha a forma da sombra em Casting Source. As opções no 6.3 são Sprite Skin, Sprite Renderer, Collider 2D, Shape Editor e None.
    • Sprite Renderer usa o contorno do sprite (Custom Outline do Sprite Editor). Ajuste Alpha Cutoff e Trim Edge se a sombra sair maior que o desenho.
    • Collider 2D usa o collider que o objeto já tem. É o mais previsível em parede.
    • Shape Editor deixa você desenhar o polígono da sombra à mão.
  4. Em Casting Option, o padrão Cast Shadow projeta sombra nos outros. Use Cast and Self Shadow se o próprio objeto também deve escurecer.

Com Tilemap, a forma mais limpa é ter um Tilemap só de paredes, com Tilemap Collider 2D (e Composite Collider 2D, se estiver usando), e colocar o Shadow Caster 2D nesse mesmo objeto com Casting Source em Collider 2D. Chão e decoração ficam em Tilemaps separados, sem sombra. Se a sua fase tem centenas de pedaços de parede com formas diferentes, meça no Profiler: forma complexa de sombra pesa, principalmente em mobile.

O que torna sombra 2D bonita não é só a técnica: é a decisão de onde a luz bate e onde fica escuro. O post sobre luz e sombra em pixel art ensina a pensar isso no desenho, e as duas coisas precisam combinar.

Quando a cena tem tocha, sombra, inimigo andando, personagem com animação e câmera seguindo, cada sistema mexe nos outros: a sombra corta o personagem, a luz não pega o Tilemap novo, a ordem de desenho quebra. Organizar isso numa fase de verdade é a parte que quem aprende sozinho mais demora para acertar, e é o que o curso de Unity trabalha em projeto completo.

Curso de Unity
Quer fazer seu primeiro jogo na Unity?

No curso de Unity 6 da CursoGame.Dev você vai do zero ao primeiro jogo, com um desafio prático em cada level e suporte individual no WhatsApp quando travar.

Conhecer o curso de Unity
Suporte no WhatsAppAcesso vitalícioGarantia de 7 dias

Normal map em sprite (Secondary Textures)

Normal map faz a luz 2D "entender" o relevo do desenho: uma pedra fica clara do lado da tocha e escura do outro, e isso muda quando a tocha se mexe.

  1. Pinte ou gere o normal map do sprite (mesmo tamanho e mesmo layout da sprite sheet).
  2. Selecione a textura do normal map e, no Inspector, troque Texture Type para Normal map. Clique em Apply. Esquecer esse passo é a causa número um de "o normal map não faz nada".
  3. Selecione o sprite original, abra o Sprite Editor e, no menu do canto superior esquerdo, troque o módulo para Secondary Textures.
  4. Clique no +, escolha _NormalMap no campo Name e arraste a textura para o campo Texture. Clique em Apply. Cada sprite aceita até 8 texturas secundárias.
  5. Na luz, defina Normal Map Quality: Fast (mais leve, pode ter artefato) ou Accurate (mais fiel, mais caro). Em Disabled, a luz ignora o normal map.
  6. Ajuste Normal Map Distance para controlar o quanto o relevo aparece sem mover a luz.

A Global Light 2D não usa normal map, então o relevo só aparece onde há luz local. Por isso a combinação ambiente escuro mais tocha funciona tão bem com normal maps.

O nome _MaskTex, no mesmo dropdown, serve para máscaras de luz usadas pelos blend styles com máscara. Não precisa dele para começar.

Sorting Layers e Target Sorting Layers

Cada Light 2D tem o campo Target Sorting Layers: a luz só afeta sprites que estão nessas camadas. Isso é recurso, não limitação:

  • A tocha ilumina Cenário e Personagens, mas não a camada UI do mundo (nomes flutuantes, barra de vida acima do inimigo).
  • Uma luz de magia pode afetar só Efeitos.
  • O fundo de parallax pode ter a própria Global Light 2D, mais clara, numa camada separada, para o céu continuar visível numa fase noturna.

Lembre que a Global Light 2D é única por blend style e Sorting Layer. Se você precisa de dois ambientes diferentes, separe por camada.

Erros comuns: tudo preto, luz sem efeito e sombra vazando

Tudo preto depois de adicionar uma luz. Falta Global Light 2D, ou ela está com intensidade 0, ou não inclui a Sorting Layer dos sprites. Abra a Global Light 2D e confira Target Sorting Layers.

Luz sem efeito nenhum. O sprite está com Sprite-Unlit-Default, ou o URP Asset ativo não usa o 2D Renderer. Confira o material do Sprite Renderer e qual pipeline está em Project Settings > Graphics e Quality. Outro motivo: a Sorting Layer do sprite não está na lista da luz.

Normal map sem efeito. Texture Type não está como Normal map, o nome na Secondary Texture não é _NormalMap, ou a luz está com Normal Map Quality em Disabled.

Sombra vazando por baixo da parede. A forma da sombra é maior que o sprite. Use Collider 2D em Casting Source, ou baixe o Trim Edge, ou desenhe com Shape Editor.

Sombra que não aparece no Tilemap. O Shadow Caster 2D está num objeto sem collider, ou o Tilemap mistura chão e parede e o collider ficou estranho. Separe as paredes num Tilemap próprio.

Se você também trabalha com Godot, compare com o post de luz 2D na Godot: os conceitos (luz ambiente, oclusor, normal map) são os mesmos, só muda o nome dos nós.

Próximo passo

Monte uma sala de masmorra com três tochas, cada uma com o TorchFlicker, paredes com Shadow Caster 2D e um normal map em pelo menos um tipo de pedra. Ande com o personagem pela sala e veja se ele fica legível em todos os pontos. Se sumir no escuro, suba a Global Light 2D um pouco antes de adicionar mais tochas.

Quando a iluminação estiver redonda, o próximo passo é escrever materiais próprios. O post sobre Shader Graph na Unity mostra como criar um Sprite Lit Shader Graph e mexer na cor e no brilho que a luz 2D recebe.

Perguntas frequentes

Por que a cena fica toda preta quando adiciono uma luz 2D na Unity?

Assim que existe uma Light 2D na cena, os sprites com material Sprite-Lit-Default passam a depender dela. Se não há uma Global Light 2D com intensidade razoável, ou se a luz não inclui a Sorting Layer do sprite em Target Sorting Layers, tudo fora do alcance da luz fica preto.

Como usar Shadow Caster 2D com Tilemap?

Coloque o Shadow Caster 2D no mesmo objeto do Tilemap que tem o Tilemap Collider 2D e escolha Collider 2D em Casting Source. Separe as paredes num Tilemap só delas, para não gerar sombra do chão. Em mapas grandes, teste o custo no Profiler, porque formas complexas pesam.

Onde coloco o normal map de um sprite na Unity?

No Sprite Editor, troque o módulo para Secondary Textures, clique no + e escolha _NormalMap no nome, apontando para a textura do normal map. A textura precisa estar importada com Texture Type Normal map, e a luz precisa ter Normal Map Quality em Fast ou Accurate.

Qual a diferença entre Spot, Freeform, Sprite e Global Light 2D?

Spot emite de um ponto, num cone que pode ir até 360 graus. Freeform usa um polígono que você desenha. Sprite usa a forma de um sprite como luz. Global ilumina tudo por igual, sem queda, e só pode existir uma por blend style e Sorting Layer.