Posso obter um efeito de lanterna (área mais clara ao redor de uma fonte de luz) em um jogo 2D?

16

Estou pensando em me escrever um jogo 2D simples. Não brilha com gráficos ou jogabilidade perfeitos no começo, mas eu consideraria o meu primeiro passo no desenvolvimento de jogos para PC. Então, imagine um jogo 2D simples baseado em sprite (como Heroes IV ou Startcraft BroodWar).

Quero que a jogabilidade suporte dia / noite com as mudanças de iluminação correspondentes e, ao mesmo tempo, será loucura ter que criar sprites para todas as nuances de iluminação. Então, decidi que basta adicionar uma camada semitransparente sobre outros objetos.

O problema desta solução é que, se eu tiver um objeto de fonte de luz no jogo (como o herói usando uma tocha ou um prédio em chamas), deve haver uma área mais clara ao redor, certo? Como estou colocando minha camada semi-transparente sobre tudo, como você sugeriria obter o efeito visual da tocha que eu quero? Talvez redesenhe essa camada adicionando 'lacunas' ou áreas de cores diferentes com base no efeito de iluminação?

Ivaylo Slavov
fonte
2
A máscara pode ser o caminho a seguir
Gustavo Maciel
5
"Torchlight" no título pode ser confuso devido ao jogo chamado Torchlight.
Tétrada
4
O @Tetrad deve estar ok, desde que não esteja em maiúsculas. Quanto a mim, o Torchlight não veio à mente até ler seu comentário.
famousgarkin
No entanto, sugeri uma edição para tornar o título mais específico.
famousgarkin
2
possível duplicata de Como a iluminação 2D é implementada?
bummzack

Respostas:

12

Não sei no que você está programando, mas é assim que eu lidei com o XNA:

  1. Na chamada de desenho, um List<Light>objeto é criado / limpo.
  2. Durante o loop de desenho do bloco, cada bloco é verificado para ver se possui alguma luz associada a ele. Se isso acontecer, os Lightobjetos serão anexados ao List<Light>.
  3. Os ladrilhos são desenhados por conta própria RenderTarget2D.
  4. Após o loop do bloco, a lista de Lights é iterada e desenhada por conta própria, RenderTarget2Dusando uma textura que fiz com a seguinte aparência:
    Textura clara(Nota: usei os valores R, G e B aqui, mas você provavelmente deve usar o canal alfa no seu textura real.)
  5. Usando um sombreador personalizado, renderizo a superfície do ladrilho na tela e passo a superfície de iluminação como um parâmetro que é amostrado para o valor de "escuridão" em cada pixel.


Agora, há algumas coisas a serem observadas:

Em relação ao ponto 4:

Na verdade, tenho dois shaders personalizados, um para desenhar as luzes no alvo de renderização da iluminação (etapa 4) e outro para desenhar o alvo de renderização do bloco na tela usando o alvo de renderização da iluminação (etapa 5).
O sombreador usado no ponto 4 me permite adicionar (o que eu chamo) um valor de "luminosidade". Esse valor é um floatmultiplicado por cada pixel na textura antes de ser adicionado ao destino de renderização, para que eu possa essencialmente tornar as luzes mais claras ou mais escuras.
Nesse ponto, também levo em consideração o valor de "escala" da luz, o que significa que posso ter luzes grandes ou pequenas usando apenas uma textura.

Em relação ao ponto 5:

Pense no alvo de renderização da iluminação como tendo essencialmente um valor para cada pixel de 0 (preto) a 1 (branco). O sombreador multiplica essencialmente esse valor contra os valores RGB de um pixel no bloco renderiza o alvo para criar a imagem final desenhada.

Também tenho mais código aqui, onde passo (para o sombreador) um valor a ser usado como a cor da sobreposição dia / noite. Isso também é multiplicado pelos valores RGB e incluído nos cálculos de destino da renderização de iluminação.


Agora, isso não permitirá que você faça coisas como bloquear a luz de contornar objetos e outros enfeites, mas, pelo menos para os meus propósitos, é simples e funciona bem.

