Ponto V!

Home XNA Shaders Deferred Shading Parte 2
Thiago Dias Pastor
Deferred Shading Parte 2Imprimir
Escrito por Thiago Dias Pastor

Olá Pessoal !!! Neste post irei dar prosseguimento ao artigo sobre deferred shading. É imprescindível ter lido a parte 1 e os tutorias citados no texto anterior (em especial esse e esse).

Tendências do Deferred Shading

Placas de vídeo modernas realizam operações matemáticas em uma velocidade superior a que acessam memória de vídeo (leitura de textura). Este fator somado a expectativa de que em um futuro esta diferença fique ainda maior (a história da evolução das GPUs mostra essa tendência), indica que a técnica deferred shading (que estruturalmente depende muito de acesso a texturas) não é uma solução para iluminação a longo prazo.

Esta técnica está cada vez mais sendo usada em jogos eletrônicos, principalmente pela capacidade de adicionar muitas luzes dinâmicas e reduzir a complexidade de desenvolvimento dos shaders. A Sony Computer Entertainment tem vários títulos usando deferred shading como Guerilla Games's Killzone 2, Media Molecule's LittleBigPlanet, e Sucker Punch Productions' inFamous. Outros jogos que usam deferred shading são GSC Game World's Stalker: Shadow of Chernobyl, Electronic Arts' Dead Space, Tabula Rasa, Realtime Worlds' Crackdown, Rockstar Games' Grand Theft Auto IV e Blizzard Entertainment's StarCraft II . A CryEngine 3 implementa deferred lightining.

Comparação com Forward Rendering

O Deferred rendering mudou fundamentalmente a maneira de se lidar com luzes dinâmicas, e isto alterou profundamente a forma de enxergar as características de medidas de desempenho dos renders.

Em termos apenas de desempenho, não é possível afirmar que o deferred shading é superior ao Forward.

Conforme citado anteriormente, a arquitetura Forward Rendering se divide em duas classes menores chamadas de Single Light Pass e Multi Pass Light. Tem-se a seguir uma descrição algorítmica básica do funcionamento de cada uma delas:

Single Pass MultiLight

Para cada objeto da cena, em um mesmo shader deve-se aplicar a lógica de renderização, processamento de geometria, de luz, de efeitos (como sombra) e produzir a imagem projetada na tela.

As principais desvantagens são:

  • Superfícies escondidas são consideradas ao aplicar iluminação (Computação inútil).
  • A complexidade do shader cresce exponencialmente com o número de luzes adicionadas.
  • O número de shaders crescer exponencialmente, uma vez que para cada técnica ou efeito diferente, vários novos shaders terão que ser criado.
  • Dificuldade de gerenciar materiais (ao mudar um comportamento de um material, temos que reescrever completamente um shader, entretanto, temos que copiar a lógica de renderização e efeitos do shader original. Logo temos várias copias muito parecidas de um código em lugares diferentes, dificultando a manutenção e a extensibilidade).

Multi Pass MultiLight

Para cada Luz na cena, renderizar a cena do ponto de vista dela e agregar ao valor do frame Buffer.

Como desvantagens têm-se:

  • Superfícies escondidas são consideradas ao aplicar iluminação (Computação inútil).
  • Grande número de batches (número de chamadas para a placa de vídeo com parâmetros diferentes - pelo menos uma para objeto a cada luz diferente).
  • Muito trabalho repetido (Para cada luz, teremos que calcular todas as transformações (que não mudam) entre as luzes - não é possível cachear resultados intermediários uma vez que não se consegue retirar resultados intermediários calculados na GPU).

Estes resultados podem ser sumarizados da seguinte maneira:

  • Os cálculos de iluminação são feitos no pixel shader e executados para a geometria rasterizada. Mesmo assumindo que não há redesenho (enviar para a GPU geometria que esta oclusa) para os objetos opacos a performance pode ser negativamente afetada pela rasterização de vários triângulos bem pequenos que ocupariam menos que um pixel na tela. As equações de iluminação serão calculadas diversas vezes para pixels que não contribuirão para a imagem final. Normalmente usa-se uma técnica chamada "early Z pass" para diminuir este efeito (pelo menos na parte de redesenho de parte oclusas), mas ela adiciona uma custo, e ele é proporcional a geometria da cena.
  • Geralmente o culling de visibilidade da luz (determiner quais pixels precisam ser iluminados por quais luzes) pode ser feito apenas dentro de um batch (na granularidade de uma chamada de desenho para a GPU), e isto normalmente significa que esta determinação só pode ser feita para cada mesh de cada vez (e o resultado não é compartilhado). Então, tenta-se descobrir quais luzes ao aplicar um shader em um objeto e tem-se apenas como escolhas do tipo "Aplicar ou não aplicar um luz em determinado mesh". Isto significa que todos ou nenhum dos pixels gerados a partir do mesh deverão efetuar os cálculos de iluminação. Novamente acarretando em operações desnecessárias que impactam no desempenho.

