Ampliação do pipeline de renderização do Unity 5: Puffers de comando

ARAS PRANCKEVIČIUS Anonymous
Feb 6, 2015|3 Min
Ampliação do pipeline de renderização do Unity 5: Puffers de comando
Esta página da Web foi automaticamente traduzida para sua conveniência. Não podemos garantir a precisão ou a confiabilidade do conteúdo traduzido. Se tiver dúvidas sobre a precisão do conteúdo traduzido, consulte a versão oficial em inglês da página da Web.

No Unity 5 nós estamos adicionando muitos recursos gráficos visíveis para o usuário (novo standard shader, iluminação global em tempo real, sondas de reflexão, novo fluxo de trabalho de mapeamento de luz e assim por diante), mas também trabalhamos na renderização de elementos internos. Além de coisas típicas como "otimizar" (por exemplo, multithread culling de luz) e "fazer mais consistente" (por exemplo, mais consistentemente entre espaços de cores Linear & Gama), também analisamos como torná-lo mais extensível.

Internamente e dentro do grupo de testes beta, discutimos diversas abordagens. Muitas ideias foram lançadas: mais callbacks de script, montagem de pequenos buffers de "aqui está uma lista de coisas para fazer", capacidade de criar pipelines de renderização completos do zero, algum tipo de ferramentas de construção de pipeline de renderização de árvore/gráfico visual e assim por diante. Para o Unity 5, nos concentramos na capacidade de criar buffers de "lista de coisas para fazer", que chamamos de "buffers de comando".

Um buffer de comando em gráficos é uma lista de baixo nível de comandos a executar. Por exemplo, APIs de renderização 3D como Direct3D ou OpenGL normalmente acabam construindo um buffer de comando que é executado pela GPU. O renderizador multi-thread do Unity também cria um buffer de comando entre uma thread de chamada e a "thread do trabalhador" que envia comandos para a API de renderização.



No nosso caso, a ideia é muito semelhante, mas os "comandos" são de nível um pouco maior. Em vez de conter coisas como "configurar o registro interno da GPU X para valorizar Y", os comandos são "Desenhar esta malha com esse material" e assim por diante.

De seus scripts, você pode criar buffers de comando e adicionar comandos de renderização a eles (“set render target, draw mesh, ...”). Depois, esses buffers de comando podem ser definidos para execução em vários pontos durante a renderização de câmera.

Por exemplo, você pode renderizar alguns objetos adicionais em um buffer de sombreamento G diferido depois de concluir todos os objetos regulares. Ou renderize algumas nuvens logo após o skybox ser desenhado, mas antes de qualquer outra coisa. Ou renderize luzes personalizadas (luzes de volume, luzes negativas etc.) em um buffer de luz de sombreamento diferido após todas as luzes regulares serem concluídas. E assim por diante, achamos que há diversas maneiras interessantes de usá-las.

Confira as páginas de CommandBuffer e CameraEvent na documentação da API de scripts.

Fotos ou não aconteceu!

Ok, ok.

Por exemplo, podemos fazer refrações de desfoque:

RenderingCommandBufferBlurryRefraction

Depois que objetos opacos e skybox são renderizados, a imagem atual é copiada em um destino de renderização temporário, desfocada e configurada como uma propriedade global de shader. O shader no objeto de vidro então mostra a imagem desfocada, com as coordenadas UV deslocadas com base em um mapa normal para simular a refração. Isso é semelhante ao que o shader GrabPass faz, exceto que você pode fazer mais coisas personalizadas (neste caso, desfoque).

Outro exemplo de caso de uso: luzes diferidas personalizadas. Aqui estão luzes em forma de esfera e tubo:

RenderingCommandBufferCustomLights

Depois de realizar o passo de luz de sombreamento diferida regular, uma esfera é desenhada para cada luz personalizada, com um shader que computa a iluminação e a adiciona ao buffer de iluminação.

Outro exemplo: decorações diferidas.

RenderingCommandBufferDecals

A ideia é: depois que o G-buffer for feito, desenhe cada “formato” do decalque (uma caixa) e modifique o conteúdo do G-buffer. Isso é muito semelhante ao modo como as luzes são feitas na sombreamento diferido, exceto que em vez de acumular a iluminação, modificamos as texturas do buffer G.

Imagem

Cada decalque é implementado aqui como uma caixa e afeta qualquer geometria dentro do volume da caixa.

Na verdade, aqui está uma pequena pasta de projetos do Unity (5.0 beta 22) que demonstra tudo acima: RenderingCommandBuffers50b22.zip.

Você pode ver que todos os casos acima nem sequer são complexos para implementar — os scripts são cerca de uma centena de linhas de código.

Acho isso empolgante. Mal posso esperar para ver o que vocês fazem com ele!