Recursos de renderização no Metro: Exodus c raytracing

imagem

Prefácio


Após o lançamento do último jogo da série Metro, passei várias horas estudando seu trabalho interno e decidi compartilhar algo que poderia parecer interessante do ponto de vista tecnológico. Não conduzirei uma análise detalhada nem estudarei o código desmontado dos shaders, mas mostrarei as decisões de alto nível tomadas pelos desenvolvedores no processo de criação do jogo.

No momento, os desenvolvedores ainda não falaram sobre as técnicas de renderização usadas no jogo. A única fonte oficial de informação é o relatório da GDC , que não pode ser encontrado em nenhum outro lugar da Internet. E isso é irritante, porque o jogo roda em um mecanismo proprietário muito interessante que evoluiu dos jogos anteriores da série Metro. Este é um dos primeiros jogos a usar o DXR .

Nota: este artigo não é uma descrição completa e voltarei a ele se encontrar algo que valha a pena adicionar. Talvez eu tenha perdido alguma coisa, porque alguns aspectos aparecem apenas nas próximas etapas do jogo, ou apenas olhei para os detalhes.

Primeiros passos


Levei vários dias para encontrar um ambiente capaz de trabalhar com este jogo. Depois de testar várias versões do RenderDoc e PIX, decidi estudar os resultados do traçado de raios usando a Nvidia NSight. Eu queria aprender renderização sem raytracing, mas o NSight também me permitiu explorar os detalhes desse recurso, então decidi deixá-lo ativado. No restante da renderização, o PIX é um bom ajuste. As capturas de tela foram tiradas usando os dois aplicativos.

O NSight tem uma desvantagem - ele não suporta salvar a captura em um arquivo, portanto não pude retornar aos quadros que estava estudando.

No começo do meu trabalho, também encontrei outro problema que não tinha nada a ver com aplicativos de depuração de quadros: as funções de rastreamento de raios exigiam a instalação da atualização mais recente do Windows, mas o jogo permitia que elas fossem incluídas nas opções sem instalar a atualização. Nesse caso, a inclusão de funções causou o travamento do jogo na inicialização. A GeForce Experience também não disse nada sobre a necessidade da versão correta do Windows para ativar esses recursos. Esse problema precisa ser resolvido nos dois lados.

Por uma questão de completude, fiz capturas de um jogo rodando com o máximo de parâmetros possíveis, mas sem DLSS.

Análise de quadros



Moldura acabada

Uma breve análise da renderização demonstra um conjunto bastante padrão de funções, com exceção da iluminação global realizada pelo traçado de raios (GI traçado por raios).

Antes de renderizar a imagem, a escala do quadro anterior é reduzida na fila de computação e o brilho médio é calculado.

A fila gráfica começa com a renderização de partículas de distorção (gotículas na câmera), que são aplicadas no estágio de pós-processamento. Então, uma rápida passagem preliminar das profundidades cria uma parte das profundidades em frente ao Gbuffer; parece que só dá um alívio.

O passe GBuffer preenche 4 destinos de renderização de acordo com o diagrama abaixo e também conclui o preenchimento do buffer de profundidade.



1. Alvo no formato RGBA8 com albedo e, possivelmente, Oclusão Ambiental no canal alfa; Em algumas superfícies, parece muito escuro.



2. Alvo no formato RGB10A2 com normais e, possivelmente, uma máscara de dispersão de subsuperfície no canal alfa.



3. Alvo no formato RGBA8 com outros parâmetros de material, provavelmente metalicidade e rugosidade no canal alfa. Curiosamente, os canais RGB neste caso contêm exatamente os mesmos dados.


4. Alvo no formato RG16F com vetores de movimento 2D.

Depois que as profundidades são completamente preenchidas, um buffer de profundidade linear é construído e sua escala diminui. Tudo isso é feito na fila de computação. Na mesma fila, o buffer é preenchido com algo semelhante à iluminação direcional sem usar sombras.

Na fila de gráficos, a GPU rastreia os raios da iluminação global, mas falarei mais sobre isso abaixo.



A fila de computação calcula oclusão do ambiente, reflexões e algo semelhante ao reconhecimento de borda.

Na fila gráfica, um mapa de sombras de quatro estágios é renderizado em um mapa de profundidade de 32 bits do tamanho 6k * 6k. Mais sobre isso abaixo. Após a conclusão do mapa de sombras direcionadas, a resolução da terceira cascata, por razões desconhecidas, diminui para 768 * 768.


