Como a renderização sob demanda pode melhorar o desempenho móvel

Nem sempre é desejável renderizar um projeto na maior taxa de quadros possível, por vários motivos, especialmente em plataformas móveis. Historicamente, os desenvolvedores do Unity usaram Application.targetFrameRate ou Vsync count para controlar a velocidade de renderização do Unity. Essa abordagem afeta não apenas a renderização, mas a frequência com que cada parte do Unity é executada. A nova API de renderização sob demanda permite que você desvincule a frequência de renderização da frequência de loop do player.
A renderização sob demanda permite que você pule quadros de renderização enquanto ainda executa o restante do loop do player em alta frequência. Isso pode ser especialmente útil em dispositivos móveis; ignorar a renderização pode trazer economia significativa de desempenho e energia, ao mesmo tempo em que permite que o aplicativo responda a eventos de toque.
Aqui estão alguns exemplos de cenários em que você pode querer diminuir a taxa de quadros:
Menus (por exemplo, o ponto de entrada do aplicativo ou um menu de pausa): Os menus tendem a ser cenas relativamente simples e, portanto, não precisam ser renderizados em velocidade máxima. Se você renderizar menus em uma taxa de quadros mais baixa, ainda receberá entrada durante um quadro que não foi renderizado, permitindo reduzir o consumo de energia e evitar que a temperatura do dispositivo suba a um ponto em que a frequência da CPU possa ser reduzida, mantendo ao mesmo tempo uma interação suave com a interface do usuário.
Jogos baseados em turnos (por exemplo, xadrez): Os jogos baseados em turnos têm períodos de baixa atividade, quando os usuários pensam sobre seu próximo movimento ou esperam que outros usuários façam seus movimentos. Durante esses momentos, você pode diminuir a taxa de quadros para evitar o uso desnecessário de energia e prolongar a vida útil da bateria.
Conteúdo estático: Você pode diminuir a taxa de quadros em aplicativos onde o conteúdo é estático na maior parte do tempo, como na interface de usuário (IU) automotiva.
Gestão de desempenho: Se você quiser gerenciar o uso de energia e as temperaturas do dispositivo para maximizar a vida útil da bateria e evitar a limitação da CPU, principalmente se estiver usando o pacote Adaptive Performance, você pode ajustar a velocidade de renderização.
Aplicações de aprendizado de máquina ou IA: Reduzir a quantidade de trabalho que a CPU dedica à renderização pode aumentar um pouco o desempenho do processamento pesado que é o foco central do seu aplicativo.
Em todos os lugares! A renderização sob demanda funciona no Unity 2019.3 com todas as plataformas suportadas (consulte os requisitos do sistema) e API de renderização (pipeline de renderização integrado, Universal Render Pipeline e High Definition Render Pipeline).
A API de renderização sob demanda consiste em apenas três propriedades no namespace UnityEngine.Rendering.
1. OnDemandRendering.renderFrameInterval
Esta é a parte mais importante. Ele permite que você obtenha ou defina o intervalo do quadro de renderização, que é um fator de divisão de Application.targetFrameRate ou QualitySettings.vSyncCount, para definir a nova taxa de quadros. Por exemplo, se você definir Application.targetFrameRate como 60 e OnDemandRendering.renderFrameInterval como 2, somente um quadro sim, outro não será renderizado, gerando uma taxa de quadros de 30 fps.
2. OnDemandRendering.effectiveFrameRate
Esta propriedade fornece uma estimativa da taxa de quadros em que seu aplicativo será renderizado. A estimativa é determinada usando os valores de OnDemandRendering.renderFrameInterval, Application.targetFrameRate, QualitySettings.vSyncCount e a taxa de atualização da tela. Mas tenha em mente que isso é uma estimativa e não uma garantia; seu aplicativo pode renderizar mais lentamente se a CPU estiver sobrecarregada com outras coisas, como scripts, física, rede, etc.
3. OnDemandRendering.willThisFrameRender
Isso simplesmente informa se o quadro atual será renderizado na tela. Você pode usar quadros não renderizados para fazer algum trabalho adicional que exija mais da CPU, como operações matemáticas pesadas, carregar ativos ou gerar prefabs.
- Embora os quadros não sejam renderizados com tanta frequência, os eventos serão enviados aos scripts em um ritmo normal. Isso significa que você pode receber uma entrada durante um quadro que não é renderizada. Para evitar o aparecimento de atraso de entrada, recomendamos que você chame OnDemandRendering.renderFrameInterval = 1 durante a entrada para manter botões, movimentos, etc. responsivos.
- Situações que exigem muito script, física, animação, etc., mas não são renderizadas, não se beneficiarão do uso da renderização sob demanda. Os resultados podem parecer instáveis e com redução insignificante no uso de CPU e energia.
Aqui está um exemplo simples mostrando como a renderização sob demanda pode ser usada em um menu para renderizar a 20 fps, a menos que haja entrada.
using UnityEngine;
using UnityEngine.Rendering;
public class Menu : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = 60;
// When the Menu starts, set the rendering to target 20fps
OnDemandRendering.renderFrameInterval = 3;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0) || (Input.touchCount > 0))
{
// If the mouse button or touch detected render at 60 FPS (every frame).
OnDemandRendering.renderFrameInterval = 1;
}
else
{
// If there is no mouse and no touch input then we can go back to 20 FPS (every 3 frames).
OnDemandRendering.renderFrameInterval = 3;
}
}
}

Aqui está um projeto de exemplo que demonstra como a renderização sob demanda pode ser usada em diversas situações.
Conte-nos nos fóruns como a renderização sob demanda está funcionando para você. Nós o testamos no Windows, macOS, WebGL, iOS e Android, tanto no Unity Editor quanto com players autônomos, mas estamos sempre abertos a mais feedback.