Adequação da neblina no solo usando quads alfa em camadas?

16

Uma abordagem em camadas usaria uma série de quadras maciças de textura alfa dispostas paralelamente ao chão, cruzando toda a geometria intermediária do terreno, para fornecer a ilusão de neblina no solo de maneira bastante eficaz de cima para baixo, olhando para baixo e um pouco menos eficaz quando dentro da neblina e olhando para o horizonte (veja a imagem abaixo).

Como alternativa, uma abordagem principalmente baseada em shader calcularia a densidade em função da distância da vista no substrato de neblina no solo e produziria o valor do fragmento com base nisso.

Sem precisar testar o desempenho de cada abordagem , gostaria de ouvir primeiro as experiências dos outros (não especulações!) Sobre que tipo de desempenho afeta a abordagem da textura alfa em camadas. Pergunto especificamente devido aos impactos freqüentemente citados do excesso (não tenho certeza de como a taxa de preenchimento vincula seu sistema de desktop médio). Uma lista de jogos usando essa abordagem, particularmente jogos mais antigos, seria imensamente útil: se isso fosse viável no hardware anterior ao DX9 / OpenGL2, provavelmente funcionaria bem para mim.

Uma grande questão está relacionada a esse tipo de efeito:

insira a descrição da imagem aqui

(O crédito de imagem vai para Lume de lume.com)

Observe como a gradação vertical da névoa é contínua / suave. OTOH, usando camadas quádruplas texturizadas, posso apenas assumir que as camadas seriam muito óbvias ao atravessá-las - quanto mais esparsas elas fossem, mais óbvio isso seria. Isso contrasta com o alinhamento dos planos de neblina para enfrentar o jogador em cada quadro, onde essa grosseria seria muito menos óbvia.

Engenheiro
fonte
1
Por que você deseja usar camadas quad alfa para isso? A "abordagem de shader-heavy" não é apenas mais precisa, também não é exatamente conhecida por ser lenta .
Nicol Bolas
1
@StephanvandenHeuvel Claro, mas é um nevoeiro baseado em distância, alinhado ao espaço de visualização. Névoa não alinhada ao solo. Corrigir?
Engenheiro de
1
@NickWiggill Sim, você está correto.
Stephan van den Heuvel
1
IIRC, o Wii tinha nevoeiro alinhado ao solo em seu (semi) oleoduto fixo. Aparentemente, a glFogCoordextensão no OpenGL herdado também permitiu isso . Embora pareça limitado: é baseado no solo ou à distância.
Laurent Couvidou
1
O Quake 3 fez algo semelhante a isso, usando uma abordagem de pipeline fixo que funcionava com o GL1.1. A grande preocupação que tenho é que a taxa de preenchimento / overdraw pode se acumular muito, mas provavelmente vale a pena fazer o download do código-fonte do terceiro trimestre e revisar sua implementação; você não pode fazer exatamente o mesmo, mas pelo menos isso pode ajudá-lo a tomar uma decisão.
Maximus Minimus

Respostas:

15

Desde que você pediu experiências, aqui estão as minhas.

Nos tempos em que eu estava programando jogos para PS2, a abordagem "camadas quadras alfa" era uma maneira de implementar o nevoeiro. Ocasionalmente como neblina no solo, mas muito mais comumente como neblina em tela cheia. E funcionou muito bem em ambos os casos. Então, sim, era viável nos dias pré-fragmento-shader.

Bem, mais ou menos. O problema, como você observou, é que, se você deseja uma névoa suave como a vista na captura de tela, precisa de um número absurdo de quads alfa.

No PS2, normalmente podíamos comprar algo entre três e cinco camadas. Que definitivamente parecia "paredes" de névoa flutuando na sua frente. Mais do que isso, e a taxa de preenchimento começou a diminuir nossa taxa de quadros.

Normalmente, esses quadríceps eram desenhados a distâncias fixas em frente à câmera, para que você nunca entendesse a situação mencionada, "andando por" um deles. Por outro lado, usando essas distâncias fixas, tudo o mais no mundo fazpasse por esses aviões enquanto o jogador se move, o que é uma falha gráfica bastante óbvia. Quase todo mundo fez isso naquela época, mas não seria aceitável agora (a menos que você estivesse fazendo isso por razões estilísticas). (Exceção: algumas pessoas calculavam valores de neblina como parte do equivalente do PS2 a um sombreador de vértice. Isso funcionou e foi muito mais rápido, mas exigiu que seus modelos fossem altamente tesselados. Você não podia ter paredes longas, por exemplo, porque a neblina era apenas sendo calculado nos cantos da parede e depois sendo espalhado por toda a face da parede.A parede parecia totalmente embaçada se você estivesse próximo ao meio, por exemplo, pois estava testando apenas os níveis de neblina pontos finais)

Observe que se você colocar quads de nevoeiro estaticamente no mundo (como você mencionou como uma possibilidade), não poderá obter a aparência de nevoeiro extremamente suave, como na imagem que você fornece - haverá sobreposições estranhas entre quads adjacentes, dependendo da orientação do espectador. Essas sobreposições podem aparecer como listras ou trapézios (se os quadríceps não forem texturizados) ou como aglomerados (se tiverem textura).

Mas vamos supor que estamos usando quads largos voltados para a tela para fazer esse nevoeiro no solo e fazer alguns cálculos sobre como fazer um nevoeiro realmente suave usando esse método, em terreno plano, com uma câmera olhando para a frente - essa é a nossa situação ideal . Vamos assumir a resolução HD: 1920x1080, que coloca o nosso horizonte na linha de varredura 540. Vamos também assumir que temos visibilidade até o horizonte (ou seja, supondo que você não tenha a névoa atingindo a opacidade total antes de atingir o horizonte). Com um quad de nevoeiro iniciando e um parando em cada linha de varredura (para obter um nevoeiro suave), precisamos (540 * 2 ==) de 1080 quad quad. Cada um desses 1080 quad nevoeiros cobrirá toda a extensão horizontal da tela,

Vamos estimar baixo e dizer que, em média, um plano de neblina cobrirá cerca de 300 linhas de pixels. Os mais próximos cobrem menos, os mais distantes cobrem menos, as linhas do meio cobrem muito mais.

Com essa estimativa, obtemos (1920x300 ==) 576.000 pixels sendo tocados pelo quad nevoeiro médio. No total, são (576.000 * 1080 ==) 622.080.000 pixels sendo tocados no total para todo o efeito "névoa suave através da renderização de muita geometria translúcida". E esse número aumentará para pessoas que executam em uma resolução mais alta. Além disso, obtemos o mesmo número de testes com o buffer z e quase o mesmo número de operações de mesclagem de pixels, pois todas essas camadas transparentes estão se desenhando uma e outra vez. São muitos pixels.

E esse é o melhor cenário - você obterá muito mais cobertura da tela dos quads de nevoeiro se o usuário olhar para baixo ou se agachar.

Observe que, como estamos sobrepondo 1080 quads, provavelmente queremos um valor alfa de cerca de (1,0 / 1080 ~ =) 0,0009 definido em cada um, para que nosso nevoeiro atinja total opacidade se você examinar todos os 1080 quads. (Poderíamos ir além disso, mas esse é o valor supondo que desejamos espalhar o intervalo o máximo possível). Observe que esse valor não pode ser representado como o componente alfa de um valor de cor de 32 bits (256 * 0,0009 ~ = 0,237 e, portanto, será arredondado para 0 se você tentar). Você precisará fornecer o valor 0,0009 ao OpenGL como um valor de ponto flutuante para que isso funcione. (Observe também que na verdade você não deseja definir esse mesmo valor em cada um - enquanto definimos que queríamos um quad para iniciar e um para terminar em cada linha de varredura abaixo do horizonte, a fim de gerar uma névoa suave,

Observe também que as misturas de neblina não funcionarão corretamente usando essa abordagem, como faria com um sombreador moderno - em vez de obter um cálculo de "mistura entre a cor do objeto base e a cor de neblina usando essa porcentagem", você obtém 1080 cálculos de "mistura entre a cor até agora e a cor do nevoeiro pela porcentagem de nevoeiro". O que significa que o nevoeiro afetará objetos após uma queda logarítmica. (Ou seja, um objeto afetado por 20 quads de nevoeiro aparecerá menos que o dobro do que algo afetado por 10 quads de nevoeiro, porque os primeiros quads de nevoeiro têm mais impacto na operação de mistura).

Tudo isso é para dizer: Por favor, use um shader de fragmento.

Não mesmo. É mais simples e mais barato, mais rápido e mais rápido de implementar e menos propenso a erros e permite que você volte a fazer seu jogo de verdade e é melhor de todas as maneiras possíveis. Nós teríamos feito isso totalmente na era PS2, se isso fosse vagamente possível na época.

Trevor Powell
fonte
1
+1 para uma resposta abrangente com base na experiência do mundo real.
usar o seguinte
3
Há um ano e um mês, quando escrevi essa pergunta, eu ainda estava disposto a brincar de frango com taxas de preenchimento. Agora, eu optaria por uma textura 3D grossa para representar volumes de neblina no solo com densidades em constante mudança determinadas, digamos, pelo ruído perlin 3D e, em seguida, usaria isso como base para os efeitos do espaço na tela, como você sugeriu.
Engineer