Parte de otimização de desempenho do Unity

[Habilidades de unidade] A tecnologia de otimização em Unity_Mom diz que as meninas devem ser independentes e autossuficientes blog-CSDN blog_Modelo de otimização de unidade

Habilidades de otimização de unidade (médio) - Zhihu



Dicas de otimização do Unity (Parte 2) - Zhihu

1. Direção de otimização

1. Otimização de vértices

     (1) Otimize a geometria : Reduza o máximo possível o número de triângulos no modelo e reutilize os vértices tanto quanto possível

    (2) Use tecnologia LOD (nível de detalhe)

     Explicação detalhada da tecnologia de otimização UnityLOD_丶Bo Liang’s blog-CSDN blog_lod Optimization

    (3) Use tecnologia de seleção de oclusão

2. Otimização de pixels

(1) O foco da otimização de pixels é reduzir o overdraw. Overdraw refere-se a um pixel sendo desenhado várias vezes. A chave é controlar a ordem do desenho .

Ao desenhar objetos transparentes devemos tentar desenhá-los de frente para trás. A razão pela qual desenhar de frente para trás pode reduzir o overdraw é a verificação de profundidade.

No Unity, os objetos definidos para a fila "Geometria" no Shader são sempre desenhados de frente para trás , enquanto os objetos em outras filas fixas (como "Transparente", "Sobrela", etc.) são desenhados de trás para frente. . Por exemplo, para o skybox , ele cobre quase todos os pixels e sabemos que sempre estará atrás de tudo, então sua fila pode ser definida como "Geometry+1" .

(2) Podemos entregar o desenho da GUI e o desenho da cena 3D para câmeras diferentes, e a faixa de ângulo de visão da câmera responsável pela cena 3D não deve se sobrepor tanto quanto possível à GUI.

(3) Reduzir a iluminação em tempo real : Se uma cena contém três fontes de luz pontuais pixel por pixel e usa um sombreador pixel por pixel, é provável que as chamadas de desenho sejam triplicadas e os overdraws também sejam aumentados. Fontes de luz pixel por pixel, os objetos iluminados por essas fontes de luz são renderizados novamente. O pior é que nem o lote dinâmico nem o lote dinâmico podem ser agrupados para essas passagens pixel por pixel, ou seja, eles quebram o lote.

(4) Use mapas de luz

Armazene antecipadamente as informações de iluminação na cena em uma textura de iluminação e, em seguida, só precisará amostrar as informações de iluminação com base na textura em tempo de execução.

3. Otimização da CPU

Reduzir chamadas de sorteio

        (1) Lote : Para objetos que utilizam o mesmo material, a única diferença entre eles é a diferença nos dados do vértice, ou seja, as malhas utilizadas são diferentes. Podemos mesclar esses dados de vértice e enviá-los para a GPU para concluir um processamento em lote.

        As condições para a unidade realizar o processamento dinâmico em lote são que os objetos usem o mesmo material e atendam a algumas condições específicas. Os vértices não podem exceder 900 e a escala xyz deve ser unificada. Objetos que usam mapa de luz não serão processados ​​em lote. Sombreadores multipassagem interromperá o processamento em lote e aceitará em tempo real. Nem os sombra .

        Processamento em lote estático: marque "Sinalizador estático" e clique na caixa suspensa triangular atrás de Estático. Veremos que esta etapa realmente define muitas coisas. O que queremos aqui é apenas "Batch estático". Se houver alguns objetos compartilhando a mesma malha antes do lote estático (por exemplo, duas caixas idênticas), então cada objeto terá uma cópia da malha, ou seja, uma malha se tornará múltiplas malhas. Enviado para a GPU, a desvantagem é que ocupa mais memória.

 (2) Mesclar texturas (Atlas): mesclar o máximo possível de texturas pequenas em uma textura grande (Atlas)

4. Otimização de largura de banda

(1) Reduza o tamanho da textura e ajuste os parâmetros através do painel Avançar da textura.As principais opções relacionadas à otimização incluem "Gerar mapas Mip", "Tamanho máximo" e "Formato".

"Generate Mip Maps" criará muitas texturas pequenas de tamanhos diferentes para a mesma textura, formando uma pirâmide de texturas. No jogo, você pode selecionar dinamicamente qual textura usar com base na distância do objeto, para que ocupe mais memória.

"Max Size" determina o comprimento e a largura da textura. Se a textura que usamos exceder esse valor máximo, o Unity irá reduzi-la para atender a essa condição.