Escrevi posts mais detalhados aqui e aqui, que podem ajudá-lo. Não tenho tempo agora, mas se você quiser, posso entrar em mais detalhes aqui no gamedev.

Ah, e aqui está uma olhada no meu editor de mapas:insira a descrição da imagem aqui

Richard Marskell - Drackir
fonte
Gere e limpe uma lista: todos os quadros podem não ser muito caros?
Gustavo Maciel
@Gtoknu Não faz nenhuma diferença perceptível no meu jogo. A lista está apenas mantendo referências a objetos que já existem na memória, então não é como se toda luz estivesse sendo recriada ou algo assim, apenas uma lista.
Richard Marskell - Drackir
você pode estar certo, não totalmente, mas está. Obviamente, você não está criando objetos completos, mas está adicionando ponteiros às referências, ainda com baixo uso, mas ainda consumindo. Você está fazendo em um bom caminho, mas eu acho que pode ser melhor se você colocar a lista fora do método draw, uma vez que a lógica do em atualização é muito mais rápido do que em empate
Gustavo Maciel
@Gtoknu Claro, você pode declarar a lista onde quiser, mas o ponto é que as luzes estão associadas aos ladrilhos. O Drawmétodo do bloco é onde você descobre se um bloco tem luzes ou não. Eu não percorro todas as peças desenhadas noUpdate método, portanto adicionaria uma sobrecarga extra para isso. Além disso, o XNA tenta garantir que Updateserá chamado 60 vezes por segundo, para que possa sacrificar as Drawchamadas por isso, o que significa que esse código seria chamado com menos frequência.
Richard Marskell - Drackir
Tudo isso dito, é um ponto discutível, porque eu finalmente mudei as luzes para suas próprias listas com base no particionamento espacial e apenas desenhei todas as luzes nas seções que cruzam a tela. Eu não falei sobre isso no meu post por falta de tempo, mas é mencionado no segundo post do blog que eu vinculei.
Richard Marskell - Drackir
9

Normalmente, a iluminação nos jogos 2D é feita com um Mapa Normal para todos os seus sprites, e calcule os efeitos de iluminação 3D nos seus sprites 2D. Isso é conhecido livremente como "2.5D". No entanto, eu não recomendaria fazer isso no seu primeiro jogo, pois é complexo.

Aqui está um vídeo incrível de alguém que fez isso no XNA: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

Dito isto, provavelmente existem maneiras de trapacear e obter um sistema de pseudo-iluminação que possa funcionar com várias suposições.

John McDonald
fonte
Já viu este vídeo antes, +1 por mencionar uma técnica tão incrível.
Gustavo Maciel
Obrigado pelo conselho e pelo link do vídeo. De fato, um mapa parece ser uma solução. Eu mesmo tentaria usar o mapa na minha camada superior para criar uma 'lacuna' ou alterar o efeito que isso causaria nos objetos subjacentes.
Ivaylo Slavov
5

É difícil sugerir uma abordagem se você não for completamente específico sobre o efeito que está tentando alcançar. Detalhes como se as luzes devem ser obstruídas pelo ambiente ou não, qual é o ponto de vista do seu jogo, até que ponto a luz deve interagir com o ambiente etc.

Vou largar meus dois centavos embora. Veja se este tutorial de Catalin Zima, intitulado Dynamic 2D Shadows, se encaixa na sua conta. Como você pode ver, a luz tem um raio e não passa por obstáculos. Você pode animar um pouco o raio e a cor para torná-la mais próxima de uma luz real da tocha.

insira a descrição da imagem aqui

Nesse caso, a luz atua como uma espécie de sobreposição na parte superior da cena, mas não interage com ela da mesma forma que no exemplo de John, embora leve em consideração os obstáculos.

Editar

Catalin vincula a outro artigo que ele usou como referência, mas o link está quebrado. Aqui está um link atualizado .

David Gouveia
fonte
Obrigado, eu acho que isso não é o efeito que eu sou depois, mas ainda obrigado por compartilhar :)
Ivaylo Slavov