Livro dos Mortos: Truques de Quixel, vento, criação de cenas e otimização de conteúdo

Nesta série de blogs, abordaremos todos os aspectos da criação de nossa demonstração Livro dos Mortos. Hoje, vamos nos concentrar em nossa parceria com a Quixel, nosso sistema de vento, construção de cenas e truques de otimização de conteúdo. Este é o quarto blog de nossa série "Making Of". Caso tenha perdido, dê uma olhada nas três últimas postagens que abordam o processo criativo de personagens, arte conceitual e ativos de fotogrametria, árvores e efeitos visuais no Book of the Dead.
Hi! Meu nome é Julien Heijmans, trabalho como artista de ambiente como parte da equipe de demonstração da Unity. Só entrei na Unity no ano passado, mas tenho cerca de 7 anos de experiência no setor de videogames. Esta postagem do blog fornecerá algumas informações sobre a produção do Book of the Dead do meu ponto de vista, o ponto de vista de um criador de conteúdo e de um artista de ambiente.
Sou novo no trabalho de ativos de fotogrametria, mas me lembro claramente do dia em que a Quixel anunciou a criação do Megascans há vários anos. Desde então, estou ansioso para ter a oportunidade de trabalhar com seus ativos. Entrar para a equipe de demonstração da Unity fez com que isso acontecesse, pois comecei a trabalhar em The Book of the Dead.
Se quiser começar a experimentar as ferramentas discutidas neste blog, você pode fazer o download do Book of the Dead: Projeto ambiental agora.

Quando entrei no projeto, percebi que não estávamos apenas usando assets da biblioteca Megascans da Quixel, mas que a Unity e a Quixel estavam fazendo uma parceria para a criação desse projeto.
Durante o processo de produção, a equipe de demonstração criou uma lista dos ativos de que precisaria e a Quixel capturaria novos ativos se não houvesse uma correspondência adequada na biblioteca existente. Muitos desses ativos eram vegetação, como grama, plantas e arbustos, que exigem equipamento e configuração adequados para serem escaneados.
A Quixel não apenas nos forneceu folhas de textura para esses ativos, mas também criou a geometria, com seus LODs e configuração de cores de vértice para dar suporte ao nosso sombreador de vento.

Entre o lançamento do Livro dos Mortos: Environment e os recursos inéditos usados no teaser, recebemos mais de 50 recursos de alta qualidade e complexidade que nos fariam ter dificuldades para cumprir nossos prazos com os poucos artistas que temos na equipe.
Durante a produção, pudemos colocar os ativos rapidamente no mecanismo e com boa aparência. Com frequência, ajustamos as texturas (principalmente o albedo, ajustando o brilho/níveis/curvas e, muitas vezes, ajustando as cores para unificá-las em toda a cena), as reembalamos adequadamente, ajustamos um pouco os LODs para o nível desejado, atribuímos as texturas a um novo material HDRP Lit e terminamos o processo.
Felizmente, a Quixel lançou recentemente uma ferramenta, o Megascans Bridge, que faria a maior parte do trabalho de importação que fizemos manualmente. Isso economiza tempo na reembalagem de texturas para HDRP e similares.

Para aqueles que estão interessados em mais recursos Megascans, aqui está um lembrete de que há várias coleções Megascans na Unity Asset Store. Todos os ativos estão prontos para serem importados em uma configuração de projeto com o Pipeline de Renderização de Alta Definição ou o Pipeline de Renderização Leve.

A criação de um sistema eólico para ativos de vegetação e todo o seu pipeline é sempre um processo complicado. Há muitos tipos diferentes de ativos de vegetação que precisariam ser animados de maneiras diferentes; duas árvores diferentes podem exigir uma configuração completamente diferente e uma complexidade de sombreamento diferente.
Por esse motivo, nossa equipe decidiu criar uma animação processual personalizada baseada em sombreamento de vértices para o efeito de vento em nossos ativos de vegetação. Nós o fizemos sob medida para trabalhar com nosso projeto específico e com as árvores ou arbustos que ele contém. Permitindo-nos ter controle total sobre ele.
Torbjorn Laedre, nosso líder técnico, criou um sombreador que suportaria vários tipos diferentes de vegetação, usando três técnicas diferentes:
- Hierarchy Pivot, para nossas árvores e algumas plantas com uma estrutura/hierarquia bem definida
- Single Pivot, para grama, plantas pequenas e para arbustos grandes com estrutura/hierarquia indefinida
- Animação de procedimentos, para ativos de vegetação em que os pivôs não podem ser previstos.

