Não sei no que você está programando, mas é assim que eu lidei com o XNA:
- Na chamada de desenho, um
List<Light>
objeto é criado / limpo.
- Durante o loop de desenho do bloco, cada bloco é verificado para ver se possui alguma luz associada a ele. Se isso acontecer, os
Light
objetos serão anexados ao List<Light>
.
- Os ladrilhos são desenhados por conta própria
RenderTarget2D
.
- Após o loop do bloco, a lista de
Light
s é iterada e desenhada por conta própria, RenderTarget2D
usando uma textura que fiz com a seguinte aparência:
(Nota: usei os valores R, G e B aqui, mas você provavelmente deve usar o canal alfa no seu textura real.)
- 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 float
multiplicado 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: