
Este é o terceiro de uma série de artigos que descompacta dicas de otimização para seus projetos Unity. Use-os como um guia para rodar em taxas de quadros mais altas com menos recursos. Depois de experimentar essas melhores práticas, não deixe de conferir as outras páginas da série:
Veja nossos últimos guias de otimização para desenvolvedores e artistas do Unity 6:
Entenda as limitações do seu hardware alvo e como perfilar a GPU para otimizar a renderização dos seus gráficos. Experimente estas dicas e melhores práticas para reduzir a carga de trabalho na GPU.
Ao perfilar, é útil começar com um benchmark para te dizer quais resultados de perfil você deve esperar de GPUs específicas.
Veja GFXBench para uma ótima lista de diferentes benchmarks padrão da indústria para GPUs e placas gráficas. O site fornece uma boa visão geral das GPUs atuais disponíveis e como elas se comparam entre si.
Veja as estatísticas de renderização
Clique no botão Stats no canto superior direito da visualização do Jogo. Esta janela mostra informações de renderização em tempo real sobre sua aplicação durante o modo Play. Use esses dados para ajudar a otimizar o desempenho:
- fps: Quadros por segundo
- CPU Principal: Tempo total para processar um quadro (e atualizar o Editor para todas as janelas)
- CPU Renderizar: Tempo total para renderizar um quadro da visualização do Jogo
- Lotes: Grupos de chamadas de desenho a serem desenhadas juntas
- Tris (triângulos) e Verts (vértices): Geometria de malha
- Chamadas SetPass: O número de vezes que o Unity deve alternar passes de shader para renderizar os GameObjects na tela; cada passe pode introduzir sobrecarga extra na CPU.
Observação: O fps no Editor não se traduz necessariamente em desempenho na build. Recomendamos que você faça o perfil da sua build para obter os resultados mais precisos. O tempo de quadro em milissegundos é uma métrica mais precisa do que quadros por segundo ao fazer benchmark. Saiba mais no e-book Guia definitivo para perfilagem de jogos Unity (edição Unity 6).

Para desenhar um GameObject, o Unity emite uma chamada de desenho para a API gráfica (por exemplo, OpenGL, Vulkan ou Direct3D). Cada chamada de desenho é intensiva em recursos. Mudanças de estado entre chamadas de desenho, como a troca de materiais, podem causar sobrecarga de desempenho do lado da CPU.
Hardware de PC e console pode suportar muitas chamadas de desenho, mas a sobrecarga de cada chamada ainda é alta o suficiente para justificar a tentativa de reduzi-las. Em dispositivos móveis, a otimização de chamadas de desenho é vital. Você pode conseguir isso com agregação de chamadas de desenho.
A agregação de chamadas de desenho minimiza essas mudanças de estado e reduz o custo da CPU para renderizar objetos. Unity pode combinar múltiplos objetos em menos lotes usando várias técnicas:
- Agregação SRP: Se você estiver usando HDRP ou URP, ative o Agregador SRP em seu Ativo de Pipeline sob Avançado. Ao usar shaders compatíveis, o Agregador SRP reduz a configuração da GPU entre chamadas de desenho e torna os dados do material persistentes na Memória da GPU. Isso pode acelerar significativamente seus tempos de renderização da CPU. Use menos Variações de Shader com uma quantidade mínima de Palavras-chave para melhorar a agregação SRP. Consulte esta documentação SRP para ver como seu projeto pode aproveitar esse fluxo de trabalho de renderização.
- Instanciação de GPU: Se você tiver um grande número de objetos idênticos (por exemplo, edifícios, árvores, grama, etc., com a mesma malha e material), use instanciação de GPU. Essa técnica os agrupa usando hardware gráfico. Para habilitar a Instanciação de GPU, selecione seu material na janela do Projeto e, no Inspetor, marque Habilitar Instanciação.
- Agregação estática: Para geometria não móvel, Unity pode reduzir chamadas de desenho para quaisquer malhas que compartilhem o mesmo material. É mais eficiente do que a agregação dinâmica, mas usa mais memória. Marque todas as malhas que nunca se movem como Agregação Estática no Inspetor. Unity combina todas as malhas estáticas em uma grande malha no momento da construção. O StaticBatchingUtility também permite que você crie esses lotes estáticos você mesmo em tempo de execução (por exemplo, após gerar um nível procedural de partes não móveis).
- Agregação Dinâmica: Para malhas pequenas, o Unity pode agrupar e transformar vértices na CPU, e então desenhá-los todos de uma vez. Observação: Não use isso a menos que você tenha malhas de baixa poligonagem suficientes (não mais de 300 vértices cada e 900 atributos de vértice no total). Caso contrário, habilitá-lo desperdiçará tempo da CPU procurando por malhas pequenas para agrupar.
Você pode maximizar o agrupamento com algumas regras simples:
- Use o menor número possível de texturas em uma cena. Menos texturas requerem menos materiais únicos, tornando-os mais fáceis de agrupar. Além disso, use atlas de texturas sempre que possível.
- Sempre asse os lightmaps no maior tamanho de atlas possível. Menos lightmaps requerem menos mudanças de estado de material, mas fique atento ao uso de memória.
- Cuidado para não instanciar materiais involuntariamente. Acessar Renderer.material em scripts duplica o material e retorna uma referência à nova cópia. Isso quebra qualquer agrupamento existente que já inclua o material. Se você deseja acessar o material do objeto agrupado, use Renderer.sharedMaterial em vez disso.
- Fique atento ao número de contagens de agrupamento estático e dinâmico em relação ao total de chamadas de desenho usando o Profiler ou as estatísticas de renderização durante as otimizações.
Por favor, consulte a documentação sobre agrupamento de chamadas de desenho para mais informações.

