Como obter luz que muda de cor no meio do caminho?


11

Pensei em criar fontes de luz e algumas janelas coloridas. Agora, as janelas são semi-transparentes. Como eu poderia fazer isso para que, quando a luz (digamos, branco puro) atinja o vidro e continue através dele, mas mude a cor para a mesma cor do vidro que passou?

Sei que o efeito descrito aqui pode ser falsificado usando luzes de área no lado "colorido" da janela, mas e se eu apenas quisesse ter um ponto de luz branco?


Em vez de alterar a cor da luz, você poderia alterar a cor de base dos objetos iluminados do outro lado do vidro? talvez isso funcionasse?
HumanCatfood

A janela transparente é renderizada como uma segunda passagem, seu sombreador simplesmente modifica o equilíbrio de cores de cada saída de pixel. Isso não funcionaria?
Patrick Hughes

Parece-me que isso é análogo ao problema das sombras; se você possui um bom algoritmo para sombras projetadas por objetos semitransparentes (não sei se isso é prático), basta executá-lo por três canais de cores paralelos.
Kevin Reid

Respostas:


14

Há um grande número de maneiras de fazer isso. Isso exigirá o uso de um sombreador e presumo que você já esteja iluminando por pixel. A seguir estão algumas sugestões, no entanto, encontrar a técnica certa para você pode levar muito mais pesquisa.

Rapido e sujo

Você pode especificar caixas delimitadoras que definem áreas internas. Se a luz estiver fora das caixas, mas a geometria (que não está na sombra) estiver dentro da caixa, a luz deverá ter sido afetada pela passagem por uma janela (isso também é verdade se a geometria estiver fora da caixa e a luz está dentro). O único problema aqui é como passar as informações da caixa para o shader e como declarar o efeito na luz.

Outra opção é especificar janelas como objetos em planos. Primeiro teste para ver se a geometria e a luz estão em lados opostos do plano e, em seguida, se o caminho entre elas cruza o plano em um ponto dentro dos limites da janela. Isso seria mais preciso que o primeiro método e seria mais fácil ter janelas nos mesmos interiores com cores diferentes de vidro.

Continue ficando mais detalhado com a representação geométrica das janelas e você obterá resultados mais precisos, mas o cálculo também ficará mais pesado.

Essas técnicas funcionariam razoavelmente bem para um atirador de corredor, mas não tão bem para um mundo dinâmico ou aberto quanto provavelmente seriam necessários muitos ajustes para fazer com que parecesse certo sem muitos artefatos. Além disso, essas técnicas podem rapidamente se tornar um pouco intensas; portanto, é recomendável mudar para um pipeline de sombreamento diferido.

Mapas Sombra

Outra opção é fazer algo semelhante ao mapeamento de sombras.

No mapeamento de sombra, você gera uma imagem de bitmap do mundo afetado por uma luz. Cada pixel, embora ainda seja uma cor, é na verdade a distância da parte mais próxima da geometria não transparente (você usa os quatro bytes para 1 flutuação em vez de 4 cores). Se você calcular a distância da luz a um pedaço de geometria e for maior que o valor correspondente no mapa de sombras, seu pedaço de geometria estará na sombra (você geralmente usa o raio entre a geometria e a luz para indexar o mapa).

Se você aplicar essa idéia ao seu problema, o que você faria é armazenar um mapa da distância da luz da peça mais próxima da geometria transparente e também fazer um segundo mapa da cor da luz depois de passar por essa geometria ( simplesmente a cor da geometria se a luz for branca).

Se o seu pedaço de geometria estiver mais distante do que a distância neste mapa, use a cor do mapa; caso contrário, use a cor clara original.

A função para calcular a cor de cada pixel no mapa deve ser aproximadamente; lightColor - invertedWindowColor. Assim, para uma luz branca pura e uma janela vermelha pura que não absorve o espectro vermelho que temos; (255.255.255) - (0,255.255) = (255,0,0). Portanto, a cor da luz do outro lado é vermelho puro. Para um objeto transparente mais complexo, como uma janela de vitral, convém fazer uma pesquisa de textura para obter a cor do material.

Se você está procurando algo semelhante, consulte Mapas de sombras reflexivas .

Essa técnica oferece uma grande fidelidade e possivelmente seria a melhor se você desejar usar geometria transparente complexa, como vitrais.

Tentativa de uma solução geral

Recentemente, tornou-se popular codificar informações de iluminação em uma representação em voxel (elas não são apenas para geometria). O mais recente mecanismo crytek usa esse tipo de estratégia para iluminação avançada ( volumes de propagação de luz ).

Aqui está a ideia geral:

  • Crie um mapa de cubos uniformemente espaçados que abranja sua cena (considere o uso de curvas de ordem z ).
  • Encontre uma maneira de armazenar informações de iluminação incidente para cada voxel (as representações harmônicas esféricas são úteis aqui).
  • Encontre o voxel que contém uma luz e represente essa luz no voxel.
    • Propague a luz para fora através dos voxels adjacentes (como água minecraft)
    • Calcule como a geometria em cada voxel afetará a luz que passa por ele (absorver, refletir, transmitir)
    • repita até a luz desaparecer

Existem várias maneiras de criar essas informações de voxel, mas a lista acima fornece uma idéia geral. Por exemplo; você pode começar gerando mapas / volumes de sombra e projetando essas informações no mapa voxel para poder criar rapidamente o mapa de iluminação direta. Então você inicia a propagação a partir dos voxels ao longo da borda da área afetada. Lembre-se de que, nesse caso, você desejará ignorar se a geometria é transparente ou não ao gerar o mapa / volume de sombras.

Na passagem final de um renderizador diferido, ao calcular a iluminação de um ponto da geometria, você simplesmente usa a posição da geometria para indexar seu mapa voxel e descobrir como é a iluminação incidente naquele ponto do espaço. Em seguida, você pode criar um mapa de tela do lado da CPU com iluminação incidente ou, possivelmente, fazer isso com o cuda.


Obrigado pelo longo post! Atualmente, estou investigando se executarei a renderização adiada ou adiada para o projeto atual em que estou trabalhando. No momento, provavelmente será adiado. Como você faria quando a janela fosse multicolorida (por exemplo, um vitral de uma igreja)?
manabreak

@manabreak - Eu usaria a extensão do mapa de sombras, pois ofereceria o melhor nível de fidelidade para esse caso. Vou editar o post para explicar isso.
OriginalDaemon

Caramba, valeu! Este post realmente fez o meu dia, provavelmente nunca vi tanto esforço em um único post.
Manabreak
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.