Como implemento a iluminação ocluída em um jogo 2D baseado em bloco?

11

Quero ter iluminação 2D que possa ser bloqueada por objetos do jogo. Meu jogo tem uma visão de cima para baixo e todos os objetos do jogo são descritos por retângulos.

Digamos que eu tenho um mundo 10x10 e coloco uma luz em 1x1 e paredes ao redor dessa luz. Quero poder ver a fonte de luz em 1x1, mas não em nenhum outro lugar, porque está bloqueada pelas paredes.

Já ouvi falar em lançar raios de luz, mas como isso realmente funciona?

LiquidFeline
fonte
1
Gostaria de ver algumas respostas independentes de idioma para esta pergunta.
Dashto
2
@ Dashto: Você precisa de um código de trabalho no idioma que usa? Que é um lugar errado para pedir ..
Kromster
O que você tentou? Quando você diz "em qualquer outro lugar sem fonte de luz", o que você quer dizer? Acendeu seu bloco de 1,1 e é isso. Talvez eu não entenda sua pergunta, você poderia postar uma ilustração?
Laurent Couvidou
1
@ Krom Stern: Na verdade, estou pedindo exatamente o oposto - uma resposta conceitual que não depende da linguagem. Os dois threads vinculados como duplicados não falam muito sobre os conceitos. De fato, a maioria das perguntas semelhantes neste site simplesmente tem respostas dizendo "Use esta biblioteca!" o que é menos útil para quem quer entender como funciona.
Dashto
@Dashto: Isso é importante peça de informação, você deve acrescentar que a questão;)
Kromster

Respostas:

13

Amit Patel escreveu um artigo muito bom sobre fundição de raios 2D.

Isso envolve lançar raios para cada um dos vértices dentro do alcance da fonte de luz para construir uma malha de luz.

insira a descrição da imagem aqui

Todos os exemplos visuais são interativos no post e muito fáceis de entender.

Você também não precisa se limitar a uma caixa, pois o perímetro que você traça pode ter a forma que desejar.

MichaelHouse
fonte
1

Você deve usar o algoritmo de radiodifusão , ou seja, deve poder calcular a interseção de raios (meia linha) com qualquer objeto em sua cena (linhas, quadrados, círculos, triângulos ...) e escolher a interseção mais próxima. Você lança o raio em todas as direções e depois "atrai a luz" apenas para o objeto mais próximo.

Aqui está como isso pode parecer .

Ivan Kuckir
fonte
Eu apenas perguntei como eu usaria o casting de raios. Eu sei sobre isso.
LiquidFeline
0

Se você sabe o que é a conversão de raios, tudo o que você precisa fazer é realmente codificá-lo. Não é muito complexo, desde que você tenha coordenadas para cada vértice.

Primeiro, crie um objeto emanador de luz. Coloque sua luz nas coordenadas x, y.

#include <math.h>
int i = 0;
if ( sqrt( abs( light.x - vertex.x )^2 + abs( light.y - vertex.y )^2 ) <= light.radius)
{
    lightOccludingVertices[i] = vertex;
    i++;
}

//If two or more vertices are both a member of an individual wall,
//illuminate the triangular area between the light, the furthest 
//vertex on the x-axis, and the furthest vertex on the y-axis

Não é garantido que funcione para um polígono côncavo, mas deve funcionar bem para todos os polígonos convexos.

Isso funcionará se seus objetos oclusivos (paredes, personagem, comedor de pessoas roxas voadoras) forem pintados na tela após a aplicação de iluminação. Caso contrário, metade de uma parede parecerá significativamente mais brilhante que a outra metade. Se sua luz pontual for equidistante de dois pares de vértices da mesma parede (exatamente a metade da altura da parede), aplique o triângulo nos dois vértices mais próximos, em vez dos dois mais distantes.

Também devo mencionar que esse método requer um ponto de vértice criado dinamicamente, em que a borda do raio da luz encontra a superfície do objeto oclusivo. Isso cria no mínimo 3 vértices para qualquer objeto oclusivo e permitirá que paredes que ultrapassam o raio da luz (ou fora da tela) também bloqueiem qualquer luz.

Mais informações sobre polígonos côncavos e convexos

igrad
fonte