O Frame Debugger permite que você congele a reprodução em um único quadro e avance através de como o Unity constrói uma cena para identificar oportunidades de otimização. Procure por GameObjects que renderizam desnecessariamente e desative-os para reduzir as chamadas de desenho por quadro.
Observação: O Frame Debugger não mostra chamadas de desenho individuais ou mudanças de estado. Apenas profilers nativos de GPU fornecem informações detalhadas sobre chamadas de desenho e tempos. No entanto, o Depurador de Frame ainda pode ser muito útil na depuração de problemas de pipeline ou questões de agrupamento.
Uma vantagem do Depurador de Frame do Unity é que você pode relacionar uma chamada de desenho a um GameObject específico na cena. Isso facilita a investigação de certos problemas que podem não ser possíveis em depuradores de frame externos.
Para mais informações, leia a documentação do Depurador de Frame e veja a seção

A taxa de preenchimento refere-se ao número de pixels que a GPU pode renderizar na tela a cada segundo.
Se o seu jogo é limitado pela taxa de preenchimento, isso significa que ele está tentando desenhar mais pixels por quadro do que a GPU pode suportar.
Desenhar em cima do mesmo pixel várias vezes é chamado de sobrecarga de desenho. A sobrecarga de desenho diminui a taxa de preenchimento e consome largura de banda de memória extra. As causas mais comuns de sobrecarga de desenho são:
- Geometria opaca ou transparente sobreposta
- Shaders complexos, muitas vezes com múltiplas passagens de renderização
- Partículas não otimizadas
- Elementos de UI sobrepostos
Embora você queira minimizar seu efeito, não há uma abordagem única para resolver problemas de sobrecarga de desenho. Comece experimentando com os fatores acima para reduzir seu impacto.
Assim como em outras plataformas, a otimização em consoles geralmente significa reduzir os lotes de chamadas de desenho. Existem algumas técnicas que podem ajudar.
- Use Ocultação de oclusão para remover objetos ocultos atrás de objetos em primeiro plano e reduzir a sobrecarga de desenho. Este requer um processamento adicional da CPU, então use o Profiler para garantir que mover o trabalho da GPU para a CPU seja benéfico.
- A instância de GPU também pode reduzir seus lotes se você tiver muitos objetos que compartilham a mesma malha e material. Limitar o número de modelos em sua cena pode melhorar o desempenho. Se feito de forma artística, você pode construir uma cena complexa sem torná-la repetitiva.
- O SRP Batcher pode reduzir a configuração da GPU entre DrawCalls agrupando comandos de Bind e Draw da GPU. Para se beneficiar desse agrupamento SRP, use quantos materiais forem necessários, mas restrinja-os a um pequeno número de shaders compatíveis (por exemplo, shaders Lit e Unlit no URP e HDRP).
A oclusão desativa GameObjects que estão totalmente ocultos (ocluídos) por outros GameObjects. Isso impede que a CPU e a GPU usem tempo para renderizar objetos que nunca serão vistos pela Câmera.
Culling acontece por câmera. Isso pode ter um grande impacto no desempenho, especialmente quando várias câmeras estão habilitadas simultaneamente. Unity usa dois tipos de culling, culling de frustum e oclusão.
Culling de frustum é realizado automaticamente em cada Câmera. Isso impede que GameObjects que estão fora do Frustum de Visão sejam renderizados, ajudando a otimizar o desempenho.
Você pode definir distâncias de culling por camada manualmente via Camera.layerCullDistances. Isso permite que você cull GameObjects pequenos a uma distância menor que o farClipPlane padrão.
Organize GameObjects em Camadas. Use o array layerCullDistances para atribuir a cada uma das 32 camadas um valor menor que o farClipPlane (ou use 0 para usar o farClipPlane padrão).
Unity cull por camada primeiro, mantendo GameObjects apenas nas camadas que a Câmera usa. Depois, o culling de frustum remove quaisquer GameObjects fora do frustum da câmera. O culling de frustum é realizado como uma série de trabalhos para aproveitar as threads de trabalho disponíveis.
Cada teste de culling de camada é muito rápido (essencialmente apenas uma operação de máscara de bits). No entanto, esse custo ainda pode se acumular com um número muito grande de GameObjects. Se isso se tornar um problema para o seu projeto, você pode precisar implementar algum sistema para dividir seu mundo em "setores" e desativar setores que estão fora do frustum da Câmera para aliviar um pouco da pressão no sistema de culling de camada/frustum do Unity.
Occlusion culling remove qualquer GameObject da visualização do jogo se a Câmera não puder vê-los. Use este recurso para evitar a renderização de objetos ocultos atrás de outros objetos, uma vez que estes ainda podem ser renderizados e custar recursos. Por exemplo, renderizar outra sala é desnecessário se uma porta estiver fechada e a Câmera não puder ver dentro da sala.
Habilitar o occlusion culling pode aumentar significativamente o desempenho, mas também pode exigir mais espaço em disco, tempo de CPU e RAM. O Unity processa os dados de oclusão durante a construção e depois precisa carregá-los do disco para a RAM enquanto carrega uma cena.
Enquanto o culling de frustum fora da visualização da câmera é automático, o occlusion culling é um processo pré-processado. Basta marcar seus objetos como Static.Occluders ou Occludees, e então processar através do Janela > Renderização > Occlusion Culling diálogo.
Confira o tutorial Trabalhando com Occlusion Culling para mais informações.

