Membangun dengan Spatial Container

Perangkat XR yang kompatibel
Panduan ini membantu Anda membangun pengalaman untuk jenis perangkat XR ini.
Headset XR
Kacamata XR Berkabel

Penampung Spasial menghadirkan windowing volumetrik ke OpenXR. Ditentukan oleh ekstensi XR_EXT_spatial_container dan XR_EXT_spatial_container_self_rendering di OpenXR 1.1, penampung spasial adalah region volumetrik 3D yang dikelola sistem di ruang pengguna tempat aplikasi Anda merender konten 3D menggunakan lapisan komposisi OpenXR standar.

Biasanya, sesi OpenXR mengklaim akses eksklusif ke seluruh ruang pandang pengguna. Penampung Spasial memungkinkan aplikasi Anda merender konten OpenXR 3D di dalam kotak 3D terbatas di lingkungan pengguna, atau beralih ke pengalaman imersif layar penuh tanpa batas kapan saja.

Tentang Penampung Spasial

Penampung spasial adalah region 3D yang dibatasi atau tidak dibatasi yang dikelola oleh sistem Android XR dan dirender oleh aplikasi OpenXR Anda:

  • Mode terbatas: Aplikasi Anda menyarankan dimensi 3D (lebar, tinggi, dan kedalaman dalam meter), dan sistem mengalokasikan kotak pembatas 3D di lingkungan pengguna. Aplikasi Anda merender konten 3D stereo di dalam volume, dan sistem akan memangkas konten yang dirender ke batas kotak 3D.
  • Mode imersif: Penampung spasial diperluas hingga batas tak terbatas, sehingga aplikasi Anda dapat menggunakan seluruh ruang pandang pengguna seperti sesi OpenXR layar penuh tradisional.
Tiga penampung spasial yang berjalan secara bersamaan dalam Mode Ruang Penuh: penampung medan 3D berwarna oranye yang terkunci di lantai, model bebek 3D berwarna biru dengan UI 2D yang terpasang, dan penampung UI 2D berwarna hijau.
Gambar 1. Beberapa penampung spasial dalam Mode Ruang Penuh: volume medan 3D yang terkunci di lantai (kiri), volume bebek 3D yang dipasangkan dengan UI 2D (tengah), dan penampung UI 2D (kanan).

Cara pengguna berinteraksi dengan Penampung Spasial

Sistem Android XR mengelola kontrol jendela penampung spasial dan penempatannya di ruang fisik, sehingga memberikan model interaksi yang konsisten di seluruh aplikasi:

  • Memindahkan dan mengubah posisi: Pengguna dapat mengambil handle sistem penampung spasial menggunakan gestur tangan (seperti mencubit) atau pengontrol gerakan untuk mengubah posisinya di ruang 3D.
  • Meminimalkan dan menutup: Kontrol jendela sistem memungkinkan pengguna meminimalkan atau menutup penampung spasial satu per satu. Saat pengguna menutup penampung, sistem akan memberi tahu aplikasi Anda sehingga aplikasi dapat membersihkan resource.
  • Mengunci ke lantai dengan pemahaman scene: Saat aplikasi Anda mendeklarasikan dan meminta izin android.permission.SCENE_UNDERSTANDING_COARSE, sistem akan otomatis mengaktifkan penempatan permukaan sehingga pengguna dapat menempatkan dan mengunci penampung spasial ke lantai fisik tanpa konfigurasi aplikasi tambahan, seperti yang ditunjukkan oleh penampung medan berwarna oranye pada Gambar 1.
  • Interaksi 3D langsung: Saat penampung difokuskan dan interaktif, pengguna dapat berinteraksi langsung dengan konten 3D di dalam volume menggunakan pelacakan gerak tangan, pandangan mata, atau pengontrol 6DoF.