As árvores foram os ativos mais complexos a serem preparados; no lado do conteúdo, elas estão usando o tipo de animação Hierarchy Pivot e dependem de três níveis distintos de hierarquia:
- Tronco, que fica apoiado no chão.
- Filiais Nível A, que estão conectadas ao tronco.
- Filiais do Nível B, que estão conectadas às filiais do Nível A.
O shader precisa saber o nível de hierarquia e o pivô de cada vértice da árvore. Primeiro, tive que criar a geometria da árvore em si e, em seguida, atribuir o nível de hierarquia para cada polígono da árvore usando o canal de cor verde do vértice.

- Um valor de 0 para o canal verde da cor do vértice significaria que ele é o tronco
- Um valor entre 0 e 1 seria o nível de ramificação A
- Um valor de 1 seria o nível de ramificação B
Fiz isso usando o Autodesk Maya e, com alguns pequenos scripts, consegui configurar todos os LODs de um ativo em 10 a 15 minutos.
Além disso, também usamos o que chamamos de "Flutter Mask" (máscara de vibração). São máscaras de textura que ajudam a determinar em que ponto da geometria está o pivô do galho. Usamos isso para as ramificações que usavam texturas alfa rígidas para a geometria. Aqui está uma ilustração dessa máscara.

Com todas essas informações preparadas, eu poderia usar o script C# que inseriria meu pré-fab de árvore e geraria um novo pré-fab com as informações de pivô de cada vértice incorporadas. Depois de adicionar um objeto WindControl à minha cena, posso importar minha árvore para a cena e começar a brincar com as propriedades do material.
Você pode ver que cada nível hierárquico tem uma propriedade de alcance (basicamente o comprimento do tronco ou dos ramos) e uma propriedade de elasticidade.
Há também algumas propriedades para configurar a animação da vibração do vento. Eles adicionam um pouco de ruído processual às posições dos vértices, para imitar a vibração dos galhos quando o vento sopra sobre eles.
Por último, mas não menos importante, tivemos que fazer com que o som do vento FX influenciasse a animação do vento. O volume do som está impulsionando a força do vento da animação. É realmente surpreendente como uma simples ideia pode acrescentar algo ao projeto. Se ainda não tiver feito isso, você deve abrir o projeto e dar uma olhada. Você perceberá que as árvores e toda a grama ao redor tremem quando ouvir grandes rajadas de vento nos arredores.
Ao visar o nível de detalhe e a densidade de um projeto como o Book of the Dead, foi importante para mim pensar em como eu estruturaria o nível, para evitar problemas de desempenho mais tarde na produção. Uma das coisas que tentei fazer com cuidado foi limitar as longas distâncias de visualização na cena. Você pode fazer isso colocando "corredores" e "gargalos" no layout da cena.

Esses layouts, juntamente com os assets configurados corretamente como sinalizadores 'Occluder static' e 'Occludee static', tornarão a seleção de oclusão da Unity mais eficiente.
Este vídeo mostra a Occlusion Culling Visualization, e você pode facilmente adivinhar para onde a câmera está olhando a partir da visualização superior. No final do vídeo, eu ativo/desativo a seleção de oclusão e vejo quais objetos estão sendo selecionados pela seleção de oclusão.
Você também poderá ver que alguns objetos não são eliminados, principalmente as árvores realmente altas, algumas com mais de 25 metros de altura, que têm uma caixa delimitadora muito grande e, portanto, são difíceis de eliminar atrás dos penhascos.
Quando o trailer foi lançado, vimos comentários de que não poderíamos usar o sistema de terreno antigo. Mas é exatamente isso que usamos, e modificamos o shader Layered Lit do Pipeline de Renderização HD para oferecer suporte a ele.
O HDRP Layered Shader permite a mistura de camadas usando sua textura de mapa de altura, de modo que o resultado é melhor do que a mistura linear que vem com o shader de terreno legado.

