Xây dựng bằng vùng chứa không gian

Các thiết bị XR được hỗ trợ
Hướng dẫn này giúp bạn xây dựng các trải nghiệm cho những loại thiết bị XR sau.
Thiết bị đeo đầu XR
Kính thông minh XR có dây

Vùng chứa không gian mang đến tính năng tạo cửa sổ thể tích cho OpenXR. Được xác định bằng các tiện ích XR_EXT_spatial_container và XR_EXT_spatial_container_self_rendering trong OpenXR 1.1, vùng chứa không gian là một vùng thể tích 3D do hệ thống quản lý trong không gian của người dùng, nơi ứng dụng của bạn kết xuất nội dung 3D bằng các lớp thành phần OpenXR tiêu chuẩn.

Thông thường, một phiên OpenXR sẽ yêu cầu quyền truy cập độc quyền vào toàn bộ trường nhìn của người dùng. Vùng chứa không gian cho phép ứng dụng của bạn kết xuất nội dung OpenXR 3D bên trong một hộp 3D có giới hạn trong môi trường của người dùng hoặc chuyển đổi sang trải nghiệm sống động toàn màn hình, không giới hạn bất cứ lúc nào.

Giới thiệu về vùng chứa không gian

Vùng chứa không gian là một vùng 3D có giới hạn hoặc không giới hạn do hệ thống Android XR quản lý và do ứng dụng OpenXR của bạn kết xuất:

  • Chế độ giới hạn: Ứng dụng của bạn đề xuất kích thước 3D (chiều rộng, chiều cao và chiều sâu tính bằng mét) và hệ thống sẽ phân bổ một hộp giới hạn 3D trong môi trường của người dùng. Ứng dụng của bạn kết xuất nội dung 3D lập thể bên trong khối lượng và hệ thống sẽ cắt nội dung được kết xuất theo ranh giới của hộp 3D.
  • Chế độ nhập vai: Vùng chứa không gian mở rộng đến ranh giới vô hạn, mang đến cho ứng dụng của bạn toàn bộ trường nhìn của người dùng như một phiên OpenXR toàn màn hình truyền thống.
Ba vùng chứa không gian chạy đồng thời ở Chế độ toàn bộ không gian: một vùng chứa địa hình 3D màu cam được khoá vào sàn, một mô hình vịt 3D màu xanh dương có giao diện người dùng 2D đính kèm và một vùng chứa giao diện người dùng 2D màu xanh lục.
Hình 1. Nhiều vùng chứa không gian ở Chế độ toàn bộ không gian: một khối địa hình 3D cố định trên sàn (trái), một khối vịt 3D kết hợp với giao diện người dùng 2D (giữa) và một vùng chứa giao diện người dùng 2D (phải).

Cách người dùng tương tác với vùng chứa không gian

Hệ thống Android XR quản lý các chế độ điều khiển cửa sổ của vùng chứa không gian và vị trí trong không gian thực, mang đến một mô hình tương tác nhất quán trên các ứng dụng:

  • Di chuyển và đặt lại vị trí: Người dùng có thể nắm lấy tay điều khiển hệ thống của vùng chứa không gian bằng cử chỉ tay (chẳng hạn như chụm ngón tay) hoặc bộ điều khiển chuyển động để đặt lại vị trí của vùng chứa trong không gian 3D.
  • Thu nhỏ và đóng: Các chế độ điều khiển cửa sổ hệ thống cho phép người dùng thu nhỏ hoặc đóng từng vùng chứa không gian riêng lẻ. Khi người dùng đóng một vùng chứa, hệ thống sẽ thông báo cho ứng dụng của bạn để ứng dụng có thể dọn dẹp tài nguyên.
  • Khoá vào sàn bằng tính năng hiểu cảnh: Khi ứng dụng của bạn khai báo và yêu cầu quyền android.permission.SCENE_UNDERSTANDING_COARSE, hệ thống sẽ tự động bật tính năng bám vào bề mặt để người dùng có thể đặt và khoá vùng chứa không gian vào sàn thực tế mà không cần định cấu hình thêm cho ứng dụng, như minh hoạ bằng vùng chứa địa hình màu cam trong Hình 1.
  • Tương tác 3D trực tiếp: Khi một vùng chứa được lấy tiêu điểm và có thể tương tác, người dùng có thể tương tác trực tiếp với nội dung 3D bên trong vùng chứa bằng tính năng theo dõi cử động của tay, ánh mắt hoặc tay điều khiển 6DoF.
