Névoa por distância e altura
Desbotar o que está longe, ou embaixo, rumo a uma cor de névoa.
Cards
Um exemplo ao vivo para ajustar, aprender e copiar.
Como funciona
O ar nunca é perfeitamente limpo. Num trecho longo o bastante, poeira e gotículas de água absorvem e espalham parte da luz que vem de um objeto distante, e espalham na sua direção um pouco da luz do céu. Por isso montanhas ao longe parecem mais claras e mais azuladas que as próximas, e os pintores chamam isso de perspectiva atmosférica. A névoa num shader imita isso com dois números por pixel: a que distância a superfície está e quanto da luz dela sobrevive a essa distância.
A parte da sobrevivência segue a lei de Beer–Lambert: cada unidade de névoa deixa passar a mesma fração da luz, então a
transmitânciaA fração da luz que atravessa um meio como a névoa, de 1 (toda) a 0 (nenhuma). Num meio uniforme, ela cai exponencialmente com a distância percorrida. Transmitância A fração da luz que atravessa um meio como a névoa, de 1 (toda) a 0 (nenhuma). Num meio uniforme, ela cai exponencialmente com a distância percorrida. Interpolação linear (mix) Mistura de a até b por um fator t, em linha reta. O GLSL chama de mix; o HLSL e a maioria dos editores de nós chamam de lerp.T = exp(−density · distance)exp(-density * distance). Depois o
pixel misturaMistura de a até b por um fator t, em linha reta. O GLSL chama de mix; o HLSL e a maioria dos editores de nós chamam de lerp.mix(a, b, t) = a (1 − t) + b t
De onde vem a distância decide o estágio:
- Pós-processamento de tela. Uma passada de tela cheia lê o quadro pronto e o
buffer de profundidadeUma imagem do tamanho do framebuffer que guarda, para cada pixel, a distância da superfície mais próxima desenhada até agora. O teste de profundidade a usa para esconder o que fica atrás.Renderização
Buffer de profundidade
Uma imagem do tamanho do framebuffer que guarda, para cada pixel, a distância da superfície mais próxima desenhada até agora. O teste de profundidade a usa para esconder o que fica atrás.
Fontes, transforma a profundidade de cada pixel numa distância e aplica a névoa na imagem inteira de uma vez. Uma passada cobre todos os materiais da cena, e é por isso que as engines fazem assim. A névoa exponencial é esta versão. - Superfície. Cada material calcula a própria névoa a partir da posição do fragmento no mundo e da posição da câmera, no fim do seu shader de fragmento. Não precisa de textura de profundidade e funciona em superfícies transparentes, que uma passada de profundidade não enxerga, mas todo shader da cena precisa incluí-la.
A névoa por altura troca o meio uniforme por um mais denso perto do chão: a densidade cai exponencialmente com a altitude, e a névoa ao longo de um raio continua tendo uma fórmula fechada. Ela precisa da posição de cada pixel no mundo, então numa passada de pós-processamento também precisa das matrizes da câmera para reconstruir essa posição a partir da profundidade.
A maioria das engines traz névoa por distância, e muitas também por altura, nas configurações de ambiente, e elas costumam ser a escolha certa. Escreva a sua quando o visual precisar ser outro: uma cor de névoa que muda com a direção do olhar, névoa que só enche um vale, ou névoa num pipeline estilizado em que a nativa não roda.
Leitura complementar
- mix (abre em uma nova aba)Referência
- clamp (abre em uma nova aba)Referência
- Linear interpolation (abre em uma nova aba)Referência
- Shaping functions (abre em uma nova aba)Livro
- Useful little functions (abre em uma nova aba)Artigo
- pow (abre em uma nova aba)Referência
- Depth testing (abre em uma nova aba)Artigo
- glDepthFunc (abre em uma nova aba)Referência
- Spatial shaders (abre em uma nova aba)Documentação
- Better fog (abre em uma nova aba)Artigo
- Beer–Lambert law (abre em uma nova aba)Referência
- glFog (abre em uma nova aba)Referência
- exp (abre em uma nova aba)Referência