Estabilização de holograma — MRTK2
Desempenho
Para que a plataforma e o dispositivo de realidade mista subjacentes produzam os melhores resultados, é importante alcançar taxas de quadros de desempenho. A taxa de quadros alvo (por exemplo: 60 FPS ou 90 FPS) varia entre plataformas e dispositivos. No entanto, as aplicações de realidade mista que atendem à taxa de quadros terão hologramas estáveis, bem como rastreamento de cabeça eficiente, rastreamento de mãos e muito mais.
Rastreamento de ambiente
A renderização holográfica estável depende fortemente do rastreamento da pose da cabeça pelo dispositivo da plataforma e do dispositivo. Unity renderizará a cena a cada quadro da pose da câmera estimada e fornecida pela plataforma subjacente. Se esse rastreamento não seguir corretamente o movimento real da cabeça, os hologramas aparecerão visualmente imprecisos. Isso é especialmente evidente e importante para dispositivos de RA como HoloLens, onde os usuários podem relacionar hologramas virtuais com o mundo real. O desempenho é significativo para um rastreamento confiável da cabeça, mas também pode haver outros recursos importantes. Os tipos de elementos do ambiente que afetam a experiência do usuário dependerão das especificidades da plataforma de destino.
Windows Mixed Reality
A plataforma Windows Mixed Reality fornece algum material de referência para estabilizar hologramas na plataforma. No entanto, há um punhado de ferramentas-chave que os desenvolvedores podem utilizar para melhorar a experiência visual do holograma para os usuários.
Compartilhamento de buffer de profundidade
Os desenvolvedores Unity têm a opção de compartilhar o buffer de profundidade do aplicativo com a plataforma. Isso fornece informações, onde existem hologramas para um quadro atual, que a plataforma pode utilizar para estabilizar hologramas por meio de um processo assistido por hardware conhecido como Reprojeção de Estágio Avançado.
Reprojeção em fase avançada
No final da renderização de um quadro, a plataforma Windows Mixed Reality pega os alvos de renderização de cor e profundidade produzidos pelo aplicativo e transforma a saída final da tela para levar em conta qualquer leve movimento da cabeça desde a última previsão de pose de cabeça. O loop de jogo de um aplicativo leva tempo para ser executado. Por exemplo, a 60 FPS, isso significa que o aplicativo está levando ~16.667ms para renderizar um quadro. Mesmo que isso possa parecer uma quantidade minúscula de tempo, a posição do usuário e a orientação de sua cabeça mudarão, resultando em novas matrizes de projeção para a câmera na renderização. A reprojeção em estágio avançado transforma os pixels na imagem final para dar conta dessa nova perspetiva.
Por pixel vs plano de estabilização LSR
Dependendo do ponto de extremidade do dispositivo e da versão do sistema operacional em execução em um dispositivo Windows Mixed Reality, o algoritmo de reprojeção em estágio avançado será executado por pixel ou por meio de um plano de estabilização.
Com base na profundidade por pixel
A reprojeção baseada em profundidade por pixel envolve a utilização do buffer de profundidade para modificar a saída de imagem por pixel e, assim, estabilizar hologramas em várias distâncias. Por exemplo, uma esfera a 1m de distância pode estar na frente de um pilar que está a 10m de distância. Os pixels que representam a esfera terão uma transformação diferente dos pixels distantes que representam o pilar se o usuário tiver inclinado ligeiramente a cabeça. A reprojeção por pixel levará em conta essa diferença de distância em cada pixel para uma reprojeção mais precisa.
Plano de estabilização
Se não for possível criar um buffer de profundidade preciso para compartilhar com a plataforma, outra forma de LSR utiliza um plano de estabilização. Todos os hologramas em uma cena receberão alguma estabilização, mas os hologramas situados no plano desejado receberão a máxima estabilização de hardware. O ponto e o normal para o plano podem ser fornecidos à plataforma através da API HolographicSettings.SetFocusPointForFrame fornecida pela Unity.
Formato do buffer de profundidade
Se tiver como alvo o HoloLens para desenvolvimento, é altamente recomendável utilizar o formato de buffer de profundidade de 16 bits em comparação com o de 24 bits. Isso pode economizar tremendamente no desempenho, embora os valores de profundidade tenham menos precisão. Para compensar a menor precisão e evitar z-fighting, recomenda-se reduzir o plano de clipe distante do valor padrão de 1000m definido por Unity.
Nota
Se estiver usando o formato de profundidade de 16 bits, os efeitos necessários do buffer de estêncil não funcionarão porque o Unity não cria um buffer de estêncil nessa configuração. A seleção do formato de profundidade de 24 bits, por outro lado, geralmente criará um buffer de estêncil de 8 bits, se aplicável na plataforma gráfica de ponto final.
Compartilhamento de buffer de profundidade no Unity
Para utilizar o LSR baseado em profundidade, há duas etapas importantes que os desenvolvedores precisam tomar.
- Em Editar>configurações do>projeto Configurações XR do>Player>SDKs> de realidade virtual habilitam o compartilhamento de buffer de profundidade
- Se estiver direcionada ao HoloLens, recomenda-se selecionar também o formato de profundidade de 16 bits.
- Ao renderizar cores na tela, renderize a profundidade também
Objetos de jogo opacos em Unity geralmente gravam em profundidade automaticamente. No entanto, objetos de texto transparentes & geralmente não gravam em profundidade por padrão. Se utilizar o sombreador padrão MRTK ou o Text Mesh Pro, isso pode ser facilmente corrigido.
Nota
Para determinar rapidamente quais objetos em uma cena não gravam visualmente no buffer de profundidade, pode-se usar o utilitário Render Depth Buffer nas Configurações do Editor no perfil de Configuração MRTK.
Sombreador padrão MRTK transparente
Para materiais transparentes usando o sombreador MRTK Standard, selecione o material para visualizá-lo na janela Inspetor . Em seguida, clique no botão Corrigir agora para converter o material para gravar em profundidade (ou seja, Z-Write On).
Antes
Depois de
Malha de texto Pro
Para objetos Text Mesh Pro, selecione o TMP GameObject para visualizá-lo no inspetor. No componente material, alterne o sombreador do material atribuído para usar o sombreador MRTK TextMeshPro.
Sombreador personalizado
Se estiver escrevendo um sombreador personalizado, adicione o sinalizador ZWrite à parte superior da definição de bloco Pass para configurar o sombreador para gravar no buffer de profundidade.
Shader "Custom/MyShader"
{
SubShader
{
Pass
{
...
ZWrite On
...
}
}
}
Suportes opacos
Se os métodos acima não funcionarem para um determinado cenário (ou seja, usando Unity UI), é possível ter outro objeto gravando no buffer de profundidade. Um exemplo comum é o uso do Unity UI Text em um painel flutuante em uma cena. Ao tornar o painel opaco ou, pelo menos, escrever em profundidade, tanto o texto como o painel serão estabilizados pela plataforma, uma vez que os seus valores z estão tão próximos um do outro.
WorldAnchors (HoloLens)
Além de garantir que as configurações corretas sejam atendidas para garantir a estabilidade visual, é importante garantir que os hologramas permaneçam estáveis em seus locais físicos corretos. Para informar a plataforma sobre locais importantes em um espaço físico, os desenvolvedores podem aproveitar WorldAnchors em GameObjects que precisam ficar em um só lugar. Um WorldAnchor é um componente adicionado a um GameObject que assume controle absoluto sobre a transformação desse objeto.
Dispositivos como o HoloLens estão constantemente verificando e aprendendo sobre o ambiente. Assim, à medida que o HoloLens rastreia o movimento e a posição no espaço, suas estimativas serão atualizadas e o sistema de coordenadas Unity ajustado. Por exemplo, se um GameObject é colocado a 1 m da câmera no início, como o HoloLens rastreia o ambiente, ele pode perceber que o ponto físico onde o GameObject está localizado está na verdade a 1,1 m de distância. Isso resultaria na deriva do holograma. A aplicação de um WorldAnchor a um GameObject permitirá que a âncora controle a transformação do objeto para que o objeto permaneça no local físico correto (ou seja, atualize para 1,1 m de distância em vez de 1 m em tempo de execução). Para persistir WorldAnchors em sessões de aplicativos, os desenvolvedores podem empregar a WorldAnchorStore para salvar e carregar WorldAnchors.
Nota
Depois que um componente WorldAnchor tiver sido adicionado a um GameObject, não será possível modificar a transformação desse GameObject (ou seja, transform.position = x). Um desenvolvedor deve remover o WorldAnchor para editar a transformação.
WorldAnchor m_anchor;
public void AddAnchor()
{
this.m_anchor = this.gameObject.AddComponent<WorldAnchor>();
}
public void RemoveAnchor()
{
DestroyImmediate(m_anchor);
}
Se você quiser uma alternativa para trabalhar manualmente com Anchors, confira as Ferramentas de Bloqueio Mundial da Microsoft.