Discussão a respeito de performance em Deferred Rendering

  • O cálculo de luzes é realizado em seu próprio passo, completamente desacoplado da geometria. Isto significa que a eficiência do pixel shader não está mais relacionado com a complexidade da geometria da cena (não ocorre os dois problemas citados anteriormente).
  • Uma vez que o cálculo de luzes é feito em coordenadas de projeção (Screen Space), o culling de visibilidade de cada luz pode ser feito usando geometrias que aproximam a área de efeito da luz (conforme discutido anteriormente, ao invés de processar um quad inteiro no caso de uma Point light, envia-se apenas uma esfera e calcula-se sua projeção, por fim calcula-se a iluminação apenas na área projetada). Isto torna possível criar luzes bem pequenas, uma vez que não existe a preocupação com sua área de atuação.
  • Para a implementação clássica de deferred rendering, precisa-se guardar todas as propriedades dos materiais no GBuffer (que depois são recuperadas no passo de iluminação). Isto faz a técnica gastar bastante largura de banda e memória de vídeo. Isto também a faz incompatível com MSAA em DirectX 9.c. (forçando uma solução "manual" para o Aliasing através de Post Processing). Qualquer cena, independentemente da complexidade da geometria e do número de luzes, precisa passar pelas quatro fases do deferred a cada frame, a geração destes bufferes adicionam um overhead que não é desprezível e em algumas configurações de cenas pode ser interessante utilizar-se da arquitetura forward.

Estado da arte e Desafios

DirectX 10

O DirectX 10 trouxe inúmeras novidades que facilitaram o uso do deferred shading. As principais são:

  • É possivel criar um "read-only" depth stencil view. Isto é importante se quisermos ler do depth buffer diretamente para reconstruir a posicao 3D (sem criar o Depth do GBuffer) No DirectX 10,nao é possivel ter um depth stencil buffer “setado” para depth testing e ao mesmo tempo ler dele, com Dx 11 é possivel.
  • É possivel rodar o pixel shaders em uma frequencia por amostra (per-sample). Util se quisermos ligar MSAA junto com deferred shading,já que é possivel guarder informacao de iluminacao emu ma resolucao por amostra. (feature do Dx 10.1)
  • É possivel acessar o SV_Coverage (pixel coverage) como variavel de entrada do pixel shader. Isto ajuda a evitarmos calcular o shading de amostras onde o depth/stencil ou o coverage test falharam (quando o MSAA estiver ativo).
  • Temos MSAA nos depth buffers. (feature do 10.1)
  • Possibilidade de usar o compute shaders para realizar os calculus de iluminacao em um grid fixo (veja a engine Frosbite). Vejam este exemplo.
Anti-Aliasing

MSAA ainda é um grande desafio, porém a chegada do DirectX 11 resolveu a maioria dos problemas. Os principais benefícios são acesso as subsamples dos RenderTargets Color e Depth, acesso a informações sobre pixel coverage como entrada do pixel shader e aumento da freqüência em que o pixel shader roda.

Com estas novas funcionalidades é possível utilizar MSAA sem artefatos e sem grandes quedas de performance. Entretanto o consumo de banda e memória de vídeo não escalam para GBuffer em grandes resoluções (Full HD com profundidade de 64 bits para cada textura do GBuffer).

Para aqueles mais avançados, procurem por MLAA (implementado na Ploobsengine =P) e FXAA.

Transparência

Transparência continua sendo um grande problema, a técnica Depth Peeling certamente funciona mais ainda é muito cara computacionalmente, normalmente utiliza-se um passo em Forward Rendering para tratar de transparência (A PloobsEngine usa esta segunda abordagem).

Para os mais avançados, é possível em DX 11 resolver este problema de uma maneira bastante “elegante”. Procure por UAV, Unordered Acess View.

Materiais Complexos

Devido ao limite de tamanho do GBuffer, equações de iluminação que utilizam diversos parâmetros não podem ser utilizadas. Nestes casos, é necessário um passo Forward para implementar esses materiais.

image

Pontos positivos e negativos de Deferred Shading

O Deferred Rendering combina técnicas tradicionais de renderização com as vantagens das técnicas de processamento de imagem. Ele separa completamente o passo de iluminação da renderização tornando-o simplesmente uma técnica de processamento de imagens. Antes de decidir pelo uso de uma arquitetura Forward ou Deferred deve-se ter em mente todas as vantagens e desvantagens de cada técnica e avaliar se o ambiente a ser construído se beneficia da abordagem escolhida.

As principais vantagens de Deferred Shading discutidas durante o capítulo inteiro estão resumidos a seguir:

  • O custo de cada luz é proporcional a área que elas ocupam na tela.
  • Todas as luzes são calculadas per Pixel e todas as superfícies são tonalizadas igualmente.
  • Luzes podem estar oclusas como qualquer outro objeto, possibilitando Culling.
  • Possibilita a adição de um grande número de luzes dinâmicas em uma cena.
  • Técnicas de sombreamento são facilmente aplicáveis.
  • Cálculo de iluminação aplicada somente uma vez em cada primitiva (não há mais cálculos desnecessários).
  • Clara separação entre renderização e iluminação facilitando o gerenciamento da aplicação (em termos de manutenção e expansão).
  • Efeitos de PostEffect como SSAO, Depth of Field e Fog são facilmente implementados.

O mesmo para as desvantagens:

  • Alto uso de memória de vídeo
  • Alto consumo de banda
  • Implementação de equações de iluminação são mais difíceis
  • Pouca flexibilidade para adição de novos materiais
  • Requer Hardwares mais potentes (suporte a MRTs e preferencialmente a Shader Model 3.0)
  • Dificuldade em implementar transparência e materiais complexos.
  • Não se beneficia de antialising MSAA por hardware (em DirectX 9)

Nos próximos tutoriais irei entrar a fundo na implementação desta técnica que fizemos para a PloobsEngine. Como sempre, qualquer duvida deixem nos comentários abaixo.

Referências Adicionais


Comentários (0)
Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter