Peça transparência independente no sistema de partículas

9

Estou escrevendo um sistema de partículas e gostaria de encontrar um truque para obter uma mistura alfa adequada sem classificar as partículas porque:

  • Cada partícula é um sprite de ponto em uma única malha e não posso usar a capacidade do gráfico de cena para classificar nós transparentes. O nó do sistema deve ser classificado corretamente, no entanto.
  • A posição das partículas é calculada no shader a partir da velocidade inicial, aceleração e tempo. Para classificar o sistema, eu teria que executar todos esses cálculos na CPU, o que é algo que eu quero evitar.
  • Classificar centenas de partículas em relação à posição da câmera e carregá-las na GPU, cada quadro é costurado para uma operação silenciosa e pesada.

O teste alfa parece ser rápido o suficiente no GLES 2.0 e funciona bem para texturas não transparentes, mas "mascaradas". Ainda assim, não é suficiente para partículas semi-transparentes.

Como você lidaria com isto?

Stepan Zastupov
fonte
Absolutamente quão essencial é que eles sejam classificados corretamente? Você realmente viu algum artefato (importante) usando mistura de baunilha?
ChrisE
Uma partícula pode se misturar com o fundo em vez de outra e, em seguida, a essência "retângulo" do sprite pontual é muito perceptível. O teste alfa ajuda aqui, mas os artefatos ainda são visíveis quando o valor alfa é baixo, mas baixo o suficiente para descartar o fragmento.
Stepan Zastupov 7/03/11
6
Você tentou desabilitar a gravação em profundidade (deixando testes de profundidade) ao renderizar as partículas? Isso deve tornar a ordem incorreta menos óbvia.
Adam
2
Após algumas experiências, descobri que a desativação da gravação em profundidade é a melhor solução na maioria dos casos.
Stepan Zastupov 21/03

Respostas:

10

Aqui está o que eu faria.

Etapa 1: não classifique. Apenas faça. Veja se é um problema. Provavelmente não é.

Etapa 2: limite as partículas de maneira que realmente não precisem de classificação, como:

  • Apenas sólidos (com arestas de alfa a cobertura)

    • deixe o zbuffer cuidar da classificação.
  • Apenas bits aditivos

    • a + b = b + a, então a ordem não importa

Etapa 3: se mais for necessário, divida a renderização de partículas em bits que devem estar na frente e no restante e execute a renderização em várias passagens (poderia corrigir fumaça complexa, por exemplo)

Etapa 4: se ainda for necessário mais, ou se você precisar de uma solução geral, uma coisa que vem à mente seria usar MRTs para realizar uma classificação muito difícil de N bucket; transforme as partículas em N superfícies de saída e componha-as em uma passagem separada.

Qualquer coisa adicional exigiria mais informações sobre seu caso de uso específico. Mas tenho certeza de que você realmente não precisa de independência de pedidos, afinal. Basta usar partículas suficientes de maneira aleatória e tudo ficará bem =)

Jari Komppa
fonte
6

Apenas não escreva no buffer de profundidade ao renderizar as partículas. Isso permitirá que todos eles sejam renderizados e combinados. Você ainda deve executar testes de profundidade para que eles possam ser adequadamente ocluídos pela geometria na cena.

KlashnikovKid
fonte
5

O uso da ordem de mistura aditiva não importa:

glEnable(GL_BLEND)
glDepthMask(GL_FALSE)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
DrawParticles();

// Now turn depth masking on and blending off, so state is unchanged.
glDepthMask(GL_TRUE)
glDisable(GL_BLEND)

Isso pressupõe que sua textura de sprite tenha um plano de fundo transparente.

teh_leecherer
fonte