No meio do processo de renderização de sombras, há um momento curioso: o atlas de impostores é complementado por alguns objetos antes de renderizar sombras locais da iluminação (sobre quais impostores podem ser encontrados aqui ). Os buffers do impostor e os buffers de sombra de iluminação local também são texturas de 6k * 6k.

Depois que todas as sombras são concluídas, o cálculo da iluminação começa. Essa parte da renderização é bastante incompreensível, porque existem muitas renderizações que executam algumas ações misteriosas e, portanto, requerem estudo adicional.


A renderização da cena termina com objetos iluminados frontalmente (olhos, partículas). Os efeitos visuais são renderizados em um buffer de meia resolução, após o qual são compostos com objetos opacos usando o zoom.


A imagem final é obtida pela correção de tons e cálculo de floração (diminua e aumente a resolução do quadro com correção de tons). Por fim, a interface do usuário é renderizada em um buffer separado e, juntamente com a composição de bloom, é sobreposta na parte superior da cena.

Não encontrei a parte em que a suavização é realizada, então deixarei para mais tarde.

Rastreamento global de raios de luz


Algumas informações sobre a iluminação global realizada pela GI rastreada por raios. Essa estrutura aceleradora cobre uma grande área do mundo do jogo, provavelmente várias centenas de metros, mantendo detalhes muito altos em todos os lugares. Parece estar fluindo de alguma forma. A cena da estrutura de aceleração não coincide com a cena rasterizada, por exemplo, os edifícios na imagem abaixo não são visíveis na forma rasterizada.


Vista superior

Aqui podemos ver quatro peças em torno da posição do jogador. Também é aparente a falta de geometria sendo testada no canal alfa. As árvores têm troncos, mas sem folhagem, sem grama, sem arbustos.


Fechar vista

Na visualização em close, os detalhes e a densidade dos objetos são melhor visualizados. Cada objeto de uma cor diferente tem sua própria estrutura aceleradora no nível inferior. Somente nesta imagem existem várias centenas deles.


Itens do jogador sob os pés

Curiosamente, os itens do jogador também fazem parte da estrutura de aceleração, mas por algum motivo estão localizados sob seus pés.


Esfolamento quebrado?


Esfolamento quebrado de novo?

Alguns dos objetos esfolados parecem quebrados na estrutura acelerada. Um dos problemas observados é esticar a malha (nas pernas da criança). Outro problema leva ao fato de que diferentes partes do personagem com esfolamento estão em posições diferentes. Não há alongamento, mas as partes são separadas uma da outra. Parece que nada disso é visível na iluminação global de rastreamento de raios, ou pelo menos não consegui perceber isso no jogo.


Um grande número de objetos

Em um plano mais geral, você pode ver quantos objetos diferentes existem na estrutura de aceleração. A maioria deles não contribuirá realmente para os resultados dos cálculos da iluminação global. Também é visto aqui que não há esquema LOD. Todos os objetos são adicionados com todos os detalhes. Seria interessante saber se isso tem algum efeito no traçado de raios (eu diria que sim).


LOD ultra-alto, cada escala e switch totalmente modelados

Outra captura de tela mostra um enorme detalhe de objetos, mesmo longe do player. Cada interruptor e cada escala nesta imagem são claramente legíveis, mesmo sem texturas. O local em que movi a câmera para tirar essa captura de tela está localizado a dezenas de metros do player e a eliminação desses detalhes não teria piorado a qualidade da imagem. Talvez a atualização da estrutura de aceleração usando LOD fosse muito cara, mas há uma alta probabilidade de que essa atualização possa ser executada de forma assíncrona. Definitivamente vale a pena explorar esse ponto com mais detalhes.

Renderização de sombras direcionais


A parte principal da renderização de sombras é simples e não requer menção especial, mas há pontos interessantes aqui.


Malhas para as quais é improvável a projeção de sombras


Enorme detalhe nos mapas de sombras


Malhas que parecem usar o buffer de índice incorreto

Parece que, como estruturas em aceleração, a renderização de sombra inclui absolutamente tudo. Existem objetos que quase não contribuem para o mapa de sombras, mas ainda são renderizados. Gostaria de saber se isso acontece por causa da permissão ou se não há uma maneira fácil no mecanismo de excluí-los?

Existem objetos que são difíceis de perceber, mesmo com sombras no espaço da tela. Não demora muito para renderizá-los, mas seria interessante ver se eles podem ser removidos para economizar um pouco de tempo.

