XR_EXT_frame_synthesis

String de nome

XR_EXT_frame_synthesis

Tipo de extensão

Extensão de instância

Número de extensão registrada

212

Revisão

1

Status de ratificação

Não ratificado

Dependências de extensão e versão

OpenXR 1.0

Colaboradores

Jian Zhang, Meta Platforms
Neel Bedekar, Meta Platforms
Xiang Wei, Meta Platforms
Guodong Rong, Meta Platforms
Trevor Dasch, Meta Platforms
Rémi Arnaud, Varjo
Paulo Gomes, Samsung Electronics
Bryce Hutchings, Microsoft
Rylie Pavlik, Collabora
Shuai Liu, ByteDance

Visão geral

Essa extensão oferece suporte para ativar a síntese de frames em aplicativos com base em dados adicionais fornecidos pelo aplicativo. As imagens de vetor de movimento e de profundidade geradas pelo aplicativo podem ser usadas pelo ambiente de execução para fazer extrapolação e reprojeção de frames de alta qualidade para sintetizar um novo frame, proporcionando uma experiência tranquila mesmo quando o aplicativo está sendo executado abaixo da meta de FPS.

Essa extensão foi projetada para ser independente de XR_KHR_composition_layer_depth , e ambas podem ser ativadas e usadas ao mesmo tempo, para fins diferentes. O XrFrameSynthesisInfoEXT :: depthSubImage pode usar dados de profundidade dedicados à síntese de frames, e a resolução pode ser menor que XrCompositionLayerDepthInfoKHR :: subImage . Consulte XrFrameSynthesisConfigViewEXT para a resolução sugerida de depthSubImage .

Enviar imagens de vetor de movimento e de profundidade

A estrutura XrFrameSynthesisInfoEXT é definida como:

typedef struct XrFrameSynthesisInfoEXT {
    XrStructureType                 type;
    const void*                     next;
    XrFrameSynthesisInfoFlagsEXT    layerFlags;
    XrSwapchainSubImage             motionVectorSubImage;
    XrVector4f                      motionVectorScale;
    XrVector4f                      motionVectorOffset;
    XrPosef                         appSpaceDeltaPose;
    XrSwapchainSubImage             depthSubImage;
    float                           minDepth;
    float                           maxDepth;
    float                           nearZ;
    float                           farZ;
} XrFrameSynthesisInfoEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • layerFlags é uma máscara de bits de XrFrameSynthesisInfoFlagsEXT .
  • motionVectorSubImage identifica a imagem vetorial de movimento XrSwapchainSubImage a ser usada para a síntese de frames.
  • motionVectorScale é um XrVector4f que dimensiona a interpretação do vetor de movimento em motionVectorSubImage .
  • motionVectorOffset é um XrVector4f que compensa a interpretação do vetor de movimento em motionVectorSubImage .
  • appSpaceDeltaPose é a transformação incremental aplicada pelo aplicativo, se houver, que afeta a visualização desde o frame anterior. As experiências de locomoção artificial (movimento com script, teletransporte etc.) envolvem o aplicativo transformando todo o XrCompositionLayerProjection :: space de uma pose de espaço do aplicativo para outra entre frames, afetando a visualização em mais do que o movimento rastreado entre frames. O appSpaceDeltaPose precisa ser uma identidade quando não há transformação XrCompositionLayerProjection :: space no aplicativo. O XrPosef :: position em appSpaceDeltaPose precisa ser relativo ao XrCompositionLayerProjection :: space atual do aplicativo .
  • depthSubImage identifica a imagem de profundidade XrSwapchainSubImage a ser usada para a síntese de frames.
  • minDepth e maxDepth são o intervalo de valores de profundidade na depthSubImage e precisam estar no intervalo de [0,0, 1,0] . Isso é semelhante aos valores mínimo e máximo de glDepthRange do OpenGL , mas com o requisito de que maxDepth ≥ minDepth .
  • nearZ é a distância positiva em metros do valor minDepth na cadeia de troca de profundidade. Os aplicativos podem usar um nearZ maior que farZ para indicar que os valores de profundidade estão invertidos. nearZ pode ser infinito.
  • farZ é a distância positiva em metros do valor maxDepth na cadeia de troca de profundidade. farZ pode ser infinito. O ambiente de execução precisa retornar o erro XR_ERROR_VALIDATION_FAILURE se nearZ == farZ.

Ao enviar imagens de vetor de movimento e de profundidade junto com camadas de projeção, adicione uma estrutura XrFrameSynthesisInfoEXT à cadeia XrCompositionLayerProjectionView :: next para cada estrutura XrCompositionLayerProjectionView na camada especificada.

O ambiente de execução precisa interpretar os dados do vetor de movimento nos canais RGB de motionVectorSubImage, modificados por motionVectorScale e motionVectorOffset, da seguinte maneira: motionVector = motionVectorSubImage rgb * motionVectorScale xyz + motionVectorOffset xyz . Os componentes motionVectorSubImage a , motionVectorScale w e motionVectorOffset w são ignorados.

O vetor de movimento representa o movimento de um pixel desde o XrFrameEndInfo ::displayTime do frame anterior até o XrFrameEndInfo ::displayTime do frame atual. O ambiente de execução pode usar essas informações para extrapolar o frame renderizado em um frame futuro.