Essa é, obviamente, uma solução temporária e não está devidamente integrada à interface do usuário. Para alterar o terreno, será necessário editar o material aplicado a ele, em vez de usar o botão "Edit Texture" (Editar textura) na guia Paint Texture (Pintar textura) do objeto de terreno.


Se quiser criar um novo terreno e aplicar texturas diferentes nele, você precisará duplicar esse material TerrainLayeredLit e atribuí-lo ao novo terreno. Você também precisará criar esses 4 conjuntos de texturas na guia Paint Texture. As texturas atribuídas ali não serão usadas para renderizar o terreno, mas permitirão que você pinte as diferentes camadas do terreno. Também é possível alterar as propriedades de ladrilho das diferentes camadas.
Além disso, para poder usar totalmente o recurso LODGroup, todos os ativos colocados no terreno são configurados como árvores, e não como ativos de detalhes.

Mas, na verdade, esse projeto tem uma quantidade muito grande de ativos espalhados pelo chão: grama, arbustos, plantas, galhos de madeira, pedras etc. Com tudo isso, o terreno pode ser bastante simples. Você pode ver abaixo que, nessa foto em particular, o terreno é apenas um material de ladrilho simples.
Ao andar pelo nível, você notará em alguns lugares uma quantidade muito grande de pequenos galhos e pinhas espalhados pelo chão.

Eles não são tão óbvios quando você simplesmente anda pelo nível, mas realmente aumentam o nível de detalhes da cena quando você começa a olhar para o chão. Às vezes, há centenas de pequenos galhos no chão, entre pedras e troncos mortos, exatamente como eles acabariam descansando se caíssem das árvores. Colocá-los manualmente seria simplesmente impossível. Por esse motivo, Torbjorn Laedre criou uma ferramenta para nos ajudar a espalhar esses pequenos detalhes no nível.
Os galhos são planos de recorte simples com um material alfa. Adicionamos colisores de cápsula de física a eles.

O script primeiro gerará a quantidade desejada desses objetos de dispersão em torno de uma posição de transformação e, em seguida, simulará a física para que eles caiam no chão, colidindo com o terreno e todos os outros ativos (rocha, troncos mortos etc.). Em seguida, ao pressionar o botão "Bake", eles serão destituídos de seus colisores, mesclados em um único objeto e receberão um LODGroup com uma distância específica na qual deverão ser removidos.
Esse script é usado por objetos chamados "UberTreeSpawner" na cena, e você pode usá-lo como quiser.
Observação sobre essa ferramenta: Para que os galhos e outros objetos espalhados caiam corretamente no chão e em outros recursos, você precisará ter colisores de malha de alta densidade em todos os recursos da cena. Ao mesmo tempo, você não quer que esses colliders pesados sejam usados quando o jogo estiver em execução. Por esse motivo, a maioria dos ativos na cena tem dois colliders diferentes: Uma luz a ser usada em tempo real no modo de reprodução pelo PlayerController com a camada padrão atribuída. E um usado exclusivamente para a simulação física desses galhos, com a camada "GroundScatter" atribuída.
O Livro dos Mortos: O projeto ambiental está usando iluminação global indireta com iluminação direta em tempo real.
Tanto a iluminação indireta do sol quanto a iluminação direta e indireta do céu são incorporadas aos mapas de luz e às sondas de luz. As sondas de reflexão, as sondas de oclusão e outras fontes de oclusão também são preparadas. A contribuição direta do sol, por outro lado, é a iluminação em tempo real. O sombreamento no Pipeline de Renderização HD fica melhor quando se usa luz direta em tempo real e também nos dá alguma liberdade para animar a rotação, a intensidade e a temperatura da cor da luz direcional em tempo de execução.