“Format” é responsável pelo modo de compressão utilizado pela textura. Normalmente, basta selecionar este modo automático e o Unity será responsável por selecionar o modo de compressão apropriado de acordo com as diferentes plataformas.

2. Otimize os detalhes

1. LOD, o código só será executado quando necessário

        Personagens fora da tela não são contados para atualizações de animação, efeitos de habilidade, barras de saúde para trapaça, etc. Os personagens fora da tela estão inativos e apenas o protagonista pode trapacear, etc.

2. Limitação de quadros, balanceamento de carga

Limitar frames com base no modelo do jogador

3. Algoritmo

Algumas operações no próprio código. Por exemplo, otimizar operações físicas, trocar espaço por tempo, usar pré-cálculo de consulta de tabela e outros métodos para acelerar os cálculos e reduzir indexação frequente, FindGetComponentd e diversas operações.

4. Interface da unidade

Tente usar GetComponent, AddComponent (também gera GC), Find e outras operações o mínimo possível

 Funções vazias como OnGUI, FixedUpdate, Update, etc. também terão sobrecarga gc, porque haverá sobrecarga na chamada da camada C++ para C#.

 MainCamera é uma operação transversal. Não a chame com frequência quando há muitas câmeras.

Quando a posição e a rotação são modificadas ao mesmo tempo, use o método SetPositionAndRotation() para defini-las todas de uma vez.

5. Física

Em termos de otimização, os pares de colisão podem ser reduzidos por meio de camadas. Tente usar BoxCollider em vez de MeshCollider . Não abra o Raycaster para controles que não exigem clique na interface da UI. Use a inspeção radiográfica mais básica.

6.IL2CPP e C++

Defina a compilação do Unity como IL2CPP e a eficiência de execução da versão C++ será bastante melhorada.

7. Animação

Se Animator.Update ou MeshSkinning.Udpate for encontrado no Prifile, a sobrecarga será relativamente grande, indicando que a ação pode precisar ser otimizada.

  

otimização:

(1) Abra Otimizar

GameObject, você pode remover alguns ossos de nós inválidos. Observe que se houver nós personalizados, você precisará arrastá-los para a lista não otimizada.  

   

(2) Compressão:

Ativar KeyframeReduction pode compactar muitos quadros-chave desnecessários. Quanto maior o valor, maior será a taxa de compactação e mais grave será a distorção.

(3) Pesos Ósseos:

Os vértices são afetados por ossos. Para ambientes não exigentes, um osso pode ser suficiente. Pode ser definido por modelo ou alterado globalmente em tempo real.

  

(4) BakeMesh:

Se precisar exibir um grande número de modelos na mesma tela, você pode usar SkinnedMeshRenderer.BakeMesh para transformar a animação em um modelo, para que possa ser mesclada durante a renderização (a animação não pode ser mesclada). DC pode ser bastante reduzido e os cálculos de skinning são omitidos.No entanto, a desvantagem é que a memória é aumentada e a sobrecarga da CPU do DynamicBatching é aumentada, resultando em pior desempenho.

(5) Sem usar o Animator:

A sobrecarga do Animator é uma ordem de magnitude maior que a do Animaton.

(6) Invisível não atualiza a configuração CullCompletely

Porém, deve-se ressaltar que algumas mensagens também irão parar, o que pode causar problemas caso haja dependência de animação.

(7) Bone LOD, GPU Skinning (alguns dispositivos e situações serão mais lentos), usando Bone em vez de CS, etc.

8. IU

A UI também é uma grande despesa, geralmente representando 30% -50%. UGUI corresponde à sobrecarga de Canvas.BuildBatch e Canvas.SendWillRenderCanvases em Profile
, que é semelhante ao LastUpdate do NGUI. Existem muitos artigos sobre otimização de UI, que são brevemente listados aqui.

 (1), separação dinâmica e estática:

Porque a IU será mesclada. O NGUI é reconstruído com base no Panel e o UGUI é reconstruído com base no Canvas para evitar que a UI dinâmica acione a mesclagem e faça com que a UI estática seja mesclada.

 (2), pré-carregado, residente, liberação instantânea :

A UI é dividida por tipo. UIs maiores e comumente usadas ficarão presas durante a criação e podem ser pré-carregadas. Da cidade principal ao cenário de batalha, garantindo o pico de memória, a interface do herói, a interface da união e outras memórias permanentes podem acelerar a velocidade de carregamento.Após a medição e otimização reais, a velocidade de carregamento mais que dobrou. Outras interfaces usadas com pouca frequência são divididas em interfaces pequenas, carregadas imediatamente e descarregadas quando fechadas para economizar memória. Deve-se observar que muitos nós de UI também levarão a um carregamento lento. Costumávamos carregar por 10 segundos, dos quais a UI serializada representava cerca de metade do tempo (teste de pré-carregamento de textura). Se o número de nós de UI for reduzido , será muito grande e desmontado.

 (3), Atlas