Permitir Resolução Dinâmica é uma configuração da Câmera que permite que você escale dinamicamente alvos de renderização individuais para reduzir a carga de trabalho na GPU. Em casos onde a taxa de quadros da aplicação diminui, você pode gradualmente reduzir a resolução para manter uma taxa de quadros consistente.
O Unity aciona essa escala se os dados de desempenho sugerirem que a taxa de quadros está prestes a diminuir como resultado de estar limitado pela GPU. Você também pode acionar essa escala manualmente com um script. Isso é útil se você estiver se aproximando de uma seção intensiva em GPU da aplicação. Se escalado gradualmente, a resolução dinâmica pode ser quase imperceptível.
Consulte a página do manual resolução dinâmica para informações adicionais e uma lista de plataformas suportadas.
Às vezes, você pode precisar renderizar de mais de um ponto de vista durante o seu jogo. Por exemplo, é comum em um jogo FPS desenhar a arma do jogador e o ambiente separadamente com diferentes campos de visão (FOV). Isso evita que os objetos em primeiro plano pareçam muito distorcidos quando vistos através do FOV grande do fundo.
Você pode usar Camera Stacking no URP para renderizar mais de uma visão de câmera. No entanto, ainda há um corte e renderização significativos feitos para cada câmera. Cada câmera incorre em alguma sobrecarga, esteja ela fazendo um trabalho significativo ou não. Use apenas os componentes de Câmera necessários para renderização. Em plataformas móveis, cada câmera ativa pode usar até 1 ms de tempo de CPU, mesmo quando não está renderizando nada.