Como a iluminação indireta é "baked", não podemos alterar muito a intensidade e a cor da luz direcional, ou ela não combinará mais com a iluminação "baked". Não conseguiríamos nos safar com um ciclo dia/noite completo nessa configuração, embora uma floresta seja um ambiente bastante tolerante em termos de obscurecimento da iluminação indireta incompatível.
Os mapas de luz criados são usados principalmente para o terreno e alguns outros ativos, mas preferimos usar uma combinação de sondas de luz e sondas de oclusão para todas as rochas e penhascos do projeto, pois elas proporcionam melhores resultados para objetos com ângulos agudos e mapas normais nítidos.
A iluminação de uma floresta densa é algo difícil de conseguir em tempo real. As árvores, com todas as suas folhas e galhos, têm uma área de superfície enorme e geometria complexa, portanto, não é prático cobri-las com mapas de luz. O uso de uma única sonda de luz por árvore proporcionaria uma iluminação uniforme de baixo para cima. Os Light Probe Proxy Volumes estão mais próximos do que gostaríamos, mas não é prático aumentar a resolução da grade para capturar detalhes finos.
Por esse motivo, nosso programador gráfico sênior, Robert Cupisz, desenvolveu as sondas de oclusão.
Do ponto de vista de um artista, é um recurso muito bom e fácil de usar: basta adicionar o objeto à cena, e ele exibe um dispositivo de volume que você precisa dimensionar para cobrir a área desejada e, em seguida, configurar seus parâmetros de resolução em X, Y e Z.

Ele também permite que você crie sondas de oclusão "Detalhadas" se quiser que alguma área da cena tenha uma densidade maior de sondas. Depois de configurado, você precisará preparar a iluminação de toda a cena. As sondas de oclusão serão cozidas durante esse processo.
Cada sonda na grade 3D faz uma amostragem da visibilidade do céu disparando raios no hemisfério superior e a armazena como um valor de 8 bits que vai de 0 totalmente oculto a 1 totalmente visível. Isso nos dá áreas mais escuras sempre que há uma concentração maior de folhas e galhos, ainda mais quando algumas árvores estão agrupadas.
As sondas que tiverem o azar de aterrissar dentro de troncos ou pedras ficarão totalmente pretas. Para evitar que essa escuridão vaze, elas são marcadas como inválidas e substituídas por sondas vizinhas válidas.
Como as sondas analisam a parte do céu que é visível, elas devem atenuar apenas a contribuição direta do céu. Por esse motivo, o lightmapper é configurado para excluir a contribuição da luz direta das sondas de luz regulares e, em seguida, a iluminação da sonda é composta como sonda de luz mais sonda de céu direta ocluída por sondas de oclusão.
Dessa forma, podemos ter toneladas de sondas de oclusão baratas que coletam amostras de pequenos detalhes de como a folhagem oculta o céu, trazendo profundidade à imagem, e pouquíssimas sondas de luz mais caras que coletam amostras de luz indireta que muda mais lentamente.

Se quiser ter uma visão mais clara de como eles afetam a cena, você também pode usar a visualização SkyOcclusion Debug.

A API da sonda de oclusão para preparar sondas de oclusão e excluir a contribuição direta do céu das sondas de luz foi adicionada ao Unity 2018.1, e todos os scripts e shaders estão disponíveis no projeto.
Portamos e reutilizamos a solução Atmospheric Scattering que desenvolvemos originalmente para a demonstração do Blacksmith.
Nosso programador sênior, Lasse Jon Fuglsang Pedersen, estendeu-o para fazer uso da superamostragem temporal, resultando em uma aparência muito mais suave.

O Lit Shader padrão do Pipeline de Renderização HD suporta vários tipos de difusão. Ele permite que você tenha materiais com dispersão de subsuperfície ou, como usado para toda a nossa vegetação neste projeto, um material translúcido mais simples com apenas transmissão de luz.

Esse efeito é configurado em dois locais diferentes:
- No material, você precisa escolher o tipo de material "Translúcido", inserir um mapa de espessura e escolher um perfil de difusão, que é o segundo local:
- As configurações do perfil de difusão, onde você pode editar todos os outros parâmetros do seu efeito de transmissão

Observação: Nossa equipe acrescentou controles deslizantes adicionais para controlar separadamente a transmissão direta e a indireta para ter mais controle sobre o resultado final. Mas essa alteração não está respeitando as regras de PBR e, portanto, não será incluída no Pipeline de Renderização HD.
Os volumes de área são criados com base no sistema de volume principal oferecido pela SRP e são muito semelhantes aos volumes Post Processing. Sua função é direcionar as propriedades do objeto, dependendo da posição do objeto da câmera principal.
Vários objetos, incluindo o Directional Light, o Atmospheric Scattering, o Auto Focus e o WindControl, têm suas propriedades orientadas por Area Volumes, portanto, se você quiser alterar a configuração de iluminação atual, por exemplo, precisará fazer isso no Area Volume correspondente. Esses objetos Area Volumes estão localizados na cena principal, em _SceneSettings > _AREASETTINGS, e têm o sufixo '_AV'.
Para aqueles que não usam muito o Pipeline de Renderização HD, agora há uma janela de depuração específica do SRP que pode ser aberta no menu Window > General > Render Pipeline Debug