Dividir razoavelmente o atlas da IU e distinguir entre atlas públicos (residentes) e atlas não públicos. Se for muito grande, levará facilmente ao carregamento redundante, o que facilmente levará ao uso excessivo de memória e à sobrecarga de troca de memória e memória de vídeo. Muito pequeno pode facilmente causar fragmentação da memória e afetar a eficiência. As regras são complexas.

(4), conjunto de memória

UIs criadas com frequência, como alias de UI, usam pools de memória para reduzir o tempo de criação e a fragmentação da memória.

 (5)、Ativo/Desativo

Não é recomendado alternar frequentemente a interface da UI entre Ativo/Desativo, pois isso acionará a operação de mesclagem da UI. Você pode movê-la para fora da tela ou definir a Camada. Porém, deve-se ressaltar que se for movido para fora da tela, ainda será mesclado e renderizado.Se não for exibido por muito tempo, é melhor usar Deactive, que depende da situação.

 (6), UISprite em vez de UITexture: a textura não será mesclada.

 (7) A UI invisível não será atualizada se não for movida: como o nome da barra de saúde, etc.

 (8) Para componentes de grupo de layout e grupo de telas, qualquer nó filho que altere seu nó pai usará getcompent para localizar o grupo de layout. Estas são as duas principais armadilhas da UGUI do Unity.

 (9) Verifique se o alvo Raycast que não precisa ser captado está desligado .

 (10) Pré-carregamento de recursos: Por exemplo, o pré-carregamento da UI introduzido anteriormente, todos os recursos devem ser pré-carregados se a memória permitir, combinados com o pool de memória. Toda a lógica de monetização, personagens, monstros, adereços e UI em nosso jogo serão pré-carregados e haverá um conjunto de estratégias de expansão e reciclagem do pool.

 (11), Pré-carregamento de shader.

9、GC

GC é uma chamada de sistema muito cara e também a principal causa da maioria dos atrasos. Não pode ser totalmente controlada. Portanto, precisamos minimizar a alocação excessiva de memória heap de código para evitar o acionamento frequente do GC. Ao mesmo tempo, também podemos GC ativamente durante o carregamento ou quando o desempenho não é sensível.

(1) Use StringBuilder em vez de string para reduzir a sobrecarga do GC . Não use rich text para alterar a cor do componente Text diretamente, modificando a cor do componente Text.

 (2), conjunto de memória de objetos de classe . Todos aqueles que são criados e excluídos com frequência devem ser usados . Dois propósitos: reduzir o tempo de carregamento, criação e liberação, reduzir a fragmentação da memória e reduzir a frequência do GC.

(3) Interface Unity: AddComponent , OnGUI, frequência de mesclagem de UI, delegado, etc. (Alguns Foreach, corrotina, etc. Unity foi otimizado)

(4) Otimização de GC de plug-ins: Os códigos-fonte de alguns plug-ins, como Behavior Tree e FMODStudio, foram modificados para reduzir GC.

3. Otimização de GPU

(1) A otimização do DrawCall geralmente envolve a fusão da malha de material, portanto ela é colocada na GPU. Renderizar um objeto que possui uma malha e carrega um material por vez usa uma chamada de desenho. Pode-se entender que chamar DC uma vez altera um pincel para desenhar um objeto na prancheta.

(2) Número de lados

A cena inteira contém menos de 10 DCs, que são combinados e produzidos pelo artista ou plug-in. A fusão estática aumentará o tempo de carregamento e a memória, e a fusão dinâmica também aumentará a memória e a sobrecarga da CPU na fusão.

(3)、LOD

A otimização da GPU também pode ser feita por meio de LOD, que pode ser feita por meio de modelo LOD , osso LOD, partícula LOD, material LOD, terreno LOD, etc. Por exemplo, configurações diferentes permitem efeitos diferentes, permitem pós-processamento, etc.

(4), bloqueio

Seleção de oclusão: como o nome sugere, áreas que estão bloqueadas e não podem ser vistas não são renderizadas, como objetos atrás de paredes. A seleção de oclusão pode ser calculada por CPU ou GPU.

Oclusão da interface do usuário: por exemplo, a interface do usuário em tela inteira pode ocultar o plano de fundo e economizar energia.