No URP, em vez de usar várias câmeras, experimente uma Render Objects Renderer Feature personalizada. Selecione Add Renderer Feature no ativo Renderer Data. Escolha Render Object.
Ao substituir cada Render Object, você pode:
- Associá-lo a um Evento e injetá-lo em um momento específico do loop de renderização
- Filtrar por Render Queue (Transparente ou Opaco) e LayerMask
- Afectar as configurações de Profundidade e Estêncil
- Modificar as configurações da Câmera (Campo de Visão e Deslocamento de Posição)

No HDRP, você pode usar passes personalizados para efeito semelhante. Configurar um Custom Pass usando um Volume de Custom Pass é análogo a usar um HDRP Volume.
Um Custom Pass permite que você:
- Mude a aparência dos materiais em sua cena
- Mude a ordem que o Unity renderiza os GameObjects
- Leia os buffers da câmera em shaders
Usar Volumes de Custom Pass no HDRP pode ajudar você a evitar o uso de Câmeras extras e a sobrecarga adicional associada a elas. Custom passes têm flexibilidade extra em como podem interagir com shaders. Você também pode estender a classe Custom Pass com C#.

À medida que os objetos se afastam, Nível de Detalhe (LOD) pode ajustar ou trocar para usar malhas de menor resolução com materiais e shaders mais simples. Isso fortalece o desempenho da GPU.
Veja o curso Trabalhando com LODs no Unity Learn para mais detalhes.

Profile seus efeitos de pós-processamento para ver seu custo na GPU. Alguns efeitos de tela cheia, como Bloom e profundidade de campo, podem ser caros, mas experimente até encontrar um equilíbrio feliz entre qualidade visual e desempenho.
O pós-processamento tende a não flutuar muito em tempo de execução. Uma vez que você tenha determinado suas Sobrescritas de Volume, aloque seus efeitos de pós-processamento uma parte estática do seu orçamento total de quadros.

Tesselação subdivide formas em versões menores daquela forma. Isso pode aumentar o detalhe através da geometria aumentada. Embora haja exemplos onde a tesselação faz sentido, como para casca de árvore realista, em geral, evite a tesselação em consoles. Eles podem ser caros na GPU.
Assim como os shaders de tesselação, os shaders de geometria e de vértice podem ser executados duas vezes por quadro na GPU - uma vez durante a pré-passagem de profundidade e novamente durante a passagem de sombra.
Se você quiser gerar ou modificar dados de vértice na GPU, um shader de computação é frequentemente uma escolha melhor do que um shader de geometria. Fazer o trabalho em um shader de computação significa que o shader de vértice que realmente renderiza a geometria pode ser comparativamente rápido e simples.
Saiba mais sobre conceitos básicos de shader.
Quando você envia uma chamada de desenho para a GPU, esse trabalho se divide em muitas frentes de onda que a Unity distribui por todos os SIMDs disponíveis na GPU.
Cada SIMD tem um número máximo de frentes de onda que podem estar em execução ao mesmo tempo. Ocupação de frente de onda refere-se a quantas frentes de onda estão atualmente em uso em relação ao máximo. Isso mede quão bem você está utilizando o potencial da GPU. Ferramentas de análise de desempenho específicas do console mostram a ocupação de frentes de onda em grande detalhe.
No exemplo abaixo, as frentes de onda do shader de vértice aparecem em verde. As frentes de onda do shader de pixel aparecem em azul. No gráfico inferior, muitas frentes de onda do shader de vértice aparecem sem muita atividade do shader de pixel. Isso mostra uma subutilização do potencial da GPU.
Se você está fazendo muito trabalho de shader de vértice que não resulta em pixels, isso pode indicar uma ineficiência. Embora uma baixa ocupação de frente de onda não seja necessariamente ruim, é uma métrica para começar a otimizar seus shaders e verificar outros gargalos. Por exemplo, se você tiver uma paralisação devido a operações de memória ou computação, aumentar a ocupação pode ajudar no desempenho. Por outro lado, muitas frentes de onda em voo podem causar thrashing de cache e diminuir o desempenho.

