Qual é a troca de desempenho entre renderização adiada e adiada?

9

A renderização direta é o processo de calcular um valor de radiação para um fragmento de superfície diretamente da geometria de entrada e das informações de iluminação. A renderização adiada divide esse processo em duas etapas: primeiro produzindo um buffer de espaço na tela contendo propriedades do material (um buffer de geometria ou buffer G) criado por rasterização da geometria de entrada e, em seguida, produzindo um valor de radiação para cada pixel combinando o G- buffer com informações de iluminação.

A renderização diferida é frequentemente apresentada como uma otimização da renderização direta. Uma explicação é que a iluminação é bastante cara e, se houver excesso de pixels, você estará iluminando pixels que nunca serão vistos na tela, enquanto que, se você armazenar as propriedades do material em um buffer G e depois iluminar, estará iluminando apenas um pixel que realmente aparecem na tela. Isso é realmente uma vantagem do diferido, já que você também pode fazer um pré-passe de profundidade e, em seguida, um passe de renderização direta com o teste de profundidade definido como D3D11_COMPARISON_EQUALou GL_EQUALequivalente?

A renderização adiada também tem o potencial de agendar melhor na GPU. Dividir uma grande frente de onda / deformação em uma frente de onda de geometria menor e frentes de onda de iluminação menores melhoram mais tarde a ocupação (mais frentes de onda em vôo simultaneamente). Mas você também acaba usando muito mais largura de banda (gravando um grande número de canais no buffer G e lendo-os novamente durante a iluminação). Obviamente, as especificidades aqui dependem muito da sua GPU, mas quais são os princípios gerais?

Existem outras considerações práticas de desempenho ao decidir entre renderização adiada e adiada? (Suponha que possamos usar variações de cada técnica, se necessário: ou seja, podemos comparar lado a lado com o lado diferido também.)

John Calsbeek
fonte

Respostas:

11

É possível evitar o excesso de objetos opacos, mesmo com a renderização direta, realizando um pré-passe de profundidade e usando essas informações para rejeitar qualquer pixel que não seja realmente visível. No entanto, dependendo do custo de vértice da sua cena, um pré-passe de profundidade pode adicionar uma quantidade inaceitável de sobrecarga de desempenho. Além disso, a renderização usando o pipeline de sombreamento de pixels da GPU significa que você não paga um custo por pixel renderizado, mas sim um custo por quad de 2x2 pixel renderizado. Portanto, mesmo fazer uma pré-passagem de profundidade ainda faz com que as bordas dos triângulos desperdiçam pixels de sombreamento do trabalho que serão descartados.

O agendamento da GPU é um tópico complexo, e a troca entre encaminhamento e adiamento não se resume simplesmente a "corre mais rápido, mas usa mais largura de banda". Se você tem duas operações igualmente baratas executadas em sequência e cada uma usa o mesmo número de recursos, não há razão para dividi-las em shaders separados: duas pequenas frentes de onda em que cada uma usa recursos X não funcionam fundamentalmente melhor do que uma única frente de onda mais longa que também usa recursos X. Porém, se você tiver uma operação barata e uma operação cara para executar em sequência, poderá se dividir em shaders separados: o shader geralmente reservará a quantidade máxima de recursos que poderá usar a qualquer momento. Isto' É possível que a renderização direta possa não ser capaz de usar toda a largura de banda da sua GPU, porque há tão poucas frentes de onda em andamento que ele não pode emitir operações suficientes para saturar a largura de banda. Mas se vocêComo a largura de banda é limitada, pode não haver vantagem na renderização adiada (pois provavelmente usará mais largura de banda).

Uma preocupação adicional de desempenho é que a renderização direta suporta diferentes tipos de material (diferentes BRDFs, digamos) simplesmente usando um sombreador diferente para esse objeto. Um renderizador diferido direto precisa manipular diferentes tipos de materiais de uma maneira diferente (potencialmente uma ramificação no shader), pois o trabalho não é mais agrupado em deformações / frentes de onda de forma coerente, dependendo do objeto que está sendo renderizado. Isso pode ser mitigado com um renderizador lado a lado - se apenas áreas específicas da tela usarem um tipo de material alternativo (por exemplo, para cabelos), você poderá usar a variação do sombreador com uma ramificação do tipo de material apenas para ladrilhos que contenham pixels com esse material .

John Calsbeek
fonte