Divisão de cena: como estamos olhando de uma perspectiva aérea, há muito poucas coisas que podem ser bloqueadas, então usamos apenas a divisão de cena.

(5), translúcido

A translucidez custa muito e prejudicará a otimização do pipeline de renderização. Também é difícil compactar texturas usando o canal alfa (especialmente o formato PVR no IOS, que sofre enormes perdas após a compactação de pixels alfa. ETC, DDS, PVR e outros formatos possuem um canal Alpha. A taxa de compressão é igual aos outros 3 canais).

Usar menos/reduzir área: Use o mínimo possível, use para minimizar a área ocupada pela tela e reduzir a taxa de preenchimento de pixels.

(6), partículas

Reduzir a área de cobertura da tela, evitar usar Alpha, mesclar materiais e malha, LOD = reduzir o número e efeito dos emissores de partículas de acordo com o modelo ou distância, quadros sequenciais: usar quadros sequenciais para efeitos especiais em alguns jogos de cima para baixo também pode muito melhorar a eficiência. .

(7), outro

  • Configurações de renderização: sombras, neblina, anti-dentes, sincronização vertical, anisotropia, renderização multithread, esqueleto computado por GPU, vértices afetados por ossos, partículas suaves e muito mais. Cada projeto tem requisitos diferentes.
  • Reduza a resolução de renderização: Reduza a resolução do Framebuff para reduzir a sobrecarga e a memória do PS, mas ficará embaçado.Muitos jogos convencionais, como Honor of Kings, reduziram sua resolução no Android.
  • Ajuste dinâmico inteligente: ajuste a configuração em tempo real de acordo com a configuração do jogador e o ambiente do jogo. Equipamentos de baixa configuração ou configurações mais baixas para combate limitarão o quadro. Plug-ins de alta configuração ou cenários de baixa sobrecarga melhorarão dinamicamente a configuração e aumente o limite de quadros. Existe um documento com uma introdução mais detalhada.
  • Pós-processamento: No Unity, você pode entender a sobrecarga de pós-processamento observando o desempenho do Graphics.Blit. O pós-processamento geralmente é um cálculo em nível de pixel. A resolução em dispositivos móveis é geralmente maior do que em PCs, então você precisa prestar mais atenção ao usá-lo.
  • Materiais submateriais multidimensionais não são usados.

4. Otimização de memória

1. Textura compactada ETC/PVR: As texturas ocupam a maior quantidade de recursos. Basicamente, comprimo texturas 3D e comprimo parcialmente texturas 2DUI. Tente usar o formato ETC no Android, use o formato pvr no IOS , o não translúcido tem uma taxa de compressão de 1/8. Esses dois formatos de compactação são semelhantes ao DDS do DX e podem ser renderizados diretamente pela placa gráfica, o que não apenas reduz a memória, mas também reduz o tamanho do pacote e melhora a velocidade de carregamento (JPG e outros formatos têm altas taxas de compactação, mas precisam ser descompactados em cores de 32 bits antes da renderização, o que requer memória adicional e memória de vídeo e sobrecarga adicional de descompressão). Os seguintes pontos precisam ser observados:

(1) Se o efeito de compactação não for bom, ele pode ser reduzido para cores de 16 bits.

(2) Desative o Mipmap: Se a interface do usuário ou o jogo de perspectiva aérea não exigir o Mipmap, ele poderá ser desativado para reduzir o tamanho em 1/3.

(3) Se for usado ETC, o mapa de compressão PVR deve ter uma potência de 2. Considerando a eficiência de renderização e a fragmentação da memória de vídeo, o tamanho máximo do mapa é recomendado como 1024, o mínimo é 64 e o máximo não pode exceder 2048. .

(4) Use Jiugong, texturas simétricas: melhore a taxa de reutilização de textura

(5) Shader: Use Shader para mesclar canais de textura para obter imagens em tons de cinza, etc. O canal alfa armazena alphatest e destaques, um canal da textura armazena sombras e outro canal armazena ao, etc. O canal alfa armazena outros canais da textura para facilitar a compactação, etc. Isso foi muito usado ao trabalhar na Lenda de Xuanyuan.

(6) Compactar animação para reduzir quadros-chave: introduzido anteriormente

(7) Desinstalação oportuna : Ao entrar e sair da cena, ou ao abrir a interface da UI e outros momentos que não são sensíveis ao desempenho, descarregue recursos e chame Resource.UnloadAsset para limpar recursos de referência e destruir , e System.GC.Collect para limpar os recursos do sistema, conforme descrito anteriormente. O AssetBundle é gerado quando carregado e destruído quando descarregado. Esta também é uma armadilha relativamente grande :)