O vetor de movimento precisa ser derivado do espaço de coordenadas normalizadas do dispositivo (NDC, na sigla em inglês), que, nesse contexto, usa convenções no estilo Vulkan: o intervalo de NDC é definido como [-1, -1, 0] a [1, 1, 1], diferente do intervalo de NDC do OpenGL. No entanto, o vetor de movimento em si não é restrito a esse intervalo. Os valores dele dependem do movimento do pixel e podem se estender além dos limites do espaço NDC. Por exemplo, considerando que o NDC de um pixel no frame anterior é PrevNDC e CurrNDC no frame atual, e que não há escala ou deslocamento, o valor do vetor de movimento é " (CurrNDC - PrevNDC) xyz ".

Uso válido (implícito)

Observação

Há muitas maneiras diferentes de gerar motionVectorSubImage e depthSubImage . Por exemplo, o aplicativo pode renderizá-los em uma passagem de vetor de movimento dedicada de resolução mais baixa (consulte XrFrameSynthesisConfigViewEXT para a resolução recomendada) ou renderizá-los na passagem de visualização principal com MRT (vários destinos de renderização). Cabe ao aplicativo decidir a abordagem específica. Os formatos de ponto flutuante de 16 bits assinados por canal de pixel são recomendados para motionVectorSubImage .

Flags de síntese de frames

typedef XrFlags64 XrFrameSynthesisInfoFlagsEXT;

// Flag bits for XrFrameSynthesisInfoFlagsEXT
static const XrFrameSynthesisInfoFlagsEXT XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT = 0x00000001;
static const XrFrameSynthesisInfoFlagsEXT XR_FRAME_SYNTHESIS_INFO_REQUEST_RELAXED_FRAME_INTERVAL_BIT_EXT = 0x00000002;

Descrições de flags

  • XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT indica que os dados do vetor de movimento 2D são usados.
  • XR_FRAME_SYNTHESIS_INFO_REQUEST_RELAXED_FRAME_INTERVAL_BIT_EXT fornece uma dica ao ambiente de execução de que o aplicativo prefere mais tempo para renderizar cada frame, com a desvantagem de que mais frames seriam sintetizados pelo ambiente de execução. Isso pode ser útil para aplicativos que preferem conservar a utilização da CPU e da GPU (por exemplo, para aumentar a duração da bateria) ou para aumentar o orçamento de computação de cada frame. O ambiente de execução pode solicitar frames em qualquer intervalo, independentemente do valor dessa flag.

Por padrão, os dados do vetor de movimento 3D são esperados pelo ambiente de execução. Portanto, motionVectorSubImage rgb , motionVectorScale xyz e motionVectorOffset xyz são usados, conforme descrito em XrFrameSynthesisInfoEXT.

Quando XR_FRAME_SYNTHESIS_INFO_USE_2D_MOTION_VECTOR_BIT_EXT está ativado em XrFrameSynthesisInfoEXT layerFlags , o ambiente de execução interpreta a imagem de vetor de movimento enviada como dados de vetor de movimento 2D, representando o movimento de pixel 2D do frame anterior para o atual. Os valores de pixels são interpretados da seguinte maneira para dados de vetor de movimento 2D: motionVector = motionVectorSubImage rg * motionVectorScale xy + motionVectorOffset xy . Os componentes motionVectorSubImage ba , motionVectorScale zw e motionVectorOffset zw são ignorados. O uso de dados de vetor de movimento 2D em vez de 3D pode diminuir a qualidade dos frames sintetizados.

A estrutura XrFrameSynthesisConfigViewEXT é definida como:

typedef struct XrFrameSynthesisConfigViewEXT {
    XrStructureType    type;
    void*              next;
    uint32_t           recommendedMotionVectorImageRectWidth;
    uint32_t           recommendedMotionVectorImageRectHeight;
} XrFrameSynthesisConfigViewEXT;

Descrições de membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • recommendedMotionVectorImageRectWidth : largura recomendada do vetor de movimento e da imagem de profundidade.
  • recommendedMotionVectorImageRectHeight : altura recomendada do vetor de movimento e da imagem de profundidade.

Quando essa extensão está ativada, um aplicativo pode transmitir uma estrutura XrFrameSynthesisConfigViewEXT na cadeia XrViewConfigurationView :: next ao chamar xrEnumerateViewConfigurationViews para adquirir informações sobre a resolução de imagem de vetor de movimento recomendada.

Uso válido (implícito)

Novas estruturas

Novas constantes de tipo enumerado

  • XR_EXT_FRAME_SYNTHESIS_EXTENSION_NAME
  • XR_EXT_frame_synthesis_SPEC_VERSION
  • Estendendo XrStructureType :

    • XR_TYPE_FRAME_SYNTHESIS_CONFIG_VIEW_EXT
    • XR_TYPE_FRAME_SYNTHESIS_INFO_EXT

Problemas

Histórico de versões

  • Revisão 1, 31/01/2022 (Jian Zhang)

    • Descrição inicial da extensão, convertida de fb_space_warp
    • Colaboração com colaboradores para refinar as interfaces de extensão.