Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Configurando XR

Introdução ao sistema de XR no Godot

O Godot fornece um sistema XR modular que abstrai muitas das diferentes especificidades da plataforma XR longe do usuário. No núcleo está o XRServer, que atua como uma interface central para o sistema XR que permite aos usuários descobrir interfaces e interagir com os componentes do sistema XR.

Cada plataforma XR suportada é implementada como uma XRInterface. Uma lista de plataformas suportadas pode ser encontrada na página de lista de recursos aqui. As interfaces suportadas registram-se no XRServer e podem ser consultadas com o método find_interface no XRServer. Quando a interface desejada é encontrada, ela pode ser inicializada chamando initialize na interface.

Aviso

Uma interface registrada significa apenas que ela está disponível; se a interface não for suportada pelo sistema hospedeiro, a inicialização pode falhar e retornar false. Isso pode ter muitos motivos e, infelizmente, os motivos diferem de plataforma para plataforma. Pode ser porque o usuário não instalou o software necessário ou porque o usuário simplesmente não conectou o headset. Você, como desenvolvedor, deve, portanto, reagir adequadamente caso uma interface falhe ao inicializar.

Devido aos requisitos especiais para saída em XR, especialmente para dispositivos visores de realidade virtual que fornecem imagens diferentes para cada olho, o XRServer no Godot substituirá vários recursos no sistema de renderização. Para dispositivos autônomos, isso significa que a saída final é gerenciada pela XRInterface e o sistema de saída usual do Godot é desativado. Para dispositivos XR de desktop que funcionam como uma segunda tela, é possível dedicar uma Viewport separada para gerenciar a saída XR, deixando a janela principal do Godot disponível para exibir conteúdo alternativo.

Nota

Observe que apenas uma interface pode ser responsável por gerenciar a saída para um dispositivo XR, esta é conhecida como a interface primária e, por padrão, será a primeira interface que for inicializada. O Godot atualmente suporta apenas implementações com um único headset. É possível, mas cada vez mais incomum, ter uma interface secundária, por exemplo, para adicionar rastreamento a um dispositivo que de outra forma seria apenas 3DOF.

Existem três tipos de nós específicos de XR que você encontrará em quase todas as aplicações de XR:

  • XROrigin3D representa, para todos os efeitos práticos, o ponto central do seu espaço de jogo. Essa é uma afirmação supersimplificada, mas entraremos em mais detalhes mais tarde. Todos os objetos rastreados no espaço físico pela plataforma XR são posicionados em relação a este ponto.

  • XRCamera3D representa a câmera (estéreo) que é usada ao renderizar a saída para o dispositivo XR. O posicionamento deste nó é controlado pelo sistema XR e atualizado automaticamente usando as informações de rastreamento fornecidas pela plataforma XR.

  • XRController3D representa um controle usado pelo jogador, comumente existem dois, um segurado em cada mão. Esses nós dão acesso a vários estados nesses controles e enviam sinais quando o jogador pressiona botões neles. O posicionamento deste nó é controlado pelo sistema XR e atualizado automaticamente usando as informações de rastreamento fornecidas pela plataforma XR.

Existem outros nós relacionados a XR e há muito mais a dizer sobre esses três nós, mas entraremos nisso mais adiante.

Qual renderização usar

Godot has 3 renderer options for projects: Compatibility, Mobile, and Forward+. The current recommendation is to use the Mobile renderer for any desktop VR project, or any project running on a standalone headset like the Meta Quest 3. XR projects will run with the Forward+ renderer, but it isn't well optimized for XR right now compared to the other two.

OpenXR

OpenXR is the industry standard API that allows different XR platforms to interact with XR applications. This standard is an open standard maintained by the Khronos Group and thus aligns very well with Godot's interests. We are thus using this as the example in this introduction. Check the respective chapters for differences in other APIs.

A implementação Vulkan do OpenXR está intimamente integrada ao Vulkan, assumindo parte do sistema Vulkan. Isso requer uma integração estreita de certos recursos gráficos principais no renderizador Vulkan, os quais são necessários antes que o sistema XR seja configurado. Esse foi um dos principais fatores decisivos para incluir o OpenXR como uma interface principal.