Pengguna berinteraksi dengan bebek 3D di dalam penampung spasial biru yang dibatasi menggunakan pelacakan gerak tangan.
Gambar 2. Pengguna berinteraksi dengan konten 3D di dalam penampung spasial terbatas menggunakan pelacakan gerak tangan.
  • Transisi antara mode terbatas dan imersif: Pengguna atau aplikasi Anda dapat mengalihkan penampung antara kotak 3D terbatas dan tampilan imersif layar penuh tanpa batas tanpa memulai ulang sesi OpenXR.
Adegan bebek 3D setelah beralih dari penampung spasial terbatas ke tampilan imersif layar penuh tanpa batas.
Gambar 3. Penampung spasial setelah beralih dari mode terbatas ke mode imersif, mengisi ruang pandang pengguna.
  • Mode ikuti saat bepergian: Karena sistem mengontrol pose setiap ruang koordinat penampung spasial (xrCreateSpatialContainerSpaceEXT), pengguna dapat mengaktifkan mode ikuti dari kontrol jendela sistem sehingga penampung 3D yang dibatasi otomatis mengikuti mereka dan tetap berada dalam ruang pandang mereka saat mereka berjalan—tanpa memerlukan konfigurasi tambahan di aplikasi Anda.

Cara menggunakan Spatial Container di Android XR

Saat mem-build aplikasi dengan Penampung Spasial, desain scene Anda di sekitar batas penampung, perubahan status, dan mode penggabungan latar belakang.

Menyesuaikan konten 3D dengan batas penampung

Dalam mode terbatas, titik asal (0, 0, 0) ruang container spasial (xrCreateSpatialContainerSpaceEXT) berada di tengah kotak pembatas 3D. Karena sistem mengelola pose ruang penampung di lingkungan pengguna, aplikasi Anda merender konten 3D-nya secara relatif terhadap (0, 0, 0), sementara sistem menangani pemosisian ulang pengguna dan mode ikuti. Sistem akan memotong geometri apa pun yang dirender di luar lebar, tinggi, atau kedalaman kotak sehingga konten tetap berada dalam volume yang ditetapkan.

Aplikasi Anda harus memproses peristiwa perubahan batas dari runtime dan menskalakan atau memosisikan ulang tampilan 3D Anda sehingga konten utama sesuai dengan dimensi penampung saat ini. Saat penampung beralih ke mode imersif, batasnya menjadi tak terbatas dan Anda dapat memulihkan tampilan ke skala dunia 1:1 penuh.

Merespons perubahan status penampung

Alih-alih mengelola visibilitas dan fokus hanya di tingkat aplikasi, setiap penampung spasial melaporkan statusnya sendiri sehingga aplikasi Anda dapat bereaksi sebagaimana mestinya:

  • Visibilitas: Menunjukkan apakah penampung saat ini ditampilkan atau disembunyikan. Jeda animasi, audio, atau update simulasi saat penampung disembunyikan. Aplikasi Anda juga dapat meminta untuk menampilkan atau menyembunyikan penampung.
  • Interaktivitas: Menunjukkan apakah penampung difokuskan dan menerima input pengguna dari pelacakan gerak tangan, pengontrol, atau pandangan mata. Mengaktifkan atau menonaktifkan sorotan interaktif dan penanganan input saat fokus berubah.
  • Mode batas: Menunjukkan apakah penampung saat ini berada dalam XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT (dipotong ke kotak 3D) atau XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT (layar penuh tanpa batas). Perbarui skala scene dan aktifkan/nonaktifkan visual lingkungan (seperti skybox atau passthrough) saat mode berubah. Aplikasi Anda juga dapat meminta transisi antara mode terbatas dan imersif kapan saja.

Menggunakan transparansi alpha-blended dalam mode terbatas

