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 時,必須將 Viewport 的 transparent_bg 屬性設為 true。若使用 XR_ENV_BLEND_MODE_ADDITIVE,則建議將背景顏色設為黑色。
無論哪種方式,背景都不會對場景照明產生影響。因此建議你調整環境設定,確保有足夠的環境光來照亮場景。
備註
部分 AR SDK 會提供環境光照資訊,甚至完整的輻射圖(radiance map),讓虛擬物件能反映現實世界的光線。Godot XR 核心目前尚未支援這些功能,但可以透過外掛實現。
OpenXR 專屬說明
在 OpenXR 中,你可以設定想要預設使用的混合模式。Godot 啟動時會嘗試選用這個模式,若不支援則會自動選擇 XR 執行環境所支援的第一個混合模式。
在透視裝置上,OpenXR 需要額外設定,這些設定會依平台而異,並由 OpenXR vendors 外掛提供。
例如,Meta Quest 需要以下設定:
「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);
}