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.
Checking the stable version of the documentation...
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);
}