Dalam mode terbatas, latar belakang transparan memungkinkan lingkungan fisik pengguna dan jendela lain tetap terlihat di sekitar model 3D Anda. Konfigurasikan kamera atau area pandang Anda dengan latar belakang transparan dan gunakan mode penggabungan lingkungan alpha-blend. Saat beralih ke mode imersif, Anda dapat tetap mengaktifkan passthrough atau beralih ke lingkungan skybox buram.

Memeriksa ketersediaan fitur dan mengonfigurasi manifes

Penampung Spasial memerlukan perangkat Android XR yang mendukung Level API Spasial 4 atau yang lebih tinggi. Daripada memeriksa level Android API secara langsung, buat kueri runtime OpenXR untuk menentukan apakah Spatial Container didukung dengan memanggil xrEnumerateInstanceExtensionProperties untuk memverifikasi bahwa XR_EXT_spatial_container dan XR_EXT_spatial_container_self_rendering tersedia, dan memanggil xrGetSystemProperties dengan XrSystemSpatialContainerPropertiesEXT untuk memeriksa supportsBounded dan supportsImmersive.

Sebelum membuat aplikasi yang menggunakan Penampung Spasial, konfigurasikan mode mulai aktivitas dan izin khusus fitur di AndroidManifest.xml.

Mengaktifkan Mode Ruang Penuh di AndroidManifest.xml

Penampung Spasial memerlukan mode Ruang Penuh Terkelola, bahkan untuk aplikasi OpenXR mandiri. Aplikasi OpenXR layar penuh tradisional mendeklarasikan XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED untuk mengambil kontrol eksklusif atas tampilan tanpa pengelolaan jendela sistem. Sebaliknya, aplikasi yang menggunakan Spatial Container mengandalkan compositor sistem Android XR untuk mengelola volume terbatas 3D, kontrol jendela, dan penempatan spasial dalam Mode Ruang Penuh, dan harus menetapkan android.window.PROPERTY_XR_ACTIVITY_START_MODE ke XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ...>
        <!-- Spatial Containers require Full Space Managed mode -->
        <property
            android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
            android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED" />

        <activity android:name=".MainActivity" ...>
            <!-- Optional hint declaring which bounds modes the activity uses -->
            <property
                android:name="org.khronos.openxr.PROPERTY_ACTIVITY_HINT_XR_SPATIAL_CONTAINER_USED_BOUNDS_MODES"
                android:value="XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT|XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT" />
        </activity>
    </application>
</manifest>

Mendeklarasikan dan meminta izin khusus fitur

Membuat dan merender penampung spasial dasar tidak memerlukan izin runtime yang berbahaya. Namun, fitur tertentu memerlukan deklarasi dan permintaan izin Android XR yang sesuai:

  • Untuk mengunci dan menambatkan penampung spasial ke lantai fisik menggunakan pemahaman scene, deklarasikan dan minta izin android.permission.SCENE_UNDERSTANDING_COARSE yang berbahaya saat runtime.
  • Untuk melacak pose kepala pengguna di OpenXR, deklarasikan dan minta android.permission.HEAD_TRACKING.
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />

Lihat Memahami izin untuk XR untuk mengetahui detail tentang cara mendeklarasikan dan meminta izin XR berbahaya saat runtime.

Mengaktifkan Spatial Containers di project Anda

Anda dapat membangun dengan Spatial Containers menggunakan Unity, Godot, atau langsung dengan OpenXR di C++. Pilih tab untuk melihat prasyarat, penyiapan editor, dan contoh kode untuk lingkungan pilihan Anda:

Unity

Prasyarat

Mengonfigurasi project Anda

  1. Buka Edit > Setelan Project > XR Plug-in Management > OpenXR.
  2. Klik Settings di samping Android XR (Extensions): Session Management dan hapus Immersive XR.
  3. Dalam daftar OpenXR Feature Groups, aktifkan Spatial Container.

Gunakan XRSpatialContainerFeature di C# untuk mengkueri batas, merespons peristiwa penampung, dan beralih antara mode terbatas dan imersif:

void OnEnable()
{
    XRSpatialContainerFeature.OnSpatialContainerBoundsChanged += OnBoundsChanged;
}

private void OnBoundsChanged(Vector3 bounds, bool infiniteBounds)
{
    float minScale = Mathf.Min(bounds.x, bounds.y, bounds.z);
    transform.localScale = infiniteBounds ? Vector3.one : Vector3.one * minScale;
}

public void SetImmersiveMode(bool immersive)
{
    XRSpatialContainerFeature.TryRequestBoundsMode(immersive);
}

Untuk mengetahui langkah-langkah penyiapan project, konfigurasi manifes, dan penanganan izin yang lengkap, lihat Menggunakan Spatial Container di Unity.

Godot

Prasyarat

Mengonfigurasi project Anda

  1. Buka Project > Setelan Project, aktifkan Advanced Settings, lalu buka General > XR > OpenXR > Extensions.
  2. Di bagian subbagian Spatial Container, pilih Enabled, lalu konfigurasikan Bounds Mode dan Bounds.
  3. Buka Project > Export... > Android, lalu pilih Use Experimental Features di bagian Android XR Features.

Gunakan singleton OpenXRSpatialContainerExtension di GDScript untuk merespons perubahan batas dan mode container:

func _ready() -> void:
    if OpenXRSpatialContainerExtension.is_enabled():
        OpenXRSpatialContainerExtension.spatial_container_bounds_changed.connect(
            _on_bounds_changed
        )

func _on_bounds_changed(_rid: RID, bounds: Vector3) -> void:
    scale = Vector3.ONE * min(bounds.x, bounds.y, bounds.z)

func set_immersive_mode() -> void:
    OpenXRSpatialContainerExtension.request_main_spatial_container_bounds_mode(
        OpenXRSpatialContainerState.IMMERSIVE
    )

Untuk setelan project, izin ekspor, dan contoh GDScript yang lengkap, lihat Menggunakan Spatial Container di Godot.

OpenXR

Prasyarat

Aktifkan XR_EXT_spatial_container dan XR_EXT_spatial_container_self_rendering saat membuat XrInstance, lalu buat dan render penampung spasial Anda:

// 1. Enable the Spatial Container extensions during xrCreateInstance
const char* enabledExtensions[] = {
    XR_EXT_SPATIAL_CONTAINER_EXTENSION_NAME,
    XR_EXT_SPATIAL_CONTAINER_SELF_RENDERING_EXTENSION_NAME,
};

// 2. Configure and create a self-rendering spatial container
XrSpatialContainerConfigurationSelfRenderingEXT selfRenderingConfig{
    .type = XR_TYPE_SPATIAL_CONTAINER_CONFIGURATION_SELF_RENDERING_EXT,
    .next = nullptr,
    .viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO,
    .suggestedBounds = {1.5f, 1.5f, 1.5f}, // Width, height, depth in meters
};

XrSpatialContainerCreateInfoEXT createInfo{
    .type = XR_TYPE_SPATIAL_CONTAINER_CREATE_INFO_EXT,
    .next = &selfRenderingConfig,
    .spatialContainerConfig =
        reinterpret_cast<const XrSpatialContainerConfigurationBaseHeaderEXT*>(
            &selfRenderingConfig),
};

XrSpatialContainerEXT spatialContainer = XR_NULL_HANDLE;
xrCreateSpatialContainerEXT(session, &createInfo, &spatialContainer);

// 3. Request bounded mode and make the container visible
xrRequestSpatialContainerBoundsModeEXT(
    spatialContainer, XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT);
xrRequestSpatialContainerVisibilityEXT(spatialContainer, XR_TRUE);

Lihat juga


OpenXR™ dan logo OpenXR adalah merek dagang yang dimiliki oleh The Khronos Group Inc. dan terdaftar sebagai merek dagang di China, Uni Eropa, Jepang, dan Inggris Raya.