Spatial Containers นำการสร้างหน้าต่างเชิงปริมาตรมาสู่ OpenXR คอนเทนเนอร์เชิงพื้นที่ซึ่งกำหนดโดยส่วนขยาย XR_EXT_spatial_container และ XR_EXT_spatial_container_self_rendering ใน OpenXR 1.1 คือพื้นที่ปริมาตร 3 มิติที่ระบบจัดการในพื้นที่ของผู้ใช้ ซึ่งแอปของคุณจะแสดงผลเนื้อหา 3 มิติโดยใช้เลเยอร์องค์ประกอบ OpenXR มาตรฐาน
โดยปกติแล้ว เซสชัน OpenXR จะอ้างสิทธิ์การเข้าถึงขอบเขตการมองเห็นทั้งหมดของผู้ใช้แต่เพียงผู้เดียว คอนเทนเนอร์เชิงพื้นที่ช่วยให้แอปแสดงผลเนื้อหา OpenXR 3 มิติภายในกล่อง 3 มิติที่มีขอบเขตในสภาพแวดล้อมของผู้ใช้ หรือเปลี่ยนไปใช้ประสบการณ์ที่สมจริงแบบเต็มหน้าจอและไม่มีขอบเขตได้ทุกเมื่อ
เกี่ยวกับคอนเทนเนอร์เชิงพื้นที่
คอนเทนเนอร์เชิงมิติพื้นที่คือขอบเขต 3 มิติที่มีขอบเขตหรือไม่มีขอบเขตซึ่งจัดการโดยระบบ Android XR และแสดงผลโดยแอป OpenXR ของคุณ
- โหมดมีขอบเขต: แอปจะแนะนำขนาด 3 มิติ (ความกว้าง ความสูง และความลึกเป็นเมตร) และระบบจะจัดสรรกรอบล้อมรอบ 3 มิติในสภาพแวดล้อมของผู้ใช้ แอปของคุณแสดงผลเนื้อหา 3 มิติแบบสเตอริโอภายในปริมาตร และระบบจะตัดเนื้อหาที่แสดงผลให้อยู่ภายในขอบเขตของกล่อง 3 มิติ
- โหมดใหญ่พิเศษ: คอนเทนเนอร์เชิงพื้นที่ขยายออกไปอย่างไม่มีที่สิ้นสุด ทำให้แอปของคุณมีขอบเขตการมองเห็นทั้งหมดของผู้ใช้เหมือนกับเซสชัน OpenXR แบบเต็มหน้าจอแบบดั้งเดิม
วิธีที่ผู้ใช้โต้ตอบกับคอนเทนเนอร์เชิงพื้นที่
ระบบ Android XR จะจัดการการควบคุมหน้าต่างของคอนเทนเนอร์เชิงพื้นที่และการวางตำแหน่งในพื้นที่จริง ซึ่งจะมอบโมเดลการโต้ตอบที่สอดคล้องกันในแอปต่างๆ ดังนี้
- การย้ายและการเปลี่ยนตำแหน่ง: ผู้ใช้สามารถจับแฮนเดิลระบบของคอนเทนเนอร์เชิงพื้นที่ได้โดยใช้ท่าทางของมือ (เช่น การบีบ) หรือตัวควบคุมการเคลื่อนไหวเพื่อเปลี่ยนตำแหน่งในพื้นที่ 3 มิติ
- การย่อและการปิด: ตัวควบคุมหน้าต่างระบบช่วยให้ผู้ใช้ย่อหรือปิดคอนเทนเนอร์เชิงพื้นที่แต่ละรายการได้ เมื่อผู้ใช้ปิดคอนเทนเนอร์ ระบบจะแจ้งเตือนแอปของคุณเพื่อให้ล้างทรัพยากรได้
- การล็อกกับพื้นด้วยความเข้าใจฉาก: เมื่อแอปประกาศและขอสิทธิ์
android.permission.SCENE_UNDERSTANDING_COARSEระบบจะเปิดใช้การสแนปพื้นผิวโดยอัตโนมัติเพื่อให้ผู้ใช้วางและล็อกคอนเทนเนอร์เชิงพื้นที่กับพื้นจริงได้โดยไม่ต้องกำหนดค่าแอปเพิ่มเติม ดังที่แสดงโดยคอนเทนเนอร์ภูมิประเทศสีส้มในรูปที่ 1 - การโต้ตอบ 3 มิติโดยตรง: เมื่อคอนเทนเนอร์ได้รับการโฟกัสและโต้ตอบได้ ผู้ใช้จะโต้ตอบกับเนื้อหา 3 มิติภายในวอลุ่มได้โดยตรงโดยใช้การติดตามการเคลื่อนไหวของมือ การจ้องมอง หรือตัวควบคุม 6DoF
- การเปลี่ยนระหว่างโหมดจำกัดและโหมดใหญ่พิเศษ: ผู้ใช้หรือแอปของคุณสามารถสลับคอนเทนเนอร์ระหว่างกล่อง 3 มิติที่จำกัดกับมุมมองใหญ่พิเศษแบบเต็มหน้าจอที่ไม่จำกัดได้โดยไม่ต้องรีสตาร์ทเซสชัน OpenXR
- โหมดติดตามขณะเดินทาง: เนื่องจากระบบจะควบคุมท่าทางของพื้นที่พิกัดของคอนเทนเนอร์เชิงพื้นที่แต่ละรายการ (
xrCreateSpatialContainerSpaceEXT) ผู้ใช้จึงสามารถเปิดใช้โหมดติดตามจากการควบคุมหน้าต่างของระบบเพื่อให้คอนเทนเนอร์ 3 มิติที่มีขอบเขตติดตามผู้ใช้โดยอัตโนมัติและอยู่ในขอบเขตการมองเห็นขณะที่ผู้ใช้เดินไปมา โดยไม่ต้องกำหนดค่าเพิ่มเติมในแอป
วิธีใช้คอนเทนเนอร์เชิงพื้นที่ใน Android XR
เมื่อสร้างแอปด้วยคอนเทนเนอร์เชิงพื้นที่ ให้ออกแบบฉากตามขอบเขตของคอนเทนเนอร์ การเปลี่ยนแปลงสถานะ และโหมดผสมพื้นหลัง
ปรับเนื้อหา 3 มิติให้พอดีกับขอบเขตของคอนเทนเนอร์
ในโหมดจำกัดขอบเขต จุดเริ่มต้น (0, 0, 0) ของพื้นที่คอนเทนเนอร์เชิงพื้นที่ (xrCreateSpatialContainerSpaceEXT) จะอยู่ที่กึ่งกลางของกรอบล้อมรอบ 3 มิติ
เนื่องจากระบบจะจัดการท่าทางของพื้นที่คอนเทนเนอร์ในสภาพแวดล้อมของผู้ใช้ แอปของคุณจึงแสดงผลเนื้อหา 3 มิติที่สัมพันธ์กับ (0, 0, 0) ขณะที่ระบบจะจัดการการเปลี่ยนตำแหน่งของผู้ใช้และโหมดติดตาม ระบบจะตัดเรขาคณิตที่แสดงผลนอกความกว้าง ความสูง หรือความลึกของกล่องเพื่อให้เนื้อหาอยู่ภายในปริมาตรที่กำหนด
แอปควรฟังเหตุการณ์การเปลี่ยนแปลงขอบเขตจากรันไทม์และปรับขนาดหรือเปลี่ยนตำแหน่งฉาก 3 มิติเพื่อให้เนื้อหาหลักพอดีกับขนาดปัจจุบันของคอนเทนเนอร์ เมื่อคอนเทนเนอร์เปลี่ยนเป็นโหมดใหญ่พิเศษ ขอบเขตจะไม่มีที่สิ้นสุดและคุณสามารถคืนค่าฉากเป็นสเกลโลกแบบ 1:1 เต็มรูปแบบได้
ตอบสนองต่อการเปลี่ยนแปลงสถานะคอนเทนเนอร์
แทนที่จะจัดการระดับการมองเห็นและการโฟกัสเฉพาะในระดับแอปพลิเคชัน คอนเทนเนอร์เชิงพื้นที่แต่ละรายการจะรายงานสถานะของตนเองเพื่อให้แอปตอบสนองตามนั้นได้
- การแสดงผล: ระบุว่าขณะนี้คอนเทนเนอร์แสดงหรือซ่อนอยู่ หยุดภาพเคลื่อนไหว เสียง หรือการอัปเดตการจำลองชั่วคราวขณะที่คอนเทนเนอร์ซ่อนอยู่ นอกจากนี้ แอปยังขอให้แสดงหรือซ่อนคอนเทนเนอร์ได้ด้วย
- ความสามารถในการโต้ตอบ: ระบุว่าคอนเทนเนอร์ได้รับการโฟกัสและรับอินพุตของผู้ใช้จากการติดตามการเคลื่อนไหวของมือ ตัวควบคุม หรือการจ้องมองหรือไม่ เปิดหรือปิดใช้ไฮไลต์แบบอินเทอร์แอกทีฟและการจัดการอินพุตเมื่อโฟกัสเปลี่ยนไป
- โหมดขอบเขต: ระบุว่าคอนเทนเนอร์อยู่ในโหมด
XR_SPATIAL_CONTAINER_BOUNDS_MODE_BOUNDED_EXT(ถูกตัดเป็นกล่อง 3 มิติ) หรือXR_SPATIAL_CONTAINER_BOUNDS_MODE_IMMERSIVE_EXT(เต็มหน้าจอแบบไม่มีขอบเขต) อัปเดตสเกลฉากและสลับภาพสภาพแวดล้อม (เช่น สกายบ็อกซ์หรือการส่งผ่าน) เมื่อโหมดเปลี่ยนไป แอปของคุณยังสามารถขอเปลี่ยนระหว่างโหมดขอบเขตและโหมดใหญ่พิเศษได้ทุกเมื่อ
ใช้ความโปร่งใสแบบผสมอัลฟ่าในโหมดที่มีขอบเขต
ในโหมดที่มีขอบเขต พื้นหลังโปร่งใสจะช่วยให้ผู้ใช้มองเห็นสภาพแวดล้อมจริงและหน้าต่างอื่นๆ รอบโมเดล 3 มิติได้ กำหนดค่ากล้องหรือวิวพอร์ตด้วยพื้นหลังโปร่งใสและใช้โหมดผสมสภาพแวดล้อมแบบผสมอัลฟ่า เมื่อเปลี่ยนไปใช้โหมดใหญ่พิเศษ คุณจะเปิดใช้โหมดส่งผ่านภาพต่อไปหรือเปลี่ยนไปใช้สภาพแวดล้อม Skybox แบบทึบแสงก็ได้
ตรวจสอบความพร้อมใช้งานของฟีเจอร์และกำหนดค่าไฟล์ Manifest
คอนเทนเนอร์เชิงมิติพื้นที่ต้องใช้อุปกรณ์ Android XR ที่รองรับ API เชิงมิติพื้นที่ระดับ 4 ขึ้นไป แทนที่จะตรวจสอบระดับ Android API โดยตรง ให้ค้นหารันไทม์ OpenXR เพื่อพิจารณาว่าระบบรองรับคอนเทนเนอร์เชิงพื้นที่หรือไม่โดยเรียกใช้ xrEnumerateInstanceExtensionProperties เพื่อยืนยันว่า XR_EXT_spatial_container และ XR_EXT_spatial_container_self_rendering พร้อมใช้งาน และเรียกใช้ xrGetSystemProperties ด้วย XrSystemSpatialContainerPropertiesEXT เพื่อตรวจสอบ supportsBounded และ supportsImmersive
ก่อนสร้างแอปที่ใช้คอนเทนเนอร์เชิงพื้นที่ ให้กำหนดค่าโหมดเริ่มต้นกิจกรรมและสิทธิ์เฉพาะฟีเจอร์ใน AndroidManifest.xml
เปิดใช้โหมด Full Space ใน AndroidManifest.xml
คอนเทนเนอร์เชิงพื้นที่ต้องใช้โหมด Full Space Managed แม้จะเป็นแอป OpenXR แบบสแตนด์อโลนก็ตาม แอป OpenXR แบบเต็มหน้าจอแบบดั้งเดิมจะประกาศ XR_ACTIVITY_START_MODE_FULL_SPACE_UNMANAGED เพื่อควบคุมการแสดงผลแต่เพียงผู้เดียวโดยไม่มีการจัดการหน้าต่างระบบ ในทางตรงกันข้าม แอปที่ใช้คอนเทนเนอร์เชิงมิติพื้นที่จะอาศัยเครื่องมือจัดวางระบบ Android XR เพื่อจัดการปริมาตรที่ถูกจำกัดขอบเขตแบบ 3 มิติ การควบคุมหน้าต่าง และการจัดวางเชิงมิติพื้นที่ในโหมด Full Space และต้องตั้งค่า android.window.PROPERTY_XR_ACTIVITY_START_MODE เป็น 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>
ประกาศและขอสิทธิ์เฉพาะฟีเจอร์
การสร้างและการแสดงผลคอนเทนเนอร์เชิงพื้นที่พื้นฐานไม่จำเป็นต้องใช้สิทธิ์รันไทม์ที่เป็นอันตราย อย่างไรก็ตาม ฟีเจอร์บางอย่างจำเป็นต้องมีการประกาศและขอสิทธิ์ Android XR ที่เกี่ยวข้อง ดังนี้
- หากต้องการล็อกและยึดคอนเทนเนอร์เชิงพื้นที่กับพื้นจริงโดยใช้การทำความเข้าใจฉาก ให้ประกาศและขอสิทธิ์
android.permission.SCENE_UNDERSTANDING_COARSEที่เป็นอันตรายที่รันไทม์ - หากต้องการติดตามท่าทางศีรษะของผู้ใช้ใน OpenXR ให้ประกาศและขอ
android.permission.HEAD_TRACKING
<uses-permission android:name="android.permission.HEAD_TRACKING" />
<uses-permission android:name="android.permission.SCENE_UNDERSTANDING_COARSE" />
ดูรายละเอียดเกี่ยวกับการประกาศและการขอสิทธิ์ XR ที่เป็นอันตรายที่รันไทม์ได้ที่ทำความเข้าใจสิทธิ์สำหรับ XR
เปิดใช้คอนเทนเนอร์เชิงพื้นที่ในโปรเจ็กต์
คุณสามารถสร้างด้วยคอนเทนเนอร์เชิงพื้นที่โดยใช้ Unity, Godot หรือใช้ OpenXR ใน C++ โดยตรง เลือกแท็บเพื่อดูข้อกำหนดเบื้องต้น การตั้งค่าเครื่องมือแก้ไข และตัวอย่างโค้ดสำหรับสภาพแวดล้อมที่ต้องการ
Unity
สิ่งที่ต้องมีก่อน
- เวอร์ชัน Unity: Unity 6 เวอร์ชัน 6000.0.58f2 ขึ้นไป
- การตั้งค่าโปรเจ็กต์: ทำตามขั้นตอนทั้งหมดในคู่มือการตั้งค่าโปรเจ็กต์ Unity
- แพ็กเกจ Unity: ติดตั้งแพ็กเกจ Android XR Extensions for Unity เวอร์ชัน 1.5.0 ขึ้นไป
กำหนดค่าโปรเจ็กต์
- ไปที่ Edit > การตั้งค่าโปรเจ็กต์ > XR Plug-in Management > OpenXR
- คลิกการตั้งค่า ข้าง Android XR (ส่วนขยาย): การจัดการเซสชัน แล้วล้าง XR แบบสมจริง
- ในรายการ OpenXR Feature Groups ให้เปิดใช้ Spatial Container
ใช้ XRSpatialContainerFeature ใน C# เพื่อค้นหาขอบเขต ตอบสนองต่อเหตุการณ์คอนเทนเนอร์ และสลับระหว่างโหมดที่มีขอบเขตและโหมดใหญ่พิเศษ
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);
}
ดูขั้นตอนการตั้งค่าโปรเจ็กต์ การกำหนดค่าไฟล์ Manifest และการจัดการสิทธิ์ทั้งหมดได้ที่หัวข้อใช้คอนเทนเนอร์เชิงพื้นที่ใน Unity
Godot
สิ่งที่ต้องมีก่อน
- เวอร์ชัน Godot: Godot 4.8-dev ขึ้นไป
- การตั้งค่าโปรเจ็กต์: ทำตามขั้นตอนทั้งหมดในคู่มือการตั้งค่าโปรเจ็กต์ Godot Engine
- ปลั๊กอิน Godot OpenXR Vendors: ติดตั้งปลั๊กอิน Godot OpenXR Vendors เวอร์ชัน 5.2 ขึ้นไป
กำหนดค่าโปรเจ็กต์
- ไปที่ Project > การตั้งค่าโปรเจ็กต์ เปิดใช้ Advanced Settings แล้วไปที่ General > XR > OpenXR > Extensions
- ในส่วนย่อย Spatial Container ให้เลือกเปิดใช้ แล้วกำหนดค่า Bounds Mode และ Bounds
- ไปที่โปรเจ็กต์ > ส่งออก... > Android แล้วเลือกใช้ฟีเจอร์ทดลองในส่วนฟีเจอร์ Android XR
ใช้ซิงเกิลตัน OpenXRSpatialContainerExtension ใน GDScript เพื่อตอบสนองต่อขอบเขตคอนเทนเนอร์และการเปลี่ยนแปลงโหมด
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
)
ดูการตั้งค่าโปรเจ็กต์ สิทธิ์การส่งออก และตัวอย่าง GDScript ทั้งหมดได้ที่หัวข้อใช้คอนเทนเนอร์เชิงพื้นที่ใน Godot
OpenXR
สิ่งที่ต้องมีก่อน
- เวอร์ชัน OpenXR: ส่วนหัว OpenXR 1.1 ที่มี
XR_EXT_spatial_containerและXR_EXT_spatial_container_self_rendering - การตั้งค่าไฟล์ Manifest: กำหนดค่าไฟล์ Manifest ของแอปตามที่อธิบายไว้ในเริ่มต้นใช้งาน OpenXR สำหรับ Android XR โดยใช้
XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED
เปิดใช้ XR_EXT_spatial_container และ XR_EXT_spatial_container_self_rendering เมื่อสร้าง XrInstance จากนั้นสร้างและแสดงผลคอนเทนเนอร์เชิงพื้นที่
// 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);
ดูเพิ่มเติม
OpenXR™ และโลโก้ OpenXR เป็นเครื่องหมายการค้าของ The Khronos Group Inc. และจดทะเบียนเป็นเครื่องหมายการค้าในจีน สหภาพยุโรป ญี่ปุ่น และสหราชอาณาจักร