florian-olivo-4hbJ-eymZ1o-unsplash

Introdução à performance em jogos

A constante evolução da tecnologia e a capacidade dos computadores no último século influenciou drasticamente nossas vidas em diferentes esferas, desde a realização de cálculos automatizados ao entretenimento e até a maneira de nos relacionarmos. Esse avanço tecnológico foi responsável tanto pela criação dos primeiros jogos eletrônicos quanto por sua evolução aos exemplares que conhecemos hoje. Temos mais capacidade de processamento gráfico e computacional, mas a indústria de jogos e suas soluções sempre está em busca de produtos que possam impressionar e atrair seus consumidores. Soluções inovadoras nesse sentido são gráficos mais sofisticados ou até maior portabilidade de consoles, como podemos ver na ascensão da popularidade de jogos mobile. Portanto, a busca pela performance em um jogo sempre estará na mente de desenvolvedores para que seu produto possua mais valor de mercado e competitividade.

comparação entre os jogos mobile Snake (1997) e Call of Duty Mobile (2019)

Tá, mas o que é exatamente essa performance? 

Existem muitas palavras bem parecidas quando se fala de performance, desempenho, otimização, eficiência etc. Pode-se dizer que todas resumidamente tratam de ‘fazer mais com menos’. Um computador é um sistema que está fazendo diversos cálculos enquanto o usamos. Cada cálculo que ele realiza tem um custo, que muitas vezes passa despercebido para seu usuário. A velocidade que um computador realiza essas contas está principalmente atrelada a 2 coisas: A capacidade de processamento da máquina e a complexidade do problema que ela está a resolver. Então, de uma forma genérica, você melhora o desempenho de um programa ao aumentar a capacidade do sistema que está o executando ou ao reduzir a complexidade dos problemas que ele está calculando. 

Certo, mas onde os jogos entram nisso tudo?

Bem, jogos são programas, portanto estão constantemente fazendo cálculos. Estes que dependem da natureza do jogo, mas envolvem comumente elementos como física, organização de qualquer tipo de recurso (Incluindo personagens, itens etc), carregamento e descarregamento de elementos de som, imagem, modelos 3D, e assim por diante. Basicamente todos os comportamentos de objetos que atuam em um jogo precisam ser calculados em algum momento ‘por trás dos panos’ para que você veja o resultado final.

Além disso, muitos desses trabalhos envolvem elementos visuais complexos que chegam aos olhos do usuário, inclusive é daí que surgiu a necessidade de um componente exclusivo para resolver problemas dessa natureza em nossos computadores, as chamadas placas de vídeo, ou GPUs (Graphics Processing Unit). 

Ademais, outra característica marcante na importância do desempenho nos jogos é que todos os cálculos necessários precisam ser resolvidos num intervalo de tempo muito curto. Toda vez que uma imagem no jogo se altera, algo precisou ser redesenhado para que a nova imagem se apresentasse e passasse a ilusão de movimento. Aliás, esta é uma grande sacada da animação, arte que se você tiver mais interesse em ler sobre, recomendo o compass de Alisson. Comumente o padrão para uma execução fluida ao olho é de 60 FPS (Frames Per Second, ou quadros por segundo). Isso quer dizer que em um segundo, a imagem da tela de um computador está sendo refeita 60 vezes. Então, as contas necessárias para tudo que eu falei precisam ser resolvidas e então as novas imagens precisam ser redesenhadas na tela (mais cálculo), tudo isso dentro de um intervalo de aproximadamente 16.67 milissegundos entre cada um desses frames! 

Qualquer quadro que leve mais do que isso irá gerar atrasos na entrega dos frames, ocasionando nas conhecidas quedas de frame rate. Todos esses processos são ainda por cima inconstantes, dependem do estado em que o jogador se encontra dentro do jogo, então certos frames podem requerer mais tempo que outros, gerando inconsistência de frames e prejudicando a experiência do usuário com um jogo lento ou ‘engasgado’ em determinados momentos.

Mesmo que sutis, quedas de frame rate são perceptíveis, especialmente com frame rates inconsistentes.
Fonte: Reddit

Limitação de CPU vs GPU

Como eu falei, existem dois tipos diferentes de limitação que computadores estão submetidos, o de lógica e o de gráficos. É costumeiro se referir a eles como gargalos de CPU e GPU, respectivamente. O motivo é simplesmente a parte do computador em que se processa estes problemas, o processador para a parte lógica e a unidade gráfica para tudo referente a imagem. O mais comum é problemas serem investigados e identificados nestes gargalos separadamente.

