Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

AR/透視

擴增實境(AR)功能會依據硬體的能力,透過不同方式來支援。

像 Magic Leap 這類的頭戴裝置,以及 TiltFive 這類眼鏡,會將渲染結果投影在「透視顯示器(see-through displays)」上,讓使用者能同時看到現實世界。

像 Quest、HTC Elite 與 Lynx R1 這類頭戴裝置,則是透過「影像透視(video passthrough)」技術,利用攝影機擷取現實畫面,並以這些影像作為背景,再將虛擬內容渲染於其上。

備註

不同平台上,透視功能的實作方式差異很大。

在 Godot 4.3 中,我們實作了一套統一的解決方案,詳見本說明頁,讓你不需再擔心這些平台差異。現在由 XRInterface 負責自動套用正確的平台專屬方法 [1]

若使用 Meta Quest 或 HTC Elite 等裝置,需安裝 OpenXR vendors plugin v3.0.0 或更新版本,才能啟用影像透視功能。

為了相容舊專案,舊有的透視 API 仍可使用,但建議依照以下新指引操作。

環境混合模式

我們可藉由設定「環境混合模式」來調整 VR 或 AR 的效果,此模式決定現實環境與虛擬世界如何混合顯示。

混合模式

混合模式

說明

XR_ENV_BLEND_MODE_OPAQUE

渲染畫面為不透明,無法看到現實世界,屬於 VR 模式。若啟用影像透視時套用此模式,將會關閉透視功能。

XR_ENV_BLEND_MODE_ADDITIVE

渲染畫面會與現實世界進行加法混合,呈現半透明效果。通常用於無法完全遮蔽現實視野的透視顯示裝置。若使用影像透視,這個模式會啟用透視功能。

XR_ENV_BLEND_MODE_ALPHA_BLEND

渲染畫面會與現實世界進行 Alpha 混合。在支援此功能的透視裝置上,Alpha 值會控制光學元件的透明度;在影像透視裝置上則與攝影機畫面進行 Alpha 混合,若適用則會啟用透視功能。

你可以透過 XRInterface 實體的 environment_blend_mode 屬性來設定應用程式的環境混合模式。

你也可以透過同一個實體的 get_supported_environment_blend_modes 屬性,查詢硬體所支援的混合模式。

設定背景

當混合模式設為 XR_ENV_BLEND_MODE_ALPHA_BLEND 時,必須將 Viewporttransparent_bg 屬性設為 true。若使用 XR_ENV_BLEND_MODE_ADDITIVE,則建議將背景顏色設為黑色。

無論哪種方式,背景都不會對場景照明產生影響。因此建議你調整環境設定,確保有足夠的環境光來照亮場景。

備註

部分 AR SDK 會提供環境光照資訊,甚至完整的輻射圖(radiance map),讓虛擬物件能反映現實世界的光線。Godot XR 核心目前尚未支援這些功能,但可以透過外掛實現。

OpenXR 專屬說明

在 OpenXR 中,你可以設定想要預設使用的混合模式。Godot 啟動時會嘗試選用這個模式,若不支援則會自動選擇 XR 執行環境所支援的第一個混合模式。

../../_images/openxr_default_blend_mode.webp

在透視裝置上,OpenXR 需要額外設定,這些設定會依平台而異,並由 OpenXR vendors 外掛提供。

例如,Meta Quest 需要以下設定:

../../_images/openxr_export_passthrough.webp

「Passthrough」設定用於指定是否支援或必須啟用透視功能。

「Boundary Mode」讓你設定是否需要啟用 Guardian(防護邊界);若要完全關閉此功能,則必須隨時保持透視模式啟用。

綜合運用

綜合上述內容,我們可以參考以下程式碼作為基礎:

@onready var viewport : Viewport = get_viewport()
@onready var environment : Environment = $WorldEnvironment.environment

func switch_to_ar() -> bool:
    var xr_interface: XRInterface = XRServer.primary_interface
    if xr_interface:
        var modes = xr_interface.get_supported_environment_blend_modes()
        if XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND in modes:
            xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_ALPHA_BLEND
            viewport.transparent_bg = true
        elif XRInterface.XR_ENV_BLEND_MODE_ADDITIVE in modes:
            xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_ADDITIVE
            viewport.transparent_bg = false
    else:
        return false

    environment.background_mode = Environment.BG_COLOR
    environment.background_color = Color(0.0, 0.0, 0.0, 0.0)
    environment.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
    return true

func switch_to_vr() -> bool:
    var xr_interface: XRInterface = XRServer.primary_interface
    if xr_interface:
        var modes = xr_interface.get_supported_environment_blend_modes()
        if XRInterface.XR_ENV_BLEND_MODE_OPAQUE in modes:
            xr_interface.environment_blend_mode = XRInterface.XR_ENV_BLEND_MODE_OPAQUE
        else:
            return false

    viewport.transparent_bg = false
    environment.background_mode = Environment.BG_SKY
    environment.ambient_light_source = Environment.AMBIENT_SOURCE_BG
    return true

陰影轉為不透明度

「陰影轉為不透明度」是 Godot 3 專為 AR 推出的空間著色器渲染模式。這種模式下,物體表面陰影越多就越不透明;當表面完全受光照時,則變為全透明,顯示出現實世界。

但在不透明狀態時,表面依然會被實際渲染。這帶來兩個影響:

  • 由於同時寫入了深度緩衝區與顏色緩衝區,即使表面完全透明,仍會遮擋其後方的幾何物件。

  • 當表面處於陰影區域時變為不透明,因此虛擬物件可以將陰影投射到現實世界中的物件上 [2]

下圖示範以「陰影轉不透明度」來顯示使用者的桌面。

下圖示範以「陰影轉不透明度」來顯示使用者的桌面。

這種模式可實現以下應用場景:

  • 你可以在現實中的桌子周圍繪製一個方形網格,這樣即使有虛擬物件位於桌子下方,桌子依然會保持可見,虛擬物件也會正確被遮擋。而將虛擬物件放在現實桌子上時,則會正確產生陰影效果。

  • 你也可以在繪製手部網格並使用手部追蹤功能時,搭配此渲染模式,讓雙手能正確遮擋虛擬物件。

以下著色器程式碼可作為實現此功能的基礎:

shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, shadow_to_opacity;

void fragment() {
    ALBEDO = vec3(0.0, 0.0, 0.0);
}