Isso também significa que o OpenXR precisa estar ativado quando o Godot inicia para configurar as coisas corretamente. Verifique a configuração Enabled nas configurações do seu projeto em XR > OpenXR.

../../_images/openxr_enabled.webp

Você também pode encontrar várias outras configurações relacionadas ao OpenXR aqui. Elas não podem ser alteradas enquanto seu aplicativo estiver em execução. As configurações padrão nos ajudarão a começar, mas para obter mais informações sobre o que está aqui, consulte Configurações OpenXR.

Você também precisará ir em XR > Shaders nas configurações do projeto e marcar a caixa Enabled para ativá-los. Depois de fazer isso, clique no botão Save & Restart.

../../_images/xr_shaders.webp

Aviso

Muitos efeitos de pós-processamento ainda não foram atualizados para suportar a renderização estereoscópica. O uso destes terá efeitos adversos.

Configurando a cena XR

Cada aplicativo de XR precisa de pelo menos um nó XROrigin3D e um nó XRCamera3D. A maioria terá dois XRController3D, um para a mão esquerda e outro para a direita. Tenha em mente que os nós de câmera e controle devem ser filhos do nó de origem. Adicione esses nós a uma nova cena e renomeie os nós de controle para LeftHand e RightHand; sua cena deve se parecer com isso:

../../_images/xr_basic_scene.webp

Os ícones de aviso são esperados e devem desaparecer depois que você configurar os controles. Selecione a mão esquerda e configure-a da seguinte forma:

../../_images/xr_left_hand.webp

E a mão direita:

../../_images/xr_right_hand.webp

No momento, todos esses nós estão no chão; eles serão posicionados corretamente em tempo de execução. Para ajudar durante o desenvolvimento, pode ser útil mover a câmera para cima para que seu y seja definido como 1.7, e mover os nós de controle para -0.5, 1.0, -0.5 e 0.5, 1.0, -0.5 para as mãos esquerda e direita, respectivamente.

Em seguida, precisamos adicionar um script ao nosso nó raiz. Adicione o seguinte código neste script:

extends Node3D

var xr_interface: XRInterface

func _ready():
    xr_interface = XRServer.find_interface("OpenXR")
    if xr_interface and xr_interface.is_initialized():
        print("OpenXR initialized successfully")

        # Change our main viewport to output to the HMD.
        get_viewport().use_xr = true
    else:
        print("OpenXR not initialized, please check if your headset is connected")

Nota

There is no restriction to where this code is executed from. It is common to add this script to the XROrigin3D node or as a Node3D child of the root node.

The OpenXR interface is unique in that we have to start it before the project loads, hence is_initialized is checked here. Most interfaces require a call to their initialize function instead.

If you wish to support multiple XR interfaces, say release a game both targeting OpenXR hardware and deploy over WebXR, you can check one after the other until a functioning interface is found.

Aviso

As OpenXR outputs the rendering result to an HMD, which often runs at a higher framerate than the monitor, Godot's V-Sync settings are ignored and V-sync will always be disabled.

Instead, OpenXR perform its own frame timing to ensure a consistent framerate.

Observe também que, por padrão, o motor de física também roda a 60Hz e isso pode resultar em uma física tremida. Você deve definir Engine.physics_ticks_per_second para um valor mais alto.

If you run your project at this point in time, everything will work but you will be in a dark world. So to finish off our starting point add a DirectionalLight3D and a WorldEnvironment node to your scene. You may wish to also add a mesh instance as a child to each controller node just to temporarily visualize them. Make sure you configure a sky in your world environment.

Agora execute o seu projeto, você deve estar flutuando em algum lugar no espaço e ser capaz de olhar ao redor.

Nota

Embora a troca tradicional de fases/níveis possa definitivamente ser usada com aplicativos XR, onde essa configuração de cena é repetida em cada nível, a maioria acha mais fácil configurar isso uma vez e carregar os níveis como uma sub-cena. Se você alternar as cenas e replicar a configuração XR em cada uma delas, certifique-se de não executar a função initialize várias vezes. O efeito pode ser imprevisível dependendo da interface XR utilizada.

Para o restante desta série de tutoriais básicos, criaremos um jogo que utiliza uma única cena.