Além dessas 2 limitantes, existe um terceiro fator que é preciso ser observado, o uso de memória. A memória primária de um sistema é aquela para qual um programa será carregado para uso. A mais comumente encontrada em dispositivos é a memória RAM (Random Access Memory). Resumidamente, é interessante notar que ela tem acesso rápido e tamanho limitado, então não podemos jogar coisas indiscriminadamente para lá. O caso de a memória RAM lotar não interrompe a execução de um programa, mas força o processador a realizar procedimentos que podem gerar grandes quedas de performance.

Alguns motores de jogos (softwares para criação de jogos) possuem ferramentas para medir e avaliar esses parâmetros de performance. A Unity, por exemplo, detém do Profiler, onde se pode analisar separadamente o custo de diferentes processos ocorrendo durante a execução de seu jogo.

O profiler permite investigar a performance de um jogo na unity em diferentes esferas.

Técnicas de otimização

Tendo tudo isso em vista, são muitas as variáveis que um desenvolvedor precisa manter em mente quando se trata de performance. Felizmente há um amplo leque de técnicas desenvolvidas para aliviar todos os limitantes identificados:

Redução de polígonos em modelos 3D

Em jogos 3D, os modelos que vemos são feitos por uma espécie de malha virtual constituída de pequenos polígonos, quase imperceptíveis ao nosso olho. Quanto mais polígonos um modelo tiver, mais suave será a textura de um modelo, mais ou menos equivalente à resolução de uma imagem em relação ao seu número de pixels. 

Em troca de um modelo mais rico em detalhes, há o custo do que será necessário para calcular todos aqueles polígonos a mais nas telas. Logo, há um esforço para minimizar o número de polígonos de qualquer modelo, tentando ainda preservar o máximo possível a sua qualidade visual. Para compensar essa ‘redução de detalhes’ e obter retorno gráfico com menor investimento de desempenho, artistas utilizam técnicas engenhosas como UV mapping e Texture baking. 

Comparação de modelos 3D com diferentes quantidades de polígonos.

Pré-carregamento inteligente de recursos

Ao jogar um jogo, você já deve ter se deparado com uma tela de carregamento. As clássicas telas são uma maneira de pré-carregar recursos necessários para uma parte do jogo para que na hora que elas sejam precisas, já tenha-se tudo pronto. Inclusive há casos em que recursos podem estar sendo carregados sem nem o jogador se dar conta, como em um momento de espera como quando um personagem está dentro de um elevador. Enquanto a memória RAM for suficiente para suportar os recursos desejados, a performance não deve ser prejudicada.

Carregamento Parcial de Objetos e Occlusion Culling

Outra técnica conceitualmente simples e ao mesmo tempo brilhante é utilizar somente o que for imediatamente necessário, ignorando o resto. Este conceito se aplica quase perfeitamente à definição de Occlusion Culling, técnica que previne a renderização de objetos que não estão sendo vistos pela câmera.

Na Unity, occlusion culling utiliza de dados associados à câmera principal do projeto para determinar que objetos não precisam ser renderizados naquele frame.

Pooling

Carregar e descarregar objetos de uma cena é um elemento crucial em jogos. Dependendo da frequência e da natureza do objeto, esses processos podem ter um impacto significativo na performance também. Uma técnica para lidar com isso é o Pooling, que consiste em pré-carregar estas instâncias de objetos em uma estrutura de dados e apenas ativá-las de acordo com a necessidade. Na hora que o objeto não é mais preciso, este é apenas desativado.

Considerações finais

Ufa, acredito que resumi as primeiras impressões da melhor forma que podia! Performance em jogos é um desafio recorrente na vida de desenvolvedores e um amplo campo de estudo, é possível inclusive traçar carreiras focadas apenas nisso. Então é claro que não seria possível falar sobre tudo que há para falar por aqui! 

A possibilidade de aplicar todo esse conhecimento técnico na entrega de um produto que promove experiências é algo muito incrível ao meu ver, só me traz mais vontade de continuar aprendendo e apreciando essa mistura fascinante de arte e tecnologia que são os jogos. Quem sabe em outro momento eu tenha a oportunidade de desenvolver mais a respeito do assunto. 

SOBRE NÓS

original.png

Desde 2014, a GamePlan é o destino para desenvolvedores, publicadoras, empreendedores e empresas da indústria de jogos que estejam atrás de Desenvolvimento de Jogos (serious games, co-desenvolvimento internacional, e jogos autorais), Gamificação, Desenvolvimento de Ecossistemas.

Aqui, no Compass, nós compartilhamos de forma descontraída nossos pensamentos e experiências a respeito da indústria e do mercado.

CATEGORIAS

GAMEPLAN TOUR

Venha papear com a gente nos eventos relacionados à indústria a seguir e vamos falar de jogos! 

7 a 10 de Julho
Big Festival