Adicionar ambientes espaciais ao app

No SDK do Jetpack XR, os ambientes espaciais são ambientes imersivos que você pode adicionar ao app para personalizar o plano de fundo da cena virtual. Os ambientes espaciais só ficam visíveis quando um app está em espaço total.

Informações gerais sobre ambientes espaciais

Um SpatialEnvironment é usado para gerenciar as preferências de ambiente espacial de um app. É um composto de uma imagem de skybox independente e da geometria especificada pelo glTF. Somente uma imagem de skybox e um arquivo de geometria glTF podem ser definidos por vez.

Um skybox representa a imagem que o usuário vê ao redor dele na cena virtual, criando a ilusão de um ambiente de plano de fundo distante, como um céu, montanhas ou uma paisagem urbana. O usuário não pode interagir com o skybox nem se aproximar dele. O SDK Jetpack XR oferece suporte a skyboxes esféricas no padrão OpenEXR. Além de fornecer um plano de fundo imersivo para o app, uma skybox EXR também fornece iluminação baseada em imagens (IBL, na sigla em inglês) a modelos 3D carregados pelo app. Para mais informações, consulte o guia para trabalhar com modelos 3D.

Os ambientes espaciais também podem incluir conteúdo de geometria 3D no padrão glTF. A geometria do ambiente carregada dessa forma será automaticamente alinhada ao piso do mundo real. A geometria do ambiente é uma ótima maneira de adicionar realismo ao ambiente usando elementos de primeiro e segundo plano que se misturam ao skybox com o efeito de paralaxe.

No guia de design para ambientes espaciais, você pode aprender sobre os diferentes tipos de recursos que podem ser usados para criar ambientes espaciais e como criar ambientes espaciais seguros e agradáveis.

É possível definir o ambiente espacial do app em uma destas três configurações:

  • Uma combinação de uma imagem de skybox e uma geometria glTF.
  • Uma superfície de passagem, em que o ambiente exibido é um feed ao vivo das câmeras voltadas para fora do dispositivo. Com opacidade total, essa superfície de passagem oculta completamente a caixa do céu e a geometria.
  • Uma configuração mista, em que a superfície de passagem não está com opacidade total nem com opacidade zero. Nesse caso, a superfície de passagem fica semitransparente, e a mistura alfa com a caixa de céu e a geometria por trás dela.

Recursos espaciais para ambientes espaciais

Importar e carregar recursos de ambiente espacial

Os recursos glTF e EXR para ambientes espaciais são carregados de forma assíncrona na classe Session. Esses arquivos precisam ser armazenados na pasta de recursos.

Criar um recurso glTF

Um recurso glTF pode ser criado como um GltfModel, em que o glTF é carregado de um arquivo local. Um GltfModel pode ser usado como parte de um ambiente de app espacial.

// assume that session is a Session that has been previously created
val environmentGeometryFuture = session.createGltfResourceAsync("DayGeometry.glb")

val environmentGeometry = environmentGeometryFuture.await()

Criar um recurso de imagem EXR

Um recurso de imagem EXR pode ser criado como um ExrImage, em que o EXR é carregado de um arquivo local. Um ExrImage pode ser usado como parte de um ambiente de app espacial para desenhar skyboxes.

// assume that session is a Session that has been previously created
val skyboxExrFuture = session.createExrImageResourceAsync("BlueSkybox.exr")

val skyboxExr = skyboxExrFuture.await()

Definir a SpatialEnvironmentPreference para seu app

setSpatialEnvironmentPreference é usado para definir o ambiente espacial preferencial de um app. Esse método define apenas uma preferência e não causa uma mudança imediata, a menos que isSpatialEnvironmentPreferenceActive já esteja ativado. Quando o dispositivo entra em um estado em que o plano de fundo do XR pode ser alterado e o recurso SpatialCapabilities.SPATIAL_CAPABILITY_APP_ENVIRONMENT está disponível, o ambiente espacial preferido para o aplicativo é mostrado automaticamente.

Definir a preferência como nula desativa o ambiente espacial preferido para o app, o que significa que o ambiente de sistema padrão será mostrado.

Se o SpatialEnvironmentPreference fornecido não for nulo, mas todas as propriedades dele forem nulas, o ambiente espacial vai consistir em um skybox preto e nenhuma geometria.

Para receber notificações sobre mudanças no estado do SpatialEnvironment, use addOnSpatialEnvironmentChangedListener.

Uso básico

Esse snippet de código cria a geometria do ambiente e os recursos de skybox e define a preferência de ambiente espacial. Essa preferência será gravada e aplicada quando o app tiver a capacidade de definir o próprio ambiente.