Ao estudar a malha, parece que algumas das malhas renderizadas no mapa de sombra têm buffers de índice quebrados, mas após o shader de vértice, eles parecem corretos (os resultados são os mesmos no PIX e no NSight). Este é o melhor exemplo que consegui encontrar, mas está longe de ser o único. Talvez este seja algum tipo de posição de embalagem especial?


As malhas parecem ter pouca aparência

Esfolar parece estar causando problemas não apenas na aceleração de estruturas. Curiosamente, isso não leva a artefatos visíveis na tela.

Parte 2


imagem

Alteração menor



Na parte anterior, escrevi que o terceiro alvo de renderização do buffer GBuffer provavelmente contém metalidade, mas parece que ele realmente contém cores especulares. No começo, não vi nenhuma cor e não entendi por que os três canais RGB contêm os mesmos dados, mas provavelmente porque não havia reflexos de cores na cena. Para esta arma, o buffer contém muito mais cores diferentes.

Também esqueci de adicionar minha textura favorita, que encontrei no processo de pesquisar a renderização do jogo. Definitivamente, vale a pena mencionar, porque demonstra a natureza caótica do desenvolvimento de jogos quando nem sempre é possível limpá-lo.


"Melhore-me!"

Composição de transparência e anti-aliasing


Tentando descobrir como a resolução do buffer de transparência de meio tamanho aumenta e como o jogo executa o antialiasing, notei algo interessante. Eu precisava de uma cena em que houvesse muito mais contraste para que fosse claramente visível o que estava acontecendo. Felizmente, consegui capturar um quadro no qual a arma do jogador se move levemente entre os quadros.


Antes de renderizar transparência

Parece que antes de compor o buffer de transparência, o buffer já contém uma imagem totalmente renderizada e, como não há arestas nítidas nesse quadro, é lógico supor que esses são os dados do quadro anterior.


Após compor a transparência do quadro atual

Ao adicionar transparência ao quadro atual, podemos observar arestas quebradas individuais. Isso aconteceu porque a arma mudou ligeiramente para a direita. Algumas nuvens são tornadas transparentes, mas são cortadas no horizonte (o que é opaco), de modo que a composição não altera o fundo, mas já é renderizada sobre a malha da arma do quadro anterior usando o buffer de profundidade do quadro atual.


Depois de adicionar opacidade ao quadro atual

Após várias chamadas de empate, são realizadas malhas de composição e opacas. Parece não haver razão específica para fazer isso nesta ordem. É lógico compor o buffer de transparência nos dados de objetos opacos do quadro atual, mas isso não acontece e seria interessante saber o porquê.


Após TAA

Depois de concluir o quadro completo, o passe do TAA (Suavização Temporal) suaviza as bordas. Eu já estava interessado nisso antes, porque não via onde a suavização ocorre. Mas pulei isso porque imediatamente após essa chamada de empate, a amostragem para baixo para o passe de início é iniciada e sinto falta dessa chamada de empate.

Reflexo da lente


Normalmente, não quero analisar efeitos individuais, mas há muitas maneiras de implementar o reflexo de lente, por isso fiquei curioso sobre quais desenvolvedores escolheram.


Alargamento da lente na composição pronta

Na maioria dos casos, o reflexo da lente é quase imperceptível, mas esse é um efeito bonito. É difícil mostrar na captura de tela, então não vou me esforçar muito nisso.


Reflexo da lente no buffer de bloom

Após a pesquisa, encontrei uma chamada de desenho que adiciona esse efeito, e acabou sendo uma chamada após o último estágio de aumento da resolução da floração. Nesse buffer, o efeito é muito mais perceptível.


Geometry Lens flare

Se você observar a geometria, o reflexo da lente é bem simples. Pelo menos 6 quadrados estão envolvidos na criação do resultado final na tela, mas não há séries de quadrados menores que se aproximem da posição do sol. Podemos concluir que esta é uma solução bastante padrão, embora alguns desenvolvedores processem o reflexo da lente diretamente na cena do ponto de encontro, enquanto outros calculam o efeito como pós-processamento.

Renderização do terreno


Em todos os jogos de mundo aberto, uma das dificuldades mais interessantes é renderizar terreno. Decidi que poderia parecer interessante estudar esse aspecto, mas, francamente, um pouco decepcionado.


À primeira vista, um fragmento do relevo parece estar sendo executado algum tipo de mosaico. A maneira como o relevo é deformado durante o movimento torna lógico supor que há algum deslocamento adicional. Além disso, em um PC, o jogo usa ativamente o mosaico, por isso seria lógico usá-lo em relevo.


Talvez eu tenha definido os parâmetros errados, mas o jogo renderiza todos os fragmentos do alívio sem mosaico. Para cada fragmento do relevo, ela usa essa grade uniforme de 32 * 32. Também não há LOD.


Observando um fragmento do relevo após o vertex shader, você pode ver que a maioria dos pares de vértices se fundiram para formar uma grade 16 * 16 quase perfeita, com exceção de alguns lugares que exigem mais precisão (provavelmente devido à curvatura do relevo). A deformação mencionada acima provavelmente ocorre devido à leitura das texturas mip do mapa de elevação do relevo quando o relevo está longe da câmera.

Truques de rastreamento de raio


E agora sobre o que todo mundo estava esperando.

Streaming de dados


Um dos aspectos mais interessantes de qualquer implementação de DXR no momento é a maneira como você trabalha com dados. O mais importante é como os dados são carregados nas estruturas em aceleração e como são atualizados. Para testar isso, fiz duas capturas e comparei as estruturas de aceleração no NSight.


O jogador está dentro do navio

Na primeira captura, eu estava dentro de um navio quebrado, visível no meio desta imagem. Apenas os objetos mais próximos são carregados, exceto as grandes rochas na borda do mapa.


O player foi para o canto superior esquerdo desta imagem.

Na segunda captura, afastei-me da borda do mapa e estava mais perto da borda superior esquerda da imagem. A nave e tudo ao seu redor ainda está carregada, mas novos objetos também foram carregados. Curiosamente, não consigo definir nenhuma estrutura de bloco. Os objetos podem ser carregados / removidos da estrutura de aceleração com base na distância e visibilidade (talvez limitando o paralelogramo?). Além disso, a borda superior direita parece mais detalhada, embora tenha se afastado dela. Seria interessante saber mais sobre isso.

Alívio e o que está por baixo


Vários aspectos da implementação do DXR no Metro: Exodus em relação ao terreno podem ser mencionados.


Em primeiro lugar, é interessante que as estruturas em aceleração não contenham malhas de alívio (com exceção de casos especiais). Esses monstros realmente rodam no jogo no chão, mas, a julgar pelos dados do NSight, você pode pensar que eles estão voando. Isso nos coloca uma questão interessante: a implementação da iluminação global pode de alguma forma levar em conta o terreno (possivelmente usando um mapa de altura e material de relevo) ou não.


No momento seguinte, eu nunca teria notado se o alívio estivesse no lugar. Observando o início do nível na estrutura acelerada do NSight, notei algumas malhas sob o relevo.


Os artistas frequentemente, por várias razões, colocam malhas de depuração abaixo do nível, mas geralmente são excluídas antes do lançamento do jogo. Nesse caso, essas malhas não apenas sobreviveram até o lançamento, mas também se tornaram parte da estrutura de aceleração.


Além dos mencionados acima, encontrei outras malhas espalhadas sob o relevo. Basicamente, eles não merecem muita menção, mas este foi muito interessante - este é um personagem logo abaixo do ponto de partida do nível. Ele ainda tem sua própria piscina.


Finalmente, o último elemento curioso da estrutura de aceleração são as malhas unilaterais que olham para fora do nível. A menos que sejam considerados bilaterais, há muito pouca chance de que eles contribuam para a imagem do jogo. Mesmo que as malhas sejam de dois lados, elas estão tão longe da área de jogo que provavelmente apenas esticam a estrutura de aceleração. É interessante ver que eles não são filtrados. Esta imagem também mostra um dos casos especiais da "malha de alívio" no canto inferior direito, entre o trem e o edifício.

Decapitação com esfolamento


Eu já falei sobre os problemas de descascar malhas, mas nesse nível notei outra coisa.


Em primeiro lugar, esse monstro mostra os dois erros em uma imagem, que notei acima. Ainda estou imaginando o que os causou.


Também notei que essas pequenas criaturas, como morcegos, não têm cabeça na estrutura acelerada.


Outro exemplo Observe o buraco onde a cabeça deve estar. Não vi um único caso em que a cabeça estivesse visível.


O mesmo tipo de criatura no modo de rasterização. Observe que a cabeça está claramente visível.


E aqui está a estrutura de arame da cabeça.

Em conclusão


Isso é tudo por hoje. Espero que você tenha gostado desse olhar para o interior do Metro: Exodus.

Continuarei a explorar a renderização do jogo, mas não publicarei novas partes do artigo, a menos que encontre partes especiais que sejam interessantes para as pessoas ou algo que valha a pena compartilhar.

Source: https://habr.com/ru/post/pt447194/


All Articles