(8) Evite alocação desnecessária de memória heap no nível do código: isso pode ser verificado por meio da análise estática do código, descrita em detalhes em outro artigo.

(9) Evite novas classes frequentes: use pool de memória .

(10) Conexão de string: Reduza a emenda de string, use StringBuilder , etc.

(11) delegado: Devido à lista vinculada interna e às operações de boxe e unboxing, o GC será alto quando a frequência de uso for alta.

(12) Uso adequado de expressões Lambda: Por exemplo, esta é a razão pela qual o sistema de partículas do Unity tinha um GC mais alto antes da versão 5.6.

(13) Se variáveis ​​ou listas temporárias forem geradas com frequência, é recomendável definir uma lista global e usá-la sempre para cálculo.

(14) Deve-se notar que as classes são alocadas no heap e as estruturas são alocadas na pilha.Às vezes, estruturas podem ser usadas.

(15) Vazamento de memória: a unidade é baseada na contagem de referência. Geralmente, vazamentos de memória são recursos que são mantidos e não podem ser liberados. A tendência de crescimento da memória é óbvia e a memória se expande ao alternar cenas repetidamente. Para esta situação, você pode escrever sua própria ferramenta para gerar o log de recursos de cada cenário. Você também pode usar o XCode para analisar a memória ao longo do tempo.

(16) Dados da tabela. As tabelas geralmente não são descarregadas. Recomenda-se usar a desserialização binária em vez de usar strings diretamente e não armazenar várias cópias em cache na memória.Se os dados da tabela forem muito grandes, você pode considerar excluí-los após o uso.

(17) Dados de vértice redundantes: Mapa da interface do usuário A malha exporta cores, normais, etc. que não são aplicáveis. A fusão estática levará a um aumento na memória.

(18) Anti-aliasing/Rendertexture: Ativar o anti-aliasing aumentará a memória e a alta resolução aumentará a memória. Você pode usar Rendertexture de forma intercambiável no pós-processamento e não criar múltiplas cópias.

(19) Número de GameObjects: menos de 1 W. Muitos livros de nós também causarão carregamento e atualização lentos e expansão de memória.

4. Memória Flash

Refletido especificamente no tamanho do pacote, velocidade de carregamento de recursos, etc. A otimização da memória flash é basicamente igual à da memória, mas há exceções. Por exemplo, usar jpg é uma forma de reduzir o tamanho do pacote e aumentar o consumo de memória da CPU. A compactação é o mesmo que a memória. Texturas, animações, tabelas guia, etc.

(1) A função de faixa de código pode ser ativada em plataformas móveis para reduzir o consumo de memória e capacidade causado pelo código. Para classes que usam reflexão, você pode usar a configuração link.xml para resolver o problema. A faixa de código é uma função de otimização fornecida pelo Unity. Ela pré-julgará o caminho de execução do código e removerá funções não utilizadas.

(2) Alguns SDKs são muito grandes e você pode negociar com terceiros para reduzir bibliotecas duplicadas.

(3) l2cpp conterá duas versões de código, ARMv7 e ARM64, portanto haverá dois volumes de código.

(4) Download dinâmico: semelhante ao microcliente. No entanto, não é recomendado em celulares, pois pode causar o uso de dados do jogador.

(5) Recursos redundantes : Ao exportar pacotes, use plug-ins ou ferramentas autoescritas para analisar recursos.

(6) Geração dinâmica de malha de textura: Algumas texturas e modelos regulares podem ser gerados por meio de cálculo, como a famosa substância usada antes, e ao otimizar o terreno no jogo final anterior, apenas a altura do terreno foi salva, e o a altura restante foi salva. A GPU é restaurada para as informações do terreno, que podem ser reduzidas em 1/3 e assim por diante.

5. Rede

1. Reduza o corpo do pacote e compacte: reutilize e mescle o binário para reduzir o corpo do pacote e compacte o pacote de protocolo.

2. Combinação de pacotes: Realize a operação de combinação de pacotes em uma determinada frequência, mescle vários pacotes para reduzir a frequência de envio e reduzir o cabeçalho do pacote.

6. Consumo de energia

1. CPG, otimização de GPU, otimização de rede,

2. Limite de quadros: Os jogos para celular geralmente limitam o quadro a 30 quadros.

3. Reduza a qualidade e os efeitos da imagem, reduza a frequência de atualização e LOD, etc.

Acho que você gosta

Origin blog.csdn.net/qq_35647121/article/details/128864129
Recomendado
Clasificación