Esta página fornece diretrizes e práticas recomendadas sobre como otimizar o desempenho em dispositivos móveis e obter a melhor fidelidade possível das funcionalidades de HDR para dispositivos móveis. Isso inclui:
Informações sobre os fatores que pesam no orçamento de desempenho em dispositivos móveis
Melhores práticas para empacotamento de projetos com funcionalidades de HDR para dispositivos móveis habilitadas
Uma experiência imersiva com as ferramentas disponíveis para avaliar gargalos de desempenho nos seus aplicativos da Unreal Engine.
Os links a seguir contêm informações úteis sobre tópicos gerais de desempenho no Android:
Conhecer seu orçamento de desempenho
O dispositivo alvo do seu aplicativo tem uma quantidade finita de recursos disponíveis, tanto para manter objetos na memória quanto para processá-los. Ao criar seu aplicativo, você deve decidir onde gastar esses recursos. Você deve se familiarizar com as capacidades do dispositivo em termos de velocidade, threads e largura de banda da CPU e GPU, bem como com a memória do dispositivo, a memória gráfica e o espaço em disco disponível.
Recomenda-se também avaliar o desempenho no dispositivo para compreender como ele funcionará e onde poderá ocorrer gargalos no desempenho. Você pode avaliar o desempenho de um dispositivo executando um aplicativo exigente ou uma demonstração técnica nele e, em seguida, observando suas estatísticas de desempenho.
Comandos do console para exibir estatísticas de desempenho
Você pode verificar as estatísticas de desempenho usando uma série de comandos do console. Para abrir o console do desenvolvedor em um dispositivo móvel , toque na tela usando quatro dedos de uma vez. Isso abrirá um teclado virtual e um prompt onde é possível inserir comandos do console.
O console e o comando de toque com quatro dedos apenas estão disponíveis em compilações Development. Eles não estão disponíveis em versões Shipping ou Testing.
No console, você pode inserir comandos para exibir informações de depuração na tela. A tabela a seguir inclui uma lista de comandos que fornecem informações de desempenho:
| Comando | Descrição |
|---|---|
Stat GPU | Exibe o tempo em milissegundos usado pela GPU para diferentes processos. Alguns dispositivos que executam o Vulkan podem oferecer suporte para stat GPU, mas esse comando não é diretamente compatível na maioria dos dispositivos móveis. |
Stat Unit | Exibe o tempo em milissegundos usado pela CPU para diferentes processos. Também exibe o thread do jogo, o thread de renderização e os tempos de GPU. |
Stat UnitGraph | Exibe um gráfico que mostra a utilização de CPU e GPU ao longo do tempo. Isso pode ajudar a identificar picos. |
Stat TextureGroup | Exibe a quantidade de memória usada por diferentes conjuntos de texturas. |
Para conhecer mais comandos do console que você pode usar para analisar o desempenho do seu aplicativo no dispositivo, consulte Comandos Stat.
Fatores comuns de desempenho
Agora que você já sabe onde procurar dados de desempenho no seu dispositivo, esta seção explicará os fatores que afetam com mais frequência o desempenho nos renderizadores de dispositivos móveis da Unreal Engine. Ao compreender quais desses elementos estão afetando seu aplicativo e como essa interferência está acontecendo, você é capaz de identificar e resolver problemas rapidamente usando as ferramentas de diagnóstico da Unreal Engine.
Mapas de normais x Malhas de alto vértice
Os renderizadores de dispositivos móveis da Unreal Engine são eficientes na renderização de um grande número de vértices, enquanto mapas de normais de alta qualidade nesses renderizadores podem ter problemas com profundidade de cor e ter um custo de desempenho maior do que um modelo de alta contagem de polígonos.
Em hardware mais simples, os mapas de normais podem melhorar muito a qualidade dos reflexos e da iluminação na superfície de um modelo. No entanto, formas sutis, como painéis da carroceria de um carro, podem exceder os deltas de 8 bits normalmente usados nesses mapas, resultando em faixas visíveis na renderização final.
Você pode usar mapas de normais de 16 bits para compensar isso, mas o custo de pixels para normais de 16 bits excede o custo de vértices de uma malha de maior densidade. As normais de 16 bits não são compactadas na engine, o que significa que também têm oito vezes o tamanho de um mapa de normais regular.
No exemplo a seguir, usamos painéis de carroceria de alta densidade sem mapas de normais. Quando o Galaxy Tab S6 é o dispositivo alvo, os painéis de carroceria totalizam aproximadamente 500.000 vértices.
Melhores práticas para mapas de normais de alta resolução
Incorporar vértices de alta resolução em um mapa de normais para um modelo com baixa contagem de polígonos pode ser um processo complexo, e muitos fatores podem reduzir a qualidade de uma textura de mapa de normais quando ela já está dentro da engine. Existem muitos conjuntos de ferramentas para incorporar mapas de normais, mas recomendamos o xNormal. O processo que usamos para o xNormal é basicamente o seguinte:
Incorpore o mapa de normais no xNormal como um TIFF 8k com 4xAA.
Importe o TIFF no Photoshop e reduza sua resolução até uma textura de 1k.
Aplique desfoque gaussiano com valor de 0,35px.
Converta a imagem de 16 para 8 bits.
Exporte a imagem para TGA de 24 bits.
Importe o mapa de normais final para a Unreal.
Para garantir que as normais de superfície usadas no processo de incorporação sejam as mesmas presentes na engine, exporte as normais otimizadas de dentro da Unreal. Importe o modelo de incorporação para a Unreal, opte por criar suas próprias normais e exporte-o da Unreal para ser incorporado no xNormal. Essa é uma etapa importante na criação de mapas de normais de alta qualidade, pois o xNormal precisa estar ciente das normais da superfície da malha para aplicar os deslocamentos do modelo de alta resolução.
Por fim, há duas opções que reduzirão artefatos ao renderizar malhas estáticas:
Usar UVs de precisão total
Usar base da tangente de alta precisão
Ambas as configurações estão disponíveis no Editor de Malha Estática, no painel Detalhes, em LODs.
Draw calls
Draw calls são pesquisas de ativos, que ocorrem a cada quadro. O número de draw calls usadas pelo seu aplicativo depende do número de malhas exclusivas na sua cena, bem como do número de IDs de material exclusivos que cada malha está usando. Atualmente, um alto número de draw calls é a principal causa de baixo desempenho gráfico, e você deve reduzi-las ao máximo.
Por exemplo, um modelo de carro altamente otimizado pode ter apenas cinco ou seis malhas separadas, e cada um desses componentes pode ter apenas um material.
Um bom alvo para draw calls em uma cena otimizada é cerca de 700 em um Galaxy Tab S6 e menos de 500 em hardware de menor desempenho. Em projetos para IHM, que tendem a usar materiais exclusivos ou complexos, 100 draw calls seria um bom alvo em um Galaxy Tab S6, enquanto menos de 50 seria preferível.
Você pode exibir a saída da sua contagem de draw calls com o comando do console Stat RHI.
Lembre-se de que a contagem de draw calls mudará conforme você estiver no JNE ou em um dispositivo. |
Reduzir a contagem de malhas
A maneira mais fácil de reduzir draw calls é reduzir o número de malhas exclusivas no seu mundo. Você pode fazer isso combinando o maior número possível de objetos em uma malha usando um conjunto de ferramentas de criação de conteúdo digital (CCD) , como o Maya, o 3DSMax ou o Blender, antes de importá-los para a Unreal.
Como reduzir a contagem de IDs de material
Há várias opções possíveis para reduzir o número de materiais exclusivos em uma malha.
O método mais simples é usar um programa como o Substance Painter, que integra vários materiais na mesma textura. Isso permite que você aproveite um grande número de tipos de material em um material da Unreal muito simples, que pode ser usado como base para instâncias de material com entradas de texturas simples. Isso também pode reduzir a contagem de instruções de material, o que melhora ainda mais o desempenho.
O segundo método usa máscaras para ter uma abordagem mais procedural. Materiais podem denotar certas características de uma superfície, como cor, rugosidade ou qualidades metálicas. Em vez de usar um material separado para partes diferentes de uma malha, é possível usar máscaras para separar as partes dos UVs de uma malha e aplicar diferentes configurações a cada seção. Você pode criar uma máscara básica usando uma textura em preto e branco, mas é mais eficiente usar a cor do vértice.
No exemplo a seguir, as cores do vértice são usadas para definir diferentes tipos de material, e o material define parâmetros que podem influenciar a aparência dessas partes individualmente. O mascaramento da cor do vértice é mais eficiente e cria uma separação mais nítida, pois não depende da resolução da textura.
Materiais
A complexidade do material pode aumentar o custo de pixel de uma renderização. Quanto mais instruções houver para cada pixel, mais tempo a renderização levará para calcular seu valor final. Materiais opacos são os mais baratos, mas podem diferir muito com base no modelo de sombreamento ou no código do shader base.
Você pode encontrar uma leitura da contagem de instruções de um material na janela Estatísticas dentro do Editor de material.
A contagem de instruções também aumentará dependendo do número de funções matemáticas existentes em um material. Quanto mais nós houver, mais caro será o material para renderizar. Algumas operações específicas também têm um custo maior. Tente limitar a contagem de instruções ao criar materiais mais complexos.
Materiais translúcidos e transparentes são alguns dos tipos de materiais mais caros. Camadas individuais de translucidez têm um alto custo por pixel. Quando várias camadas de transparência são empilhadas e renderizadas, o custo é muito maior. Isso é conhecido como overdraw.
Faróis e lanternas traseiras de veículos são exemplos de áreas problemáticas com transparência. Em muitos casos, usamos mapas de textura pintados à mão para reduzir a complexidade do material. Formas complexas e profundas podem ser bem ilustradas, mesmo com uma textura plana.
Otimizar a resolução da textura
Texturas de alta resolução exigem muito espaço para armazenamento em um dispositivo e na memória de texturas do dispositivo. Texturas maiores exigem mais pixels para renderizar e processar. Embora possam aumentar a fidelidade, há um retorno decrescente no tamanho da textura, dado a resolução da tela do dispositivo e o ângulo de visão da textura. É importante usar a menor textura possível para obter o nível de fidelidade desejado.
Para determinar as texturas necessárias, primeiro você precisa finalizar a posição da câmera e o campo de visão (CDV) do qual visualizará o modelo. Isso ajudará a determinar o espaço de tela de todas as malhas e materiais.
Após determinar a posição da câmera, você pode usar uma textura de depuração especial para determinar a resolução de textura a ser usada para os vários materiais. Essa textura usa o comportamento de mipmapas para determinar qual resolução é necessária para diferentes componentes, aplicando cores diferentes em cada mipmapa. Isso facilita a identificação do mip que o material está usando e de qual resolução de textura deve ser usada.
Conecte a textura incluída ao canal Emissivo de um material não iluminável e aplique esse material à malha. Ao visualizar a malha da distância adequada da câmera, a codificação de cores indicará qual nível de mip a engine está usando para renderizar. O nível mais alto observado deve ser o tamanho da textura nativa dos mapas de normal e oclusão de ambiente.
Tamanho do pacote e tempo de inicialização
Ao empacotar um aplicativo e seus ativos, há uma escolha entre o tamanho do pacote no disco e o desempenho de inicialização do tempo de execução.
Quando a compactação ZLib estiver habilitada, o tamanho do pacote da aplicação será menor. No entanto, isso exige mais tempo da CPU para carregar o aplicativo, o que pode reduzir a velocidade de inicialização. Para otimizar o tempo de inicialização, você pode desabilitar a compactação.
Configurações de streaming recomendadas
As seguintes configurações de streaming são recomendadas em DefaultEngine.ini. Elas fornecem mais tempo na inicialização de um aplicativo para carregamento assíncrono de ativos, o que pode melhorar o tempo de inicialização.
[/Script/Engine.StreamingSettings]
s.PriorityAsyncLoadingExtraTime=275.0
s.LevelStreamingActorsUpdateTimeLimit=250.0
s.PriorityLevelStreamingActorsUpdateExtraTime=250.0Configurações de empacotamento recomendadas
As configurações de empacotamento a seguir são recomendadas em DefaultEngine.ini. Essas configurações reduzem a quantidade de compactação usada ao empacotar ativos, pois arquivos .pak descompactados são carregados com uma velocidade consideravelmente superior em comparação com os arquivos compactados com ZLib na inicialização.
[/Script/UnrealEd.ProjectPackagingSettings]
bCompressed=False
BuildConfiguration=PPBC_Development
bShareMaterialShaderCode=True
bSharedMaterialNativeLibraries=True
bSkipEditorContent=TrueAnalisar o tamanho do pacote no disco
A Unreal Engine apresenta várias ferramentas úteis que podem fornecer insights sobre o consumo de dados dos ativos.
Mapa de tamanho
O Mapa de tamanho lê e compara o consumo relativo de memória dos ativos no editor. Para usá-lo, você deve habilitar o plugin AssetManagerEditor. Depois disso, você pode acessá-lo clicando com o botão direito do mouse em uma pasta no Navegador de Conteúdo e selecionando Mapa de tamanho no menu de contexto.
O Mapa de tamanho exibe uma janela com ícones que representam a quantidade de memória consumida por pastas e arquivos. Quanto maior o ícone, mais espaço o arquivo ocupa.
Para obter mais informações sobre como usar o Mapa de tamanho, consulte Preparação e segmentação.
O Mapa de tamanho lê a área ocupada pelos ativos conforme eles são usados no editor. Após o empacotamento do projeto, o consumo de memória será diferente. Isso ocorre devido aos diferentes tipos de compactação que ocorrem durante o processo de preparação. Como regra geral, o mapa de tamanho representará o maior tamanho possível que um ativo pode ocupar.
Estatísticas
A ferramenta Estatísticas oferece informações mais detalhadas sobre o uso de ativos em um nível. Você pode localizá-la no menu suspenso Janela.
A janela Estatísticas detalha o número de ativos nos seus arquivos de nível e pode exibir todos os níveis ou apenas níveis específicos. Estatísticas de primitivas lista informações sobre o número de triângulos, consumo de memória e contagem.
Outros dados exibidos nessa lista incluem uso de textura e informações de iluminação de malha estática. O modo de lista da janela Estatísticas pode ilustrar rapidamente quais ativos estão consumindo mais memória. Os dados de Estatísticas do preparador também são muito úteis, pois listam todos os ativos que foram preparados no último processo de empacotamento.
Relatórios de memória
Enquanto as ferramentas Estatísticas e Mapa de tamanho mostram o consumo de dados dos arquivos dentro do Unreal Editor, o comando do console Memreport -full pode ser usado em uma instalação do aplicativo inicializada em um dispositivo alvo. Isso fornece uma visão detalhada e precisa do tamanho dos arquivos, conforme eles existirão com as configurações de compressão do dispositivo.
Depois que o app estiver na configuração Desenvolvimento e carregado no dispositivo, você poderá abrir a janela do console e inserir o comando. Esse instantâneo de memória é salvo no diretório do projeto, no dispositivo. O diretório costuma ser Game/[YourApp]/[YourApp]/Saved/Profiling/Memreports/, mas isso pode variar.
O arquivo .memreport é um arquivo de texto que pode ser lido na maioria dos editores de texto. O início do texto inclui algumas informações sobre a memória alocada e os tamanhos dos pools, enquanto a maior parte do texto mostra um registro dos níveis que foram carregados, estatísticas de RHI, alvos de renderização, informações da cena e muito mais. Todas essas informações são valiosas, pois representam os dados reais que passaram pelo processo de preparação e empacotamento.
Se você pesquisar o termo Listagem de todas as texturas, encontrará uma lista de todas as texturas do seu aplicativo, junto com informações detalhadas sobre o tipo, grupo, tamanho e consumo de memória das texturas. A lista é classificada por tamanho de memória, com as texturas maiores apresentadas primeiro. Essa é uma maneira rápida e fácil de identificar as texturas que estão consumindo mais memória.
Análise do tempo de inicialização
Os fatores que afetam o tempo de inicialização incluem:
O tempo necessário para carregar e descompactar os ativos iniciais
O tamanho geral do seu aplicativo
Quaisquer plugins que precisam ser ativados na instalação do usuário
A quantidade de dados de strings que precisam ser analisados
Qualquer alocação ou fragmentação de memória no dispositivo do usuário
Existem várias ferramentas diferentes disponíveis para analisar o tempo de inicialização do seu aplicativo, mas a Unreal Insights é a mais recomendada, pois pode analisar os dados de desempenho remotamente a partir de um dispositivo alvo. Para obter informações completas sobre esse conjunto de ferramentas, consulte a seção Unreal Insights.
Para obter um exemplo de como usar a Unreal Insights em um aplicativo Android, confira Unreal Insights em dispositivos Android.