// Assume that session is a Session that has been previously created

// Create a GLTFResource
val environmentGeometry = session.createGltfResourceAsync("DayGeometry.glb").await()

// Create an ExrImage for the skybox
val skyboxExr = session.createExrImageResourceAsync("BlueSkybox.exr").await()

val spatialEnvironmentPreference = SpatialEnvironmentPreference(skyboxExr, environmentGeometry)

val preferenceResult = session.spatialEnvironment.setSpatialEnvironmentPreference(spatialEnvironmentPreference)

if (preferenceResult ==  SpatialEnvironment.SetSpatialEnvironmentPreferenceChangeApplied()) {
   // The environment was successfully updated and is now visible, and any listeners
   // specified using addOnSpatialEnvironmentChangedListener will be notified.
} else if (preferenceResult == SpatialEnvironment.SetSpatialEnvironmentPreferenceChangePending()) {
    // The environment is in the process of being updated. Once visible, any listeners
   // specified using addOnSpatialEnvironmentChangedListener will be notified.
}

Uso avançado

Para casos de uso mais avançados em que você precisa de mais controle sobre o ambiente, é possível incorporar verificações de SpatialCapabilities e implementar um addOnSpatialEnvironmentChangedListener para determinar quando você quer definir a preferência de ambiente espacial.

Definir a PassthroughOpacityPreference para o ambiente espacial do seu app

Um dos componentes do plano de fundo virtual imersivo de um app é uma superfície de passagem. Nesse caso, o plano de fundo exibido é um feed ao vivo das câmeras externas do dispositivo.

setPassthroughOpacityPreference é usado para definir a opacidade de passagem preferida de um app. Esse método define apenas uma preferência e não causa uma mudança imediata, a menos que a capabilidade SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL esteja disponível. Quando o dispositivo entra em um estado em que a opacidade de passagem pode ser alterada e o recurso SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL está disponível, a opacidade de passagem preferida para o aplicativo é aplicada automaticamente.

Os valores da preferência de opacidade de passagem variam de 0.0f (opacidade zero, em que a superfície de passagem não está visível) a 1.0f (opacidade total, em que a superfície de passagem oculta o ambiente espacial). O parâmetro setPassthroughOpacityPreference é um número flutuante anulável. Definir o valor como nulo indica que o app não tem preferência de opacidade de passagem e retornará o controle de passagem para o sistema.

Uso básico

Este snippet de código define a preferência de opacidade de passagem. Essa preferência será lembrada e aplicada quando o app tiver a capacidade de definir a opacidade de passagem.

// Assume that session is a Session that has been previously created

val preferenceResult = session.spatialEnvironment.setPassthroughOpacityPreference(1.0f)

if (preferenceResult ==  SpatialEnvironment.SetPassthroughOpacityPreferenceChangeApplied()) {
  // The passthrough opacity request succeeded and should be visible now, and any listeners specified using addOnPassthroughOpacityChangedListener
  // will be notified
} else if (preferenceResult == SpatialEnvironment.SetPassthroughOpacityPreferenceChangePending()) {
  // The passthrough opacity preference was successfully set, but not
  // immediately visible. The passthrough opacity change will be applied
  // when the activity has the
  // SpatialCapabilities.SPATIAL_CAPABILITY_PASSTHROUGH_CONTROL capability.
  // Then, any listeners specified using addOnPassthroughOpacityChangedListener
  // will be notified
}

Uso avançado

Para casos de uso mais avançados em que você precisa de um controle mais preciso sobre a opacidade de passagem, incorpore verificações de SpatialCapabilities e implemente um addOnPassthroughOpacityChangedListener para determinar quando você quer definir a preferência de opacidade de passagem.

Otimização de recursos

Ao criar recursos para definir o SpatialEnvironment dos usuários, é importante garantir que os recursos atinjam uma resolução de alta qualidade, mantendo um tamanho de arquivo razoável. Verifique se o glb usa mipmaps e texturas ktx2. Também é importante considerar o número de polígonos nos arquivos glb, porque um número alto pode levar a um consumo de energia desnecessário. A maior parte do tamanho do arquivo para a maioria das instâncias de SpatialEnvironment vem da imagem usada para o Skybox. Para garantir que as imagens sejam otimizadas, execute os recursos usando uma ferramenta de otimização (por exemplo, ktx).

Determinar a opacidade de passagem atual

val currentPassthroughOpacity =  session.spatialEnvironment.getCurrentPassthroughOpacity()

Veja também