Quais são alguns métodos para renderizar transparência no OpenGL


14

A mistura alfa pode ser ativada para tornar as superfícies transparentes, da seguinte forma:

glDisable(GL_DEPTH_TEST); //or glDepthMask(GL_FALSE)? depth tests break blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Mas isso só funciona se os objetos forem renderizados de volta para a ordem frontal. Caso contrário, as coisas no fundo aparecerão na frente de objetos mais próximos, como o piso da imagem abaixo. Para partículas e elementos da GUI, a classificação seria boa, mas para malhas triangulares parece muito esforço e lento, conforme discutido aqui: https://www.opengl.org/wiki/Transparency_Sorting .

Quais são os métodos comuns para lidar com isso? Eu sei que isso é bastante amplo e não busco detalhes detalhados da implementação, apenas uma breve descrição de algumas abordagens e o que pode estar envolvido.

insira a descrição da imagem aqui


Não tenho certeza se isso deve ser uma resposta ou não, mas os erros na sua imagem são causados ​​pela renderização sem teste de profundidade em todas as primitivas. Você deve renderizar a cena em 2 passagens: Primeiro, renderize normalmente toda a geometria sólida. Posteriormente, desative as gravações em profundidade (não GL_DEPTH_TEST) e processe a geometria translúcida em ordem aproximadamente inversa à anterior. Isso garantirá que a geometria transparente não seja desenhada na frente da geometria sólida à sua frente.
precisa saber é o seguinte

@yuriks Nesse caso, é provavelmente um péssimo exemplo da minha parte, mas tudo deve ser transparente. Eu queria algo para mostrar como a transparência pode parecer errada quando mal realizada. Também um exemplo em que a geometria de classificação seria incrivelmente difícil (por exemplo, aqui o piso é um polígono gigante e cobre toda a faixa de profundidade).
Jozxyqk

Respostas:


10

Um conjunto de técnicas para evitar pedidos explícitos tem o nome de Transparência Independente dos Pedidos (OIT, abreviado).

Existem muitas técnicas de OIT.

Historicamente, um é o peeling de profundidade . Nesta abordagem, você primeiro renderiza os fragmentos / pixels mais frontais e, em seguida, encontra o mais próximo do encontrado na etapa anterior e assim por diante, continuando com a "camada" necessária. É chamado de descascamento em profundidade, porque a cada passo você "descasca" uma camada de profundidade. Toda a sua camada pode ser recombinada normalmente de trás para frente. Para implementar esse algoritmo, você precisa ter uma cópia do buffer de profundidade.

Outro conjunto de técnicas são as misturas OIT. Um dos mais recentes e interessantes é o OIT Blended Weighted, proposto por McGuire e Bavoil . Basicamente, aplica uma soma ponderada para todas as superfícies que ocupam um dado fragmento. O esquema de ponderação que eles propõem é baseado no espaço da câmera Z (como uma aproximação à oclusão) e na opacidade.
A idéia é que, se você pode reduzir o problema a uma soma ponderada, não se importa muito com o pedido.

Além do artigo original, um ótimo recurso para detalhes de implementação e problemas do OIT ponderado misturado está no blog de Matt Pettineo . Como você pode ler em seu post, essa técnica não é uma bala de prata. O principal problema é que o esquema de ponderação é central e precisa ser ajustado de acordo com a sua cena / conteúdo. A partir de seus experimentos, embora a técnica pareça funcionar bem para a opacidade relativamente baixa e média, ela falha quando a opacidade se aproxima de 1 e, portanto, não pode ser usada em materiais onde grande parte da superfície é opaca (ele é o exemplo da folhagem).

Novamente, tudo se resume a como você ajusta seus pesos de profundidade e encontrar aqueles que se encaixam perfeitamente em seus casos de uso não é necessariamente trivial.

Quanto ao que é necessário para o OIT Blended Ponderado, nada mais que dois destinos de renderização extras. Uma que você preencha com a cor alfa pré-multiplicada (cor * alfa) e alfa, ambas ponderadas de acordo. O outro apenas para os pesos.


6

Uma opção é usar descamação profunda.

Essencialmente, a pessoa processa a cena um número definido de vezes (digamos, nvezes) para determinar o mais próximo, o segundo mais próximo, até os nfragmentos mais próximos da cena.

Esse processamento é feito aplicando primeiro um teste regular de profundidade em toda a cena (que naturalmente retorna a superfície mais próxima). Em seguida, usa-se o resultado do teste de profundidade para filtrar a primeira camada, ignorando tudo com uma profundidade menor que a retornada no teste de profundidade.

A aplicação do teste de profundidade novamente retornará a segunda camada. Repita conforme necessário.

Depois de ter as camadas, basta desenhar todas as camadas na ordem inversa (supondo que você acompanhe as cores RGBA de cada camada), combinando normalmente, pois as camadas estão na ordem da frente para trás.


1
Obrigado! Parece que vou precisar de dois buffers de profundidade para isso. Ou seja, um para armazenar e filtrar as últimas profundidades e outro para fazer o teste de profundidade para a renderização atual. Corrija-me se estiver errado, mas suponho que precisarei de duas texturas de profundidade para o FBO, que troco entre cada passe de peeling.
jozxyqk

1
@jozxyqk Correto, dois buffers de profundidade são necessários para este procedimento.
Es1024

1

O creme da nata de passagem única não (ou poucas) compromete a transparência no OpenGL é um buffer A. Com o OpenGL moderno, é possível implementar:

http://blog.icare3d.org/2010/06/fast-and-accurate-single-pass-buffer.html

Evita as múltiplas passagens de descamação profunda e não requer classificação onerosa.


3
Idealmente, as respostas devem ser independentes e dependem vitalmente de links externos. Ter links é bom para material suplementar, mas uma resposta não deve consistir apenas em uma palavra-chave. Se você pudesse incluir alguns detalhes sobre o que é um buffer A e como ele funciona, isso melhoraria bastante sua resposta.
Martin Ender
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.