Com isso, você poderá ver camadas GBuffer individuais, componentes de iluminação ou mapas de textura específicos de seus materiais, ou até mesmo substituir albedo/suavidade/normal. É uma ferramenta realmente útil quando você tem alguns objetos que não estão sendo renderizados corretamente ou qualquer outro erro visual. Isso o ajudará a identificar a origem do problema muito mais rapidamente.
A melhor parte é que essas exibições de depuração são geradas automaticamente a partir de seus shaders, e os programadores podem criar novas exibições de depuração com bastante facilidade.

Eu até usei essas exibições de depuração para criar os painéis de árvores que são usados no plano de fundo da cena. Apenas coloquei meus ativos em uma cena vazia e tirei capturas de tela com as camadas de albedo, rugosidade e gbuffer normal visíveis, e as usei para criar meus mapas de textura.
Embora grande parte da otimização resida no lado do código, também é importante que seus ativos e cenas estejam configurados corretamente se você quiser ter uma taxa de quadros decente. Aqui estão algumas das maneiras pelas quais o conteúdo foi otimizado para esse projeto:
- Todos os nossos materiais estão usando o GPU Instancing.
- Estamos usando LODs para a maioria dos ativos nessa cena, o que é imprescindível.
- O recurso LOD Crossfade é excelente, pois permite uma mistura agradável e suave entre os diferentes níveis de detalhes de seu objeto. No entanto, esse recurso é bastante pesado e pode realmente aumentar o número de chamadas de desenho em seu projeto. Por esse motivo, nós o desativamos no maior número possível de ativos.
- Para evitar uma transição perceptível entre LODs, começamos a usar mapas normais do Object Space em muitos de nossos ativos de rochas e penhascos grandes.


Observação: O uso do mapa normal Object Space em vez do mapa normal Tangent Space reduzirá a precisão do mapa normal. Na verdade, isso não é muito perceptível em nossos ativos que são muito ásperos e barulhentos, mas você provavelmente não vai querer usá-lo em ativos de superfície dura.
- Embora seja importante limitar a distância de visualização pela maneira como a cena é construída e pelo uso de occlusion culling, também vale a pena saber que muitas das draw calls usadas para renderizar a cena são, na verdade, provenientes da renderização de cada cascata dos mapas de sombra (mais especificamente da luz direcional em nosso projeto).
- Recebemos muitas chamadas de saque dos pequenos ativos de vegetação espalhados pelo terreno, centenas e centenas deles em alguns locais. Conseguimos uma boa redução das chamadas de saque criando áreas maiores desses ativos de grama e plantas. Em vez de ter centenas deles, teríamos apenas 15 a 20.
Observe que isso tem um impacto na qualidade visual, pois, com ativos tão grandes, fica muito difícil evitar que a grama seja cortada por pedras e outros ativos colocados no chão. - Estamos usando a seleção de camadas, que é um recurso já existente no Unity, mas não tem nenhuma interface do usuário. Esse recurso permite selecionar objetos que são atribuídos a uma camada específica, dependendo da distância em que se encontram da câmera. Torbjorn ampliou esse recurso para poder também eliminar a projeção de sombra desses objetos a uma distância diferente. Por exemplo, a maioria dos nossos pequenos recursos de vegetação deixa de projetar sombras a uma distância de cerca de 15 metros, o que não é muito perceptível, dada a quantidade de ruído da grama e de outras plantas no chão, e são completamente eliminados a cerca de 25 metros, independentemente da configuração do LODGroup.
---
Fique atento à próxima postagem do blog desta série. Exploraremos o trabalho realizado para criar o sombreamento, a iluminação, o pós-processamento e muito mais do Book of the Dead.
Se você não pôde comparecer à Unite Berlin, em breve lançaremos a apresentação de Julien Heijmans sobre arte ambiental na demonstração. Você pode seguir nosso canal no YouTube para se manter atualizado sobre quando esse vídeo for lançado.