Se você tiver intervalos em que está subutilizando a GPU, a Computação Assíncrona permite que você mova trabalhos úteis de shader de computação em paralelo para sua fila de gráficos. Isso faz melhor uso desses recursos de GPU.
Por exemplo, durante a geração do mapa de sombras, a GPU realiza renderização apenas de profundidade. Muito pouco trabalho de shader de pixel acontece neste ponto, e muitas frentes de onda permanecem desocupadas.
Se você puder sincronizar algum trabalho de shader de computação com a renderização apenas de profundidade, isso resulta em um melhor uso geral da GPU. As frentes de onda não utilizadas poderiam ajudar com a Oclusão Ambiental em Espaço de Tela ou qualquer tarefa que complemente o trabalho atual.
Assista a esta sessão sobre Otimização de desempenho para consoles de alto desempenho da Unite.

O GPU Resident Drawer (disponível para URP e HDRP) é um sistema de renderização impulsionado pela GPU projetado para otimizar o tempo da CPU, oferecendo benefícios significativos de desempenho. Ele suporta renderização multiplataforma e é projetado para funcionar imediatamente com projetos existentes.
O sistema pode ser ativado dentro do ativo de Pipeline de Renderização HDRP ou URP. Selecione Desenho Instanciado para ativá-lo. Você também pode selecionar se deseja ativá-lo apenas no modo de Jogo ou também no modo de Edição.
Quando você ativa o GPU Resident Drawer, jogos que são limitados pela CPU devido a um alto número de chamadas de desenho podem melhorar em desempenho à medida que a quantidade de chamadas de desenho é reduzida. As melhorias que você verá dependem da escala de suas cenas e da quantidade de instanciamento que você utiliza. Quanto mais objetos instanciáveis você renderizar, maiores serão os benefícios que você verá.
Ao selecionar a opção de Desenho Instanciado, você pode receber uma mensagem na interface avisando que a configuração "BatchRenderGroup Variants deve ser 'Manter Todos'". Ajustar esta opção nas configurações gráficas completa a configuração para o GPU Resident Drawer.
Para saber mais, confira nosso tópico de discussão aqui.

Oculsão de GPU, disponível para URP e HDRP, funciona em conjunto com o GPU Resident Drawer. Isso aumenta significativamente o desempenho ao reduzir a quantidade de sobreposição para cada quadro, o que significa que o renderizador não está desperdiçando recursos desenhando coisas que não são vistas.
Para ativar a oclusão de GPU, localize o ativo do pipeline de renderização e ative a caixa de seleção de Oclusão de GPU.
Para habilitar a Oclusão de GPU no Modo de Depuração no Unity 6, vá para Janela > Renderização > Oclusão de Culling. Aqui, você pode visualizar como os objetos estão sendo ocultados alternando várias opções de visualização.


Você pode encontrar muitas mais melhores práticas e dicas para desenvolvedores e criadores avançados do Unity no hub de melhores práticas do Unity. Escolha entre mais de 30 guias, criados por especialistas da indústria, engenheiros e artistas técnicos do Unity, que ajudarão você a desenvolver de forma eficiente com as ferramentas e sistemas do Unity.