Meta推出MR Motif,基于Raycast与Depth API实现虚实交互定位
通过即时内容放置来提升真实感和加快项目设置
(映维网Nweon 2025年03月06日)Mixed Reality Motif是一个帮助你在混合现实体验中快速执行常见机制的蓝图。为了帮助开发者克服在混合现实中构建高质量、同步的多人游戏体验所带来的挑战,Meta日前分享了Mixed Reality Motif的新系列:通过即时内容放置来提升真实感和加快项目设置。
随着v71的发布,我们引入了MRUK Raycast Beta API,而开发者几乎可以立即开始创建混合现实体验。在当前的混合现实环境中,内容放置可能是一个繁琐的过程,因为设置过程要求用户在启动混合现实体验时扫描房间。有了如此多的虚拟内容和面板用例(从菜单到对象以及介于两者之间的一切),快速放置各种可交互内容的能力对于创建无缝、愉快的体验比以往任何时候都更加重要。
这就是MRUK Raycasting的由来。这个功能是为想要在用户面前放置一个2D面板或3D对象的应用而设计。利用MRUK Raycasting,用户可以简单地看一下放置的方向,并可开始与2D和3D内容进行交互。
这种类型的即时放置可以实现大规模,无摩擦的体验,支持用户与其虚拟环境之间自然和现实的交互。例如在先前分享的通过共享活动来实现同步多人体验的主题中,我们创造了一个虚拟棋盘体验体验。在这种情况下,可以利用MRUK Raycasting轻松地放置虚拟棋盘并在其下方投射逼真的阴影。
在这个即时放置混合现实主题中,我们将专注于如何使用Depth API的基础知识,亦即Raycast API背后的核心技术-并通过利用深度信息直接在你的着色器中实现视觉效果。这需要建立必要的知识来理解EnvironmentDepthManager是如何支持EnvironmentRaycastManager。
另外,你将学习EnvironmentRaycastManager是如何使用它的环境信息来执行光线投射,返回命中点信息,并允许你毫不费力地放置对象。EnvironmentRaycastManager是MRUK包的一部分,所以在开始之前,请确保在项目中安装了MRUK v71或以上版本。
Depth API:基础
Depth API提供实时深度图,而应用可以用来感知周围环境。首先,它通过允许现实世界的物体和表面遮挡虚拟对象,令它们看起来融入了实际环境,从而增强混合现实体验。遮挡至关重要,因为它可以防止虚拟内容作为一个层出现在现实世界,并潜在地破坏沉浸感。
从v67版本开始,我们更新了检索深度纹理的机制,从而提高了质量和性能。EnvironmentDepthManager类,现在是Meta XR Core SDK的一部分,负责为着色器提供深度信息,并允许你创建以前几乎不可能的视觉效果和游戏玩法。
当利用深度API时,EnvironmentDepthManager类需要出现在你的场景中,以便在着色器和脚本中使用环境深度信息。这个类检查支持,初始化深度提供器,并从每帧的深度传感器中检索深度纹理。诸如_EnvironmentDepthTexture(真实世界的深度图),_EnvironmentDepthReprojectionMatrices(深度摄像头的视图投影矩阵)和_EnvironmentDepthZBufferParams(用于线性化深度值的参数)等关键属性在着色器中全局设置。EnvironmentDepthManager支持硬遮挡和软遮挡模式,可以应用对象特定的深度掩码。这个设置允许着色器将虚拟对象与真实世界的深度混合,以实现逼真的遮挡和视觉效果。
在着色器中访问深度变量
DepthLookingGlassMotif着色器使用渐变颜色效果将Depth API提供的真实世界深度可视化。它同时显示摄像头看到的虚拟对象深度。要看到虚拟场景对象,你需要启用深度纹理。
为了使用_EnvironmentDepthTexture, _EnvironmentDepthReprojectionMatrices和_EnvironmentDepthZBufferParams,我们可以导入包含Meta XR SDK Core package附带的稳健的着色器。相关文件包含处理环境深度采样和重投影的实用函数和预定义宏,允许我们轻松访问深度数据并将其集成到着色器中。同一个包含文件适用于BiRP和URP。
#include "Packages/com.meta.xr.sdk.core/Shaders/EnvironmentDepth/BiRP/EnvironmentOcclusionBiRP.cginc"
DepthLookingGlassMotif着色器展示了如何采样深度,并使用_EnvironmentDepthZBufferParams将数据从归一化设备坐标(NDC)转换为线性深度,使我们能够准确地测量从头显到环境深度的距离。
然后使用_EnvironmentDepthReprojectionMatrices将世界位置转换为正确的深度空间,以便比较场景深度和环境深度纹理。
_EnvironmentDepthTexture类是系统捕获的实际深度图,表示现实世界表面相对于摄像头的深度。
使用_EnvironmentDepthZBufferParams可以很容易地将采样深度归一化为线性深度,从而可以无缝地比较和混合虚拟对象和现实世界的深度。
这个功能使得基于物体相对于环境深度的位置来进行遮挡成为可能。如果你想在着色器可视化虚拟对象,记住这只适用于不透明对象,因为Unity中的透明对象不会写入深度缓冲区。
如果你依然想要写入深度缓冲区的不可见对象,我们在项目中包含了一个名为DepthMaskMotif的自定义着色器,而你可以应用到一个对象,使其不可见,但依然可以通过你的Depth Looking Glass看到。这种机制有助于创造密室逃生或捉鬼冒险等体验。
在着色器中访问深度图
对于这个Motif,你可以学习如何将效果直接应用于深度图。另外,当球体在空中飞行时,我们在深度图应用了照明效果。
球体本身有一个着色器,负责将自身遮挡在物体后面。要将遮挡添加到你的shadergraph着色器,你所要做的就是添加一个OcclusionSubGraph并将其接到着色器的alpha输出。在示例中,我们添加了一个名为Environment Depth Bias的浮动属性作为输入。稍微增加这个值将解析z-fighting,或者换句话说,防止我们的对象在太靠近墙壁时闪烁。
对于示例中的冲击波效果,我们使用一个简单的球体,其中它的大小随着时间的推移而增加,并且在它与深度相交的地方,我们应用一定的颜色来给它一个冲击波效果。你可以在项目中找到这个DepthScanEffectMotif着色器。它包含一个_Color属性,用于确定可视化的基本颜色。
另外,它有一个_Girth属性,用于控制冲击波的厚度。
以上就是我们如何使用Depth API来创建不同的视觉效果。接下来,我们将深入了解为什么这与即时内容放置相关。
即时内容放置
如果你看过这个项目,你可能已经注意到,为了把球体放在我们的房间里,我们根本没有使用任何网格。相反,我们利用了全新的EnvironmentRaycastManager。使用EnvironmentRaycastManager放置对象的基本概念如下:
重要的是是EnvironmentRaycastManager.Raycast函数。它对环境执行光线投射,并向我们返回命中结果,其中包含命中点、命中表面法线和法线置信度等信息。这是我们检测一个表面并在所述表面上放置任何对象所需的所有信息。
为了加深你对这个概念的理解,我们准备了一个名为InstantContentPlacement的额外场景。其中,我们将向你展示如何抓取对象并检测适合放置的任何表面。另外,使用相同的概念,我们在对象下方放置了一个接地阴影,它紧紧地贴在检测的表面之上,给予物体和体验更多的真实感。
在SurfacePlacementMotif类中,我们检查对象是否被抓取。在抓取时,我们想要更新我们的放置指示器,而它告诉我们是否足够接近表面来放置我们的对象。你会看到它从对象向环境投射一道光线。如果它碰到一个表面,我们测量对象和命中点之间的距离。一旦距离足够近,我们启用指示器并将其移动到命中点。
当取消选择时,我们首先检查是否碰到一个表面。如果是这样,我们测量距离来检查对象是否依然足够接近那个表面。如果是,我们平滑地将对象移动到表面上,稍微偏移一点,以便更好地可视化,这样我们依然可以看到阴影。最简单的即时放置是这样的:
using Meta.XR.MRUtilityKit; using UnityEngine; public class BasicInstantPlacement : MonoBehaviour { public Transform Object; public EnvironmentRaycastManager RaycastManager; // Check if we hit a surface below our object if (RaycastManager.Raycast(new Ray(Object.position, Vector3.down), out var hitInfo)) { // Position the object on the hitpoint/detected surface Object.position = hitInfo.point; } } }
开始在混合现实中放置虚拟内容
使用本博客的见解,GitHub的源代码项目,以及教程视频,你将拥有开始在物理环境中的几乎任何表面放置任何虚拟对象的知识和技能。利用Raycast API和Depth API来充分发挥其潜力,解锁独特的视觉效果,提供更多的乐趣和真实感,我们非常期待看到你将如何实现你的混合现实体验。