Người dùng tương tác với một chú vịt 3D bên trong một vùng chứa không gian màu xanh dương có giới hạn bằng tính năng theo dõi cử động của tay.
Hình 2. Người dùng tương tác với nội dung 3D bên trong một vùng chứa không gian có giới hạn bằng tính năng theo dõi cử động của tay.
  • Chuyển đổi giữa chế độ giới hạn và chế độ hiển thị tối đa: Người dùng hoặc ứng dụng của bạn có thể chuyển đổi vùng chứa giữa hộp 3D có giới hạn và chế độ xem hiển thị tối đa toàn màn hình không giới hạn mà không cần khởi động lại phiên OpenXR.
Cảnh chú vịt 3D sau khi chuyển từ vùng chứa không gian có giới hạn sang chế độ xem toàn màn hình sống động không giới hạn.
Hình 3. Vùng chứa không gian sau khi chuyển từ chế độ giới hạn sang chế độ hiển thị tối đa, lấp đầy trường nhìn của người dùng.
  • Chế độ theo dõi khi di chuyển: Vì hệ thống kiểm soát tư thế của không gian toạ độ của từng vùng chứa không gian (xrCreateSpatialContainerSpaceEXT), nên người dùng có thể bật chế độ theo dõi từ các chế độ điều khiển cửa sổ hệ thống để vùng chứa 3D có giới hạn tự động theo dõi họ và luôn nằm trong trường nhìn của họ khi họ di chuyển mà không cần thêm bất kỳ cấu hình nào trong ứng dụng.

Cách sử dụng vùng chứa không gian trên Android XR

Khi tạo ứng dụng bằng vùng chứa không gian, hãy thiết kế cảnh xung quanh ranh giới, thay đổi trạng thái và chế độ kết hợp nền của vùng chứa.

Điều chỉnh nội dung 3D cho phù hợp với ranh giới vùng chứa

Ở chế độ giới hạn, điểm gốc (0, 0, 0) của không gian vùng chứa không gian (xrCreateSpatialContainerSpaceEXT) nằm ở giữa hộp giới hạn 3D. Vì hệ thống quản lý tư thế của không gian vùng chứa trong môi trường của người dùng, nên ứng dụng của bạn sẽ kết xuất nội dung 3D tương ứng với (0, 0, 0) trong khi hệ thống xử lý việc định vị lại người dùng và chế độ theo dõi. Hệ thống sẽ cắt bớt mọi hình học được kết xuất bên ngoài chiều rộng, chiều cao hoặc chiều sâu của hộp để nội dung nằm trong khối lượng được chỉ định.

Ứng dụng của bạn nên theo dõi các sự kiện thay đổi ranh giới từ thời gian chạy và điều chỉnh tỷ lệ hoặc định vị lại cảnh 3D để nội dung chính vừa với kích thước hiện tại của vùng chứa. Khi vùng chứa chuyển sang chế độ hiển thị tối đa, các giới hạn sẽ trở nên vô hạn và bạn có thể khôi phục cảnh của mình về tỷ lệ thế giới 1:1 đầy đủ.

Phản hồi các thay đổi về trạng thái vùng chứa

