XR_EXT_frame_synthesis

String de nome

XR_EXT_frame_synthesis

Tipo de extensão

Extensão de instância

Número de ramal registrado

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 outros dados 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 QPS.

Essa extensão foi projetada para ser independente do XR_KHR_composition_layer_depth , e ambos podem ser ativados e usados ao mesmo tempo, para finalidades diferentes. O XrFrameSynthesisInfoEXT :: depthSubImage pode usar dados de profundidade dedicados à síntese de frames, e a resolução dele pode ser menor que XrCompositionLayerDepthInfoKHR :: subImage . Consulte XrFrameSynthesisConfigViewEXT para ver a resolução sugerida de depthSubImage .

Enviar imagens vetoriais 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 dos 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 que 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 programado, 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 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 do aplicativo atual.
  • depthSubImage identifica a imagem de profundidade XrSwapchainSubImage que será usada para a síntese de frames.
  • minDepth e maxDepth são o intervalo de valores de profundidade no 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 swapchain 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 swapchain 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 vetores de movimento e de profundidade com camadas de projeção, adicione uma estrutura XrFrameSynthesisInfoEXT à cadeia XrCompositionLayerProjectionView :: next para cada estrutura XrCompositionLayerProjectionView na camada em questão.

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 de dispositivo normalizadas (NDC, na sigla em inglês), que, neste 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 ver a resolução recomendada) ou 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 canal de ponto flutuante de 16 bits com sinal por pixel são recomendados para motionVectorSubImage .

Sinalizações de síntese de frame

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 o uso de CPU e 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, independente do valor dessa flag.

Por padrão, o ambiente de execução espera dados de vetor de movimento 3D. 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 do 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 pixel são interpretados da seguinte forma 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 dos membros

  • type é o XrStructureType dessa estrutura.
  • next é NULL ou um ponteiro para a próxima estrutura em uma cadeia de estruturas.
  • recommendedMotionVectorImageRectWidth : vetor de movimento recomendado e largura 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 receber informações sobre a resolução recomendada da imagem vetorial de movimento.

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
    • Colaborar com colaboradores para refinar as interfaces de extensão.