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 )与透视¶
增强现实的支持方式因硬件不同而有所差异。
诸如 Magic Leap、TiltFive 等设备通过使用`“透视显示屏” <https://en.wikipedia.org/wiki/See-through_display>`__ 显示渲染结果,使得用户能同时看到虚拟与现实世界。
而另一方面, Quest、HTC Elite 和 Lynx R1 等设备通过一种称为视频透视(Video Passthrough)的技术实现这一功能:摄像头记录现实世界的画面作为渲染背景,在上面显示渲染结果。
备注
透视功能在不同平台上的实现方式也不尽相同。
在 Godot 4.3 中,我们实现了一种统一的方法,因此你无需担心这些差异,XRInterface 实现现在负责应用正确的平台依赖方法。
而对于 Meta Quest 和 HTC Elite 等头戴设备,你需要使用 `OpenXR vendors plugin v3.0.0 或更高版本插件<https://github.com/GodotVR/godot_openxr_vendors/releases>`__ 来启用视频透视功能。
为保证向后兼容,旧的透视 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 混合模式时,应将背景颜色设置为黑色。
这两种解决方案都会导致背景渲染不再提供环境照明。因此,建议相应地调整环境设置,确保有足够的环境光来照亮场景。
备注
部分增强现实 SDK 确实会提供环境光信息——甚至是完整的辐射图——以允许在虚拟对象中模拟真实世界的反射。不过,目前 Godot XR 的核心尚不支持此功能,但可以通过插件来实现。
OpenXR 特定功能¶
在 OpenXR 选项卡中,你可以配置想要使用的默认混合模式。如果该模式可用,Godot 将在启动时选择此混合模式。如果不可用,Godot 将默认选择 XR 运行时提供的第一个支持的混合模式。
对于透视设备,OpenXR 需要配置额外的设置。这些设置依赖于平台,并通过 OpenXR 供应商插件提供。
举个例子,以下是 Meta Quest 所需的设置:
Passthrough 设置定义了是否支持或者需要启动视频透视功能。
The Boundary Mode allows you to define whether the guardian is needed,
disabling this fully requires passthrough to be enabled at all times.
Putting it together¶
综合以上内容,我们可以使用以下代码作为基础:
@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
阴影转不透明模式¶
阴影转不透明( Shadow to opacity )是 Godot 空间着色器的一种渲染模式,在 Godot 3 中专门为 AR 引入。这种特殊的渲染模式会根据表面阴影决定其透明程度:当表面越多地处于阴影中,表面就变得越不透明。而表面完全被照亮时,表面会变得完全透明,从而显示出真实世界。
但是,表面实际上是在不透明状态下渲染的。使用该模式会导致两个后果:
由于深度缓冲区和颜色缓冲区都被写入,即使表面完全透明,我们仍会遮挡其后方的几何体。
由于我们将表面在阴影中变得不透明,因此虚拟物体可以在现实世界的物体上投射阴影。
“阴影到不透明”效果在用户桌面上的应用。¶
这使得以下应用场景成为可能:
你可以在现实世界的桌子周围渲染一个盒子网格,这样即使有虚拟物体放在桌子下面,桌子也能保持可见。虚拟物体会被正确地遮挡。当将虚拟物体放在现实世界的桌子上时,会在桌子上投下阴影。
在使用手部追踪功能渲染手部网格时,你可以使用这种渲染模式的着色器,以确保你的手能正确地遮挡虚拟物体。
以下着色器代码可以作为实现该功能的良好基础:
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);
}