Thay vì chỉ quản lý chế độ hiển thị và tiêu điểm ở cấp ứng dụng, mỗi vùng chứa không gian sẽ báo cáo trạng thái riêng để ứng dụng của bạn có thể phản ứng tương ứng:

  • Chế độ hiển thị: Cho biết vùng chứa hiện đang hiển thị hay bị ẩn. Tạm dừng ảnh động, âm thanh hoặc cập nhật mô phỏng trong khi vùng chứa bị ẩn. Ứng dụng của bạn cũng có thể yêu cầu hiện hoặc ẩn vùng chứa.
  • Khả năng tương tác: Cho biết vùng chứa có được lấy tiêu điểm và nhận dữ liệu đầu vào của người dùng từ tính năng theo dõi cử động của tay, tay điều khiển hoặc ánh mắt hay không. Bật hoặc tắt tính năng làm nổi bật tương tác và xử lý hoạt động đầu vào khi tiêu điểm thay đổi.
  • Chế độ ranh giới: Cho biết vùng chứa hiện đang ở chế độ XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT (được cắt thành hộp 3D) hay XR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT (toàn màn hình không giới hạn). Cập nhật tỷ lệ cảnh và bật/tắt hình ảnh môi trường (chẳng hạn như hộp bầu trời hoặc chế độ xem xuyên thấu) khi chế độ thay đổi. Ứng dụng của bạn cũng có thể yêu cầu chuyển đổi giữa chế độ giới hạn và chế độ hiển thị tối đa bất cứ lúc nào.

Sử dụng độ trong suốt được pha trộn alpha ở chế độ giới hạn

Ở chế độ có giới hạn, nền trong suốt cho phép người dùng nhìn thấy môi trường xung quanh và các cửa sổ khác xung quanh mô hình 3D của bạn. Định cấu hình máy ảnh hoặc khung nhìn có nền trong suốt và sử dụng chế độ kết hợp môi trường kết hợp alpha. Khi chuyển sang chế độ nhập vai, bạn có thể tiếp tục bật chế độ nhìn xuyên qua hoặc chuyển sang môi trường hộp bầu trời mờ.

Kiểm tra phạm vi cung cấp của các tính năng và định cấu hình tệp kê khai

Vùng chứa không gian yêu cầu thiết bị Android XR hỗ trợ cấp độ API không gian cấp 4 trở lên. Thay vì kiểm tra trực tiếp cấp độ API Android, hãy truy vấn thời gian chạy OpenXR để xác định xem vùng chứa không gian có được hỗ trợ hay không bằng cách gọi xrEnumerateInstanceExtensionProperties để xác minh rằng XR_EXT_spatial_container và XR_EXT_spatial_container_self_rendering có sẵn, đồng thời gọi xrGetSystemProperties bằng XrSystemSpatialContainerPropertiesEXT để kiểm tra supportsBounded và supportsImmersive.

Trước khi tạo một ứng dụng sử dụng Vùng chứa không gian, hãy định cấu hình chế độ bắt đầu hoạt động và mọi quyền dành riêng cho tính năng trong AndroidManifest.xml.

Bật chế độ Toàn bộ không gian trong AndroidManifest.xml

Vùng chứa không gian yêu cầu chế độ Toàn bộ không gian được quản lý, ngay cả đối với các ứng dụng OpenXR độc lập. Các ứng dụng OpenXR toàn màn hình truyền thống khai báo XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED để nắm quyền kiểm soát độc quyền đối với màn hình mà không cần quản lý cửa sổ hệ thống. Ngược lại, một ứng dụng sử dụng Vùng chứa không gian sẽ dựa vào trình kết hợp hệ thống Android XR để quản lý các khối lượng giới hạn 3D, chế độ điều khiển cửa sổ và vị trí không gian trong Chế độ toàn bộ không gian, đồng thời phải đặt android.window.PROPERTY_XR_ACTIVITY_START_MODE thành 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>

Khai báo và yêu cầu cấp quyền theo tính năng cụ thể

