Parte 1: processamento de vérticesNeste artigo, examinaremos mais de perto o que acontece com o mundo 3D depois que todos os seus vértices forem processados. Novamente teremos que tirar a poeira dos livros de matemática, nos acostumar com a geometria das pirâmides de truncamento e resolver o mistério das perspectivas. Também vamos mergulhar brevemente na física do traçado de raios, iluminação e materiais.
O tópico principal deste artigo é uma importante etapa de renderização, na qual o mundo tridimensional de pontos, segmentos e triângulos se torna uma grade bidimensional de blocos multicoloridos. Muitas vezes, esse processo parece invisível, porque a conversão de 3D para 2D é invisível, em contraste com o processo descrito no
artigo anterior , onde pudemos ver imediatamente a influência dos shaders de vertex e do mosaico. Se você ainda não está pronto para isso, pode começar com o nosso artigo
3D Game Rendering 101 .
Preparando para duas medições
A grande maioria dos leitores lê este site em um monitor ou tela de smartphone completamente plana; mas mesmo se você tiver uma técnica moderna - um monitor curvo, a imagem exibida por ele também consistirá em uma grade plana de pixels multicoloridos. No entanto, quando você joga o novo Call of Mario: Deathduty Battleyard, as imagens parecem tridimensionais. Os objetos se movem pela cena, se tornam maiores ou menores, aproximando-se e se afastando da câmera.
Tomando o
Fallout 4 da Bethesda como exemplo, lançado em 2014, podemos ver facilmente como os picos são processados, criando uma sensação de profundidade e distância; Isso é especialmente visível no modo de estrutura de arame (veja acima).
Se você executar qualquer jogo em 3D nas últimas duas décadas, quase cada um deles executará a mesma sequência de ações para converter o mundo 3D dos vértices em uma matriz de pixels 2D. Essa conversão geralmente é chamada
rasterização , mas é apenas uma das muitas etapas de todo o processo.
Precisamos analisar as diferentes etapas e estudar as técnicas e cálculos usados nelas. Como referência, usaremos a sequência usada no Direct3D. A imagem abaixo mostra o que acontece com cada vértice do mundo:
Pipeline de conversão do Direct3DNo
primeiro artigo [
tradução em Habré] vimos o que está acontecendo no espaço mundial (espaço mundial): aqui, usando vários cálculos matriciais, os vértices são transformados e coloridos. Iremos pular o próximo passo, porque no espaço da câmera apenas os vértices são convertidos e ajustados após o movimento, para que a câmera se torne um ponto de referência.
As etapas a seguir são muito complicadas de ignorar, porque são absolutamente necessárias para a transição do 3D para o 2D - se implementadas corretamente, nosso cérebro olhará para uma tela plana, mas "verá" uma cena com profundidade e escala. Se tudo for feito errado, a imagem será muito estranha!
É tudo sobre perspectiva
O primeiro passo nesta sequência é definir o escopo do ponto de vista da câmera. Para fazer isso, primeiro você precisa definir os ângulos do campo de visão horizontal e vertical - as primeiras mudanças nos jogos, porque as pessoas desenvolveram a visão periférica horizontal melhor que a vertical.
Podemos descobrir isso observando a imagem com o campo de visão de uma pessoa:
Dois cantos do campo de visão (campo de visão, fov) definem a forma da pirâmide de
frustum - uma pirâmide 3D com uma base quadrada emanando da câmera. O primeiro canto define o vov
vertical , o segundo
horizontal ; nós os denotamos pelos símbolos
α e
β . De fato, vemos o mundo não muito assim, mas, do ponto de vista dos cálculos, é muito mais fácil trabalhar com a pirâmide de truncamento do que tentar gerar uma quantidade realista de visibilidade.
Você também precisa especificar mais dois parâmetros - a localização dos
planos de recorte próximo (ou frontal) e distante (traseiro)
(planos de recorte) . O primeiro corta o topo da pirâmide, mas determina essencialmente o quão perto da posição da câmera tudo está desenhado; o último faz o mesmo, mas determina a que distância da câmera as primitivas serão renderizadas.
O tamanho e a localização do plano de truncamento próximo são muito importantes porque se tornam o que é chamado de
viewport . De fato, é isso que vemos no monitor, ou seja, quadro renderizado e, na maioria das APIs gráficas, a janela de exibição é desenhada no canto superior esquerdo. Na imagem abaixo, o ponto (a1, b2) será a origem do plano: a largura e a altura do plano são medidas em relação a ele.
A proporção da janela
de visualização é importante não apenas para exibir o mundo renderizado, mas também para corresponder à proporção do monitor. Por muitos anos, o padrão foi 4: 3 (ou 1,3333 ... em decimal). Hoje, no entanto, a maioria reproduz uma proporção de 16: 9 ou 21: 9, denominada widescreen e ultra widescreen.
As coordenadas de cada vértice no espaço da câmera devem ser transformadas para que todas caibam no plano de truncamento próximo, como mostrado abaixo:
Aparar o lado e a parte superior da pirâmideA transformação é realizada usando outra matriz chamada
matriz de projeção em perspectiva . No exemplo abaixo, para realizar as transformações, usamos os ângulos do escopo e a posição dos planos de truncamento; no entanto, você pode usar o tamanho da viewport.
O vetor de posição do vértice é multiplicado por essa matriz, o que nos fornece um novo conjunto de coordenadas transformadas.
Voila! Agora, todos os vértices são escritos de tal maneira que o mundo de origem é apresentado como uma perspectiva 3D, e as primitivas próximas ao plano de truncamento frontal parecem maiores do que aquelas mais próximas do plano distante.
Embora o tamanho da janela de visualização e os ângulos do ângulo de visualização estejam relacionados, eles podem ser processados individualmente. Em outras palavras, você pode definir a pirâmide de truncamento de forma a obter um plano de truncamento próximo que difira em tamanho e proporção da janela de visualização. Para fazer isso, é necessária uma etapa adicional na cadeia de operações, na qual os vértices no plano de truncamento próximo devem ser transformados novamente para explicar essa diferença.
No entanto, isso pode levar a uma distorção da perspectiva visível. Usando o
jogo Bethesda
Skyrim 2011 como exemplo
, podemos ver como a alteração do ângulo horizontal da região de visibilidade
β , mantendo a mesma proporção da viewport, afeta muito a cena:
Nesta primeira imagem, definimos
β = 75 ° e a cena parece completamente normal. Vamos tentar agora definir
β = 120 °:
Duas diferenças são imediatamente visíveis - primeiro, agora vemos muito mais do lado do nosso "campo de visão"; segundo, os objetos agora parecem muito mais distantes (especialmente as árvores). No entanto, o efeito visual na superfície da água agora parece errado, porque o processo não foi projetado para uma área de visibilidade.
Agora vamos imaginar que nosso personagem tem olhos alienígenas e defina
β = 180 °!
Essa área de visibilidade cria uma cena quase panorâmica, mas você deve pagar por isso com uma distorção grave dos objetos renderizados nas bordas. Isso aconteceu novamente porque os designers do jogo não previram tal situação e não criaram os recursos e efeitos visuais do jogo para esse ângulo de visão (o valor padrão é de aproximadamente 70 °).
Pode parecer que nas imagens acima a câmera se moveu, mas não é assim - a única mudança é modificar a pirâmide de truncamento, que por sua vez alterou as dimensões do plano de truncamento próximo. Em cada imagem, a proporção da janela de visualização permanece a mesma; portanto, a matriz de escala é aplicada aos vértices para que tudo se encaixe nela.
Então você fica ou sai?
Depois de realizar as transformações no estágio de projeção, passamos para o que é chamado de
espaço de clipe . Embora isso seja feito
após a projeção, é mais fácil mostrar o que acontece se realizarmos as operações com antecedência:
Na figura acima, vemos que no pato de borracha, um dos morcegos e parte das árvores, os triângulos estão dentro da pirâmide de truncamento; no entanto, o outro morcego e a árvore mais distante estão fora dos limites da pirâmide de truncamento. Embora os vértices que compõem esses objetos já tenham sido processados, não os veremos na janela de exibição. Isso significa que eles
estão cortados .
Ao
truncar ao longo da pirâmide (recorte de frustum), todas as primitivas fora da pirâmide de truncagem são completamente excluídas e as que ficam nas bordas são convertidas em novas primitivas. O truncamento não melhora muito o desempenho, porque todos esses vértices invisíveis já foram processados antes deste estágio em shaders de vértices etc. Se necessário, toda a etapa de truncamento pode ser completamente ignorada, mas esse recurso não é suportado por todas as APIs (por exemplo, o OpenGL padrão não permitirá que ela seja ignorada, mas isso pode ser feito com a extensão da API).
Vale ressaltar que a posição do plano de truncamento distante nos jogos nem sempre é igual à
distância do
empate , pois este é controlado pelo próprio mecanismo de jogo. O mecanismo também executa
recorte na pirâmide (seleção de frustum) - executa um código que determina se o objeto será desenhado dentro da pirâmide de truncamento e se afetará objetos visíveis; se a resposta for
não , o objeto não é transferido para a renderização. Isso não é o mesmo que recortar frustrum, porque também descarta primitivas fora da pirâmide, mas elas já passaram pelo estágio de processamento de vértices. Ao selecionar, eles não são processados, o que economiza muitos recursos.
Fizemos todas as transformações e truncamentos, e parece que os vértices estão finalmente prontos para o próximo passo na sequência de renderização. Mas, na verdade, não é assim, porque todos os cálculos realizados no estágio de processamento do vértice e nas operações de conversão do espaço mundial para o espaço de truncamento devem ser executados em um sistema de coordenadas uniforme (ou seja, cada vértice tem 4 componentes, não 3) . No entanto, a viewport é totalmente bidimensional, ou seja, a API espera que as informações do vértice contenham apenas os valores de
x, y (embora o valor da profundidade
z seja salvo).
Para se livrar do quarto componente, é executada uma
divisão de perspectiva , na qual cada componente é dividido pelo valor de
w . Esta operação restringe
x e
y ao intervalo de valores possíveis [-1.1] e
z ao intervalo [0.1]. Estes são chamados de
coordenadas de dispositivos normalizados (NDC).
Se você quiser aprender mais sobre o que acabamos de explicar e gostar de matemática, leia o
excelente tutorial sobre este tópico Song Ho An. Agora vamos transformar esses vértices em pixels!
Nós dominamos a rasterização
Como no caso de transformações, examinaremos as regras e processos usados para transformar uma viewport em uma grade de pixels, usando o Direct3D como exemplo. Esta tabela se assemelha a uma planilha do Excel com linhas e colunas, na qual cada célula contém diferentes valores de dados (como cor, valores de profundidade, coordenadas de textura etc.). Geralmente, essa grade é chamada de
imagem rasterizada , e o processo de sua geração é chamado de
rasterização . No artigo
3D rendering 101, simplificamos este procedimento:
A imagem acima dá a impressão de que as primitivas são simplesmente cortadas em pequenos blocos, mas, na realidade, há muito mais operações. O primeiro passo é determinar se o primitivo está voltado para a câmera - por exemplo, na imagem acima com uma pirâmide de truncamento, os primitivos que compõem a parte de trás do coelho cinza não serão visíveis. Portanto, embora estejam presentes na janela de exibição, eles não precisam ser renderizados.
Podemos aproximadamente imaginar como é isso olhando para o diagrama abaixo. O cubo passou por várias transformações para posicionar o modelo 3D no espaço 2D da tela e, do ponto de vista da câmera, algumas das faces do cubo não são visíveis. Se assumirmos que todas as superfícies são opacas, algumas dessas primitivas podem ser ignoradas.
Da esquerda para a direita: espaço mundial> espaço da câmera> espaço de projeção> espaço da telaNo Direct3D, isso pode ser implementado informando ao sistema qual será o
estado de renderização e esta instrução informará que é necessário remover (
cortar ) os lados de cada primitivo olhando para frente ou para trás (ou não cortar completamente, por exemplo, no modo de
estrutura de arame ) . Mas como ela sabe de que lado está olhando para frente ou para trás? Quando examinamos a
matemática do processamento de vértices , vimos que triângulos (ou melhor, vértices) possuem vetores normais informando ao sistema em qual direção ele está olhando. Graças a essas informações, você pode executar uma verificação simples e, se o primitivo falhar, ele será removido da cadeia de renderização.
Agora é hora de aplicar a grade de pixels. Esse é novamente um processo inesperadamente complexo, porque o sistema precisa entender se o pixel está dentro do primitivo - completamente, parcialmente ou não existe. Para fazer isso, o processo de
teste de cobertura é realizado. A figura abaixo mostra como os triângulos são rasterizados no Direct3D 11:
A regra é bastante simples: um pixel é considerado dentro do triângulo se o centro do pixel passar em uma verificação, que a Microsoft chama de
regra "superior esquerda" . "Topo" refere-se à verificação da linha horizontal; o centro do pixel deve estar nesta linha. "Esquerda" refere-se a linhas não horizontais, e o centro do pixel deve estar à esquerda dessa linha. Existem outras regras relacionadas a não-primitivas, por exemplo, segmentos e pontos simples e, ao usar a
multisampling , adicionais se condições aparecerem nas regras.
Se você olhar atentamente a documentação da Microsoft, poderá ver que as formas criadas pelos pixels não são muito semelhantes às primitivas originais. Isso ocorre porque os pixels são muito grandes para criar um triângulo realista - a imagem de bitmap não contém dados suficientes sobre os objetos originais, o que causa um fenômeno chamado
alias .
Vejamos o aliasing com um exemplo do
UL Benchmark 3DMark03 :
Rasterização de 720 x 480 pixelsNa primeira imagem, a imagem rasterizada tem uma resolução muito baixa - 720 por 480 pixels. O aliasing é claramente visível nos trilhos e nas sombras projetadas pelas armas do soldado superior. Compare isso com o resultado obtido durante a rasterização com um aumento de 24 vezes no número de pixels:
Rasterização 3840 x 2160 pixelsAqui vemos que o apelido no parapeito e a sombra desapareceu completamente. Parece que você sempre deve usar um bitmap grande, mas o tamanho da grade deve ser suportado pelo monitor no qual o quadro será exibido. E, levando em consideração o fato de que todos esses pixels precisam ser processados, é óbvio que haverá uma diminuição no desempenho.
A amostragem múltipla pode ajudar aqui. Veja como funciona no Direct3D:
Em vez de verificar se o centro do pixel corresponde às regras de rasterização, vários pontos dentro de cada pixel (chamados amostras de subpixel ou subamostras) são
verificados e, se alguns deles satisfazem os requisitos, fazem parte da figura. Pode parecer que não há benefício e o aliasing é aprimorado, mas ao usar a multisampling, as informações sobre quais subamostras são cobertas pela primitiva e os resultados do processamento de pixels são armazenadas em um buffer na memória.
Esse buffer é então usado para misturar essas subamostras e pixels para que as bordas da primitiva sejam menos rasgadas. Examinaremos o alias em outro artigo em mais detalhes, mas, por enquanto, essas informações são suficientes para entendermos o que a multisampling pode fazer quando usada para rasterizar muito poucos pixels:
Como você pode ver, a quantidade de alias nas bordas de diferentes formas diminuiu significativamente. Definitivamente, a rasterização de resolução mais alta é definitivamente melhor, mas a degradação do desempenho pode solicitar que você use multisampling.
Também durante a rasterização, um
teste de oclusão é realizado. É necessário porque a janela de visualização será preenchida com primitivas sobrepostas - por exemplo, na figura acima, os triângulos prospectivos que compõem o soldado em primeiro plano se sobrepõem aos mesmos triângulos de outro soldado. Além de verificar se a primitiva cobre um pixel, você também pode comparar as profundidades relativas e, se uma superfície estiver atrás de outra, ela deverá ser removida do processo de renderização restante.
No entanto, se o primitivo próximo for transparente, o primitivo distante permanecerá visível, embora não seja aprovado no teste de sobreposição. É por isso que quase todos os mecanismos 3D realizam verificações de sobreposição
antes de enviar dados para a GPU e, em vez disso, criam algo chamado
buffer z , que faz parte do processo de renderização. Aqui, o quadro é criado da maneira usual, mas em vez de salvar as cores de pixel prontas na memória, a GPU salva apenas os valores de profundidade. Posteriormente, eles podem ser usados em shaders para verificar a visibilidade e com grande controle e precisão dos aspectos relacionados a objetos sobrepostos.
Na imagem mostrada acima, quanto mais escura a cor do pixel, mais próximo o assunto da câmera.
O quadro é renderizado uma vez para criar um buffer z e, em seguida, renderizado novamente, mas desta vez durante o processamento dos pixels, um sombreador é ativado, verificando se há valores no buffer z. Se estiver invisível, a cor do pixel não será gravada no buffer do quadro final.Até agora, nosso último passo principal será a interpolação dos atributos do vértice - no esquema simplificado original, o primitivo era um triângulo completo, mas não esqueça que a janela de visualização é preenchida apenas com os cantos das figuras, e não com as próprias figuras. Ou seja, o sistema deve determinar qual cor, profundidade e textura da primitiva deve estar entre os vértices, e essa operação é chamada de interpolação . Como você deve ter adivinhado, esse é outro cálculo, e não é tão simples.Apesar de a tela rasterizada ser apresentada em 2D, as estruturas dentro dela representam uma perspectiva 3D. Se as linhas fossem realmente bidimensionais, poderíamos usar uma equação linear simples para calcular cores e outras coisas , porque passamos de um vértice para outro. Porém, devido ao aspecto 3D da cena, a interpolação deve levar essa perspectiva em consideração; Para saber mais sobre esse processo, leia o excelente artigo de Simon Young .Assim, a tarefa está concluída - para que o mundo 3D dos vértices se transforme em uma grade 2D de blocos coloridos. Mas ainda não terminamos.Frente para trás (com algumas exceções)
Antes de terminarmos de considerar a rasterização, precisamos falar sobre a ordem da sequência de renderização. Não estamos falando sobre o estágio em que, por exemplo, o mosaico aparece na sequência de processamento; queremos dizer a ordem na qual as primitivas são processadas. Os objetos geralmente são processados na ordem em que estão no buffer de índice (um bloco de memória informando ao sistema como os vértices são agrupados) e isso pode afetar significativamente a maneira como objetos e efeitos transparentes são processados.A razão para isso é que as primitivas são processadas uma de cada vez e, se você renderizar as que estão à frente, todas as pessoas atrás delas serão invisíveis (é aqui que o abate por oclusão entra em cena) e podem ser descartadas do processo (ajudando a economizar desempenho). Isso geralmente é chamado de renderização front-to-back e, para esse processo, o buffer de índice deve ser ordenado dessa maneira.No entanto, se algumas dessas primitivas forem transparentes na frente da câmera, a renderização de frente para trás levará à perda de objetos atrás de transparentes. Uma solução é renderizar de trás para a frente, na qual primitivos e efeitos transparentes são calculados por último.Da esquerda para a direita: a ordem na cena, renderização de frente para trás, renderização de trás para frenteOu seja, em todos os jogos modernos, a renderização é executada de trás para frente? Seja qual for o caso - não esqueça que a renderização de cada primitivo individual levará a uma diminuição muito maior no desempenho em comparação com a renderização apenas do que vemos. Existem outras maneiras de processar objetos transparentes, mas, no caso geral, não existe uma solução ideal adequada para qualquer sistema, e cada situação precisa ser considerada separadamente.De fato, isso nos permite entender os principais prós e contras da rasterização - em equipamentos modernos, é um processo rápido e eficiente, mas ainda é um reflexo aproximado do que vemos. No mundo real, todo objeto pode absorver, refletir e às vezes refratar a luz, e tudo isso afeta a aparência final da cena exibida. Dividindo o mundo em primitivos e renderizando apenas partes deles, chegamos rápido. mas um resultado muito difícil.Agora, se houvesse alguma outra maneira ...Outra maneira é: traçado de raios!
Quase cinquenta anos atrás, um cientista da computação chamado Arthur Eppel trabalhou em um sistema para renderizar imagens em um computador no qual um raio de luz era emitido da câmera em uma linha reta até colidir com um objeto. Após a colisão, as propriedades do material (sua cor, refletividade etc.) alteraram o brilho do feixe de luz. Para cada pixel na imagem renderizada, havia um raio emitido, e o algoritmo executou uma cadeia de cálculos para determinar a cor do pixel. O processo de Eppel é chamado de fundição por raios .Cerca de dez anos depois, outro cientista chamado John Whited , , , , . , ; , , .
(ray tracing) ( ,
, , )
.
Na imagem acima, você pode entender como o algoritmo Whited funciona. Para cada pixel no quadro, um feixe é emitido da câmera e se move até atingir a superfície. Neste exemplo, a superfície é translúcida, para que a luz possa ser refletida e refratada através dela. Nos dois casos, são gerados raios secundários que viajam até colidirem com a superfície. Novos raios secundários também são gerados para explicar a cor das fontes de luz e as sombras que elas criam.A natureza recursiva do processo é que raios secundários podem ser gerados toda vez que um novo raio emitido cruza a superfície. Isso pode ficar fora de controle rapidamente, portanto o número de raios secundários gerados é sempre limitado. Após a conclusão do caminho do feixe, a cor em cada ponto final é calculada com base nas propriedades do material dessa superfície. Esse valor é então transmitido ao longo do raio anterior, alterando a cor dessa superfície, e assim por diante, até chegarmos ao ponto inicial do raio primário, ou seja, o pixel no quadro.Esse sistema pode ser extremamente complexo e até cenas simples podem gerar uma grande quantidade de computação. Felizmente, existem truques que simplificam o trabalho - em primeiro lugar, você pode usar equipamentos projetados especificamente para acelerar essas operações matemáticas, semelhante ao que acontece com a matemática matricial no processamento de vértices (mais sobre isso mais adiante). Outro truque importante é uma tentativa de acelerar o processo de determinação do objeto no qual o raio caiu e o local exato de sua interseção - se o objeto consiste em muitos triângulos, essa tarefa pode ser surpreendentemente difícil:Fonte: Rastreio de raios em tempo real com a Nvidia RTX.Emvez de verificar cada triângulo individual em cada objeto, é gerada uma lista de volumes delimitadores (BVs) antes de realizar o rastreio de raios - esses são paralelepípedos comuns que descrevem um objeto. Para várias estruturas dentro do objeto, volumes delimitadores menores são criados ciclicamente.Por exemplo, o primeiro BV será o coelho inteiro. O próximo casal descreverá sua cabeça, pernas, corpo, cauda, etc; cada volume, por sua vez, será outra coleção de volumes para estruturas menores da cabeça, corpo etc., e o último nível de volume conterá um pequeno número de triângulos para verificação. Todos esses volumes são geralmente organizados em uma lista ordenada (chamada hierarquia BV)ou BVH); graças a isso, o sistema verifica uma quantidade relativamente pequena de BV a cada vez:Embora o uso do BVH, estritamente falando, não acelere o rastreamento de raios, gerando uma hierarquia e o algoritmo de pesquisa subsequente necessário no caso geral é muito mais rápido do que verificar a interseção de um raio com um dos milhões de triângulos no mundo 3D.Atualmente, programas como o Blender e os raios POV usam o traçado de raios com algoritmos adicionais (como rastreamento de fótons e radiosidade) para gerar imagens muito realistas:A pergunta óbvia pode surgir: se o traçado de raios é tão bom, por que não é usado em todos os lugares? A resposta está em duas áreas: primeiro, até um simples traçado de raio cria milhões de raios que precisam ser calculados repetidamente. O sistema começa com apenas um feixe por pixel da tela, ou seja, com uma resolução de 800 x 600, gera 480.000 raios primários e, em seguida, cada um deles gera muitos raios secundários. Esse é um trabalho muito difícil, mesmo para PCs modernos. O segundo problema é que o traçado simples de raios não é muito realista e, para sua implementação adequada, é necessário um monte de equações muito complexas adicionais.Mesmo com equipamentos modernos, a quantidade de trabalho em jogos em 3D é inatingível para implementação em tempo real. Na renderização em 3D 101vimos que uma referência de rastreamento de raios leva dezenas de segundos para criar uma única imagem de baixa resolução.Como o primeiro Wolfenstein 3D realizou o lançamento de raios em 1992 e por que jogos como Battlefield V e Metro Exodus , lançados em 2019, oferecem recursos de rastreamento de raios? Eles realizam rasterização ou rastreamento de raios? Pouco a pouco de ambos.Uma abordagem híbrida para o presente e o futuro
Em março de 2018, a Microsoft anunciou o lançamento de uma nova extensão de API para o Direct3D 12 chamada DXR (DirectX Raytracing). Era um novo pipeline gráfico que complementa os pipelines de rasterização e computação padrão. Funcionalidade adicional foi fornecida pela adição de shaders, estruturas de dados, etc., mas não exigia suporte de hardware, exceto o que já era necessário para o Direct3D 12.Na mesma Conferência de desenvolvedores de jogos na qual a
Microsoft falou sobre DXR , a Electronic Arts falou sobre seu
Projeto Pica Pica - um experimento com um mecanismo 3D usando DXR. A empresa mostrou que o traçado de raios pode ser usado, mas não para renderizar todo o quadro. A maior parte do trabalho utiliza técnicas tradicionais de rasterização e shaders computacionais, enquanto o DXR é usado em áreas específicas. Ou seja, o número de raios gerados é muito menor do que seria para toda a cena.
Essa abordagem híbrida foi usada no passado, embora em menor grau. Por exemplo, o Wolfenstein 3D
usou a conversão de raios para renderizar um quadro, mas isso foi feito com uma coluna de feixe por pixel, não um pixel. Ainda pode parecer impressionante, a menos que você se lembre de que o jogo funcionou com uma resolução de 640 x 480 [aprox. transl .: na verdade 320 x 200], ou seja, ao mesmo tempo, não foram emitidos mais de 640 raios.
As placas gráficas do início de 2018, como a AMD Radeon RX 580 ou a Nvidia GeForce 1080 Ti, atendiam aos requisitos de DXR, mas mesmo com suas capacidades de computação, havia preocupações de que elas não seriam poderosas o suficiente para tornar o DXR significativo.
A situação mudou em agosto de 2018, quando a Nvidia lançou sua mais recente arquitetura de GPU
, codinome Turing . A característica mais importante desse chip foi o surgimento dos chamados RT Cores: blocos lógicos separados para acelerar os cálculos da interseção raio-triângulo e a passagem da hierarquia dos volumes delimitadores (BVH). Esses dois processos são procedimentos demorados para determinar os pontos de interação da luz com triângulos que compõem os objetos da cena. Como os RT Cores eram unidades de processador Turing exclusivas, o acesso a eles só podia ser feito por meio da API proprietária da Nvidia.
O primeiro jogo a suportar esse recurso foi o Battlefield V. da EA
Quando testamos o DXR , ficamos impressionados com a melhoria nos reflexos na água, na grama e nos metais, bem como com uma diminuição correspondente no desempenho:
Para ser sincero, os patches subseqüentes melhoraram a situação, mas ainda havia uma diminuição na velocidade de renderização de quadros (e ainda é). Em 2019, havia outros jogos que suportam essa API e executam o traçado de raios para partes individuais do quadro. Testamos o
Metro Exodus e o
Shadow of the Tomb Raider , diante da mesma situação - com o uso ativo do DXR reduz significativamente a taxa de quadros.
Na mesma época, os UL Benchmarks
anunciaram a criação de um teste de função DXR para o
3DMark :
O DXR é usado na placa de vídeo Nvidia Titan X (Pascal) - sim, o resultado é 8 fpsNo entanto, um estudo de jogos com suporte a DXR e o teste 3DMark mostraram que o traçado de raios, mesmo em 2019, continua sendo uma tarefa muito difícil para a GPU, mesmo a um preço de mais de US $ 1.000. Isso significa que não temos alternativas reais à rasterização?
Os recursos progressivos das tecnologias de gráficos 3D para consumidores costumam ser muito caros, e seu suporte inicial a novos recursos da API pode ser bastante fragmentado ou lento (como descobrimos
ao testar o Max Payne 3 em diferentes versões do Direct3D em 2012). O último problema geralmente surge porque os desenvolvedores de jogos tentam incorporar o máximo de recursos modernos em seus produtos, às vezes sem experiência suficiente.
No entanto, sombreadores de vértice e pixel, mosaico, renderização HDR e oclusão ambiental do espaço na tela também foram técnicas caras, adequadas apenas para GPUs poderosas, e agora são o padrão para jogos e muitas placas gráficas são suportadas. O mesmo acontecerá com o traçado de raios; com o tempo, ele simplesmente se transformará em outro parâmetro de detalhe, ativado por padrão para a maioria dos jogadores.
Em conclusão
Então, chegamos ao final da segunda parte da análise, na qual examinamos mais profundamente o mundo dos gráficos 3D. Aprendemos como os topos dos mundos e modelos são transferidos de três dimensões e se transformam em uma imagem 2D plana. Vimos que precisamos levar em consideração o escopo e perceber qual o impacto que ele tem. Examinamos o processo de conversão desses verines em pixels e terminamos com uma breve olhada em alternativas ao processo de rasterização tradicional.
Como no artigo anterior, dificilmente poderíamos revelar todos os tópicos e perdemos alguns detalhes - no final, este não é um livro! Mas esperamos que você tenha aprendido algo novo e agora respeite o trabalho de programadores e engenheiros que usaram a computação e a ciência para implementar tudo isso em seus jogos 3D favoritos.