Việc tạo và kết xuất vùng chứa không gian cơ bản không yêu cầu quyền khi bắt đầu chạy nguy hiểm. Tuy nhiên, một số tính năng cụ thể yêu cầu khai báo và yêu cầu các quyền tương ứng của Android XR:

  • Để khoá và neo vùng chứa không gian vào sàn thực tế bằng tính năng hiểu cảnh, hãy khai báo và yêu cầu quyền nguy hiểm android.permission.SCENE_UNDERSTANDING_COARSE trong thời gian chạy.
  • Để theo dõi tư thế đầu của người dùng trong OpenXR, hãy khai báo và yêu cầu android.permission.HEAD_TRACKING.
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />

Hãy xem phần Tìm hiểu về các quyền đối với XR để biết thông tin chi tiết về cách khai báo và yêu cầu các quyền nguy hiểm đối với XR trong thời gian chạy.

Bật vùng chứa không gian trong dự án của bạn

Bạn có thể xây dựng bằng vùng chứa không gian bằng Unity, Godot hoặc trực tiếp bằng OpenXR trong C++. Chọn một thẻ để xem các điều kiện tiên quyết, cách thiết lập trình chỉnh sửa và mã ví dụ cho môi trường bạn muốn:

Unity

Điều kiện tiên quyết

Định cấu hình dự án

  1. Chuyển đến Edit > Project Settings > XR Plug-in Management > OpenXR (Chỉnh sửa > Cài đặt dự án > Quản lý trình bổ trợ XR > OpenXR).
  2. Nhấp vào biểu tượng Cài đặt bên cạnh Android XR (Extensions): Session Management (Android XR (Tiện ích): Quản lý phiên) rồi bỏ đánh dấu Immersive XR (XR sống động).
  3. Trong danh sách OpenXR Feature Groups (Nhóm tính năng OpenXR), hãy bật Spatial Container (Vùng chứa không gian).

Sử dụng XRSpatialContainerFeature trong C# để truy vấn ranh giới, phản hồi các sự kiện vùng chứa và chuyển đổi giữa chế độ có giới hạn và chế độ hiển thị tối đa:

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);
}

Để biết các bước thiết lập dự án, cấu hình tệp kê khai và xử lý quyền, hãy xem bài viết Sử dụng vùng chứa không gian trong Unity.

Godot

Điều kiện tiên quyết

Định cấu hình dự án

  1. Chuyển đến Project > Project Settings (Dự án > Cài đặt dự án), bật Advanced Settings (Cài đặt nâng cao) rồi chuyển đến General > XR > OpenXR > Extensions (Chung > XR > OpenXR > Tiện ích).
  2. Trong tiểu mục Spatial Container (Vùng chứa không gian), hãy chọn Enabled (Đã bật) rồi định cấu hình Bounds Mode (Chế độ ranh giới) và Bounds (Ranh giới).
  3. Chuyển đến Project > Export... (Dự án > Xuất...) > Android rồi chọn Use Experimental Features (Sử dụng các tính năng thử nghiệm) trong phần Android XR Features (Tính năng Android XR).

Sử dụng singleton OpenXRSpatialContainerExtension trong GDScript để phản hồi các thay đổi về ranh giới và chế độ của vùng chứa:

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
    )

Để biết chế độ cài đặt dự án, quyền xuất và ví dụ về GDScript đầy đủ, hãy xem bài viết Sử dụng vùng chứa không gian trong Godot.

OpenXR

Điều kiện tiên quyết

Bật XR_EXT_spatial_container và XR_EXT_spatial_container_self_rendering khi tạo XrInstance, sau đó tạo và kết xuất vùng chứa không gian:

// 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);

Xem thêm


OpenXR™ và biểu trưng OpenXR là các nhãn hiệu thuộc sở hữu của Khronos Group Inc. và được đăng ký làm nhãn hiệu ở Trung Quốc, Liên minh Châu Âu, Nhật Bản và Vương quốc Anh.