2016 年 11 月
第 31 卷,第 11 期
此文章由机器翻译。
HoloLens - HoloLens 简介
通过 Adam Tuliper |2016 年 11 月
这是为新的创新设备令人兴奋年。它有称其为虚拟现实 (VR) 的年份,增加现实 (AR) 和一些非常明显和寄予厚望设备已开始传送,包括 HoloLens、 HTC 和 Oculus 立夫特 CV1。John Riccitiello,首席执行官 Unity 技术,说的 AR/VR: "它是非常令人信服它按原义改变了一切,一次中代技术"和夫斯言。HoloLens,来自 Microsoft,令人兴奋的新设备都能够混合实部和虚拟世界。
什么是 HoloLens?
HoloLens 是方便停留在您头无约束,则完全自包含的 Windows 10 计算机。它是称为混合的实际设备,尝试 blend 实部和数字世界上的设备。您可以看到对象放在世界上看起来和 — 在一定程度上 — 表现基本一样它们在现实生活中。与此相反,VR immerses 您的环境中,您通常看不到任何内容你,但该虚拟世界各地。您一般不现实生活中直观地了解您 h e a d 装入的显示器 (HMD) 之外。 这种体验可能会跳转时您坐在办公椅飞入外部空间。并且 AR 尝试增强周围世界的额外数据,如标记或可能适用于您所在的位置的 heads-up 信息。有些 AR 耳机只引发重叠你看到的任何屏幕上文本和图像。
使用 HoloLens,可以将应用程序和对象放到您了解您的环境周围世界。如果您希望固定到墙上插座或中间空气类似数字屏幕,在应用程序中所示 图 1, ,没问题。此类应用程序保留,即使您留出您的空间并返回第二天。我已经不断地将虚拟 windows 打开其他聊天室,若要对感到惊讶时我回去天之后,它们仍然存在。还远不止这些。假设您希望 (包括攀上沙发若要查看 h e a d 的顶部),您可以四处走动和检查您的客厅可以顺利放在手边的主干。同样,没问题。删除虚拟 3D 对象,例如一个球 — 称为一张全息图,为您的世界和它将处于和命中真实表并且停止。将表移动和球将处于并且命中您真正的场所。HoloLens 了解周围世界,大多数是第一次它们 (尽管我一直盼能够下载到我的头脑功夫) 尝试绝对迎接惊喜吧。
图 1 在墙上的应用程序
在本文中,我将讨论 HoloLens 开发环境和输入的三个支柱 — 对此、 手势和语音,它表示与 HoloLens 进行交互的主要方式。更多 HoloLens 功能,例如空间映射,将在我的下一篇文章中介绍空间音频和坐标系统。
工具和 SDK
没有 HoloLens 的单独 SDK — 它是简单的 Windows 10 SDK 的一部分。您只是需要 Visual Studio 2015 与 Update 3 + 安装,并确保您已经在安装过程勾选了"工具和 Windows 10 SDK"。你可以回过头来运行 Visual Studio 安装程序在再次选择这些选项,当然,只需再次运行更新 3 (或更高版本有可能的话) 安装程序。
HoloLens,通用 Windows 平台 (UWP),因为它是一个 Windows 10 设备,运行于 UWP 应用。没错,不仅在桌面、 手机和 Xbox,但上也 HoloLens 任何 Windows 10 应用程序可以运行。您可以找到有关获取 Windows Phone 和 Windows 应用商店非 UWP 应用程序并将它们在转换已发布的指南 bit.ly/2c3Hkit。若要确保 UWP 应用程序将出现在 Windows 应用商店,请确保你已留 HoloLens 设备系列在 Windows 开发人员中心发布您的应用程序时,如中所示 图 2。与在任何平台上的任何应用程序的情况一样,您需要确保您的应用程序将显示您面向,在特定设备上良好,如不同的设备具有不同分辨率和内存功能。
图 2 确保 Windows 开发人员中心提交支持 HoloLens
开发全息版应用程序的两个选项,可以充分利用 HoloLens 功能的类型设置,包括 DirectX 和 Unity。此外可以创建使用 C# 和 XAML 中,一个普通 UWP 应用程序,但它将在 HoloLens 运行作为 2D 应用程序且未显示在空间中删除全息周围的能力。有多种项目模板在 Visual Studio 中的全息版应用程序可以显示全息,如中所示 图 3。请确保满足之前要求,否则您可能看不到可用的模板。Unity (HoloLens 我首选的开发环境) 具有在其网站上提供的 HoloLens 技术预览 (HTP) 生成中现成支持 bit.ly/2bBZsNn。
图 3 HoloLens DirectX 模板
在某些时候,但是,您必须接触 Visual Studio 中,即使您使用 Unity 中,尽管开发体验都是使用纯 DirectX 有很大不同。将部署到 HoloLens 通过 Visual Studio,可以在通过本地的 USB 连接的远程连接或通过仿真程序中,如中所示 图 4。
图 4 将部署到 HoloLens 的不同方法
文档如何呢? MSDN 一直为开发人员,而年就很难查找正是您所需要的新增功能的一项重要功能。现在文档是完全重做在 docs.microsoft.com。HoloLens 团队想要其文档,可很好,并且应该能够找到在同一位置中的大多数情况 bit.ly/1rb7i5C。如果您发现某些东西,告知 HoloLens 团队。我们做出了许多改进,在 Microsoft,更好的一个新时代,HoloLens 团队正在帮助冲锋良好、 稳定文档进行深入交流。
硬件 HoloLens 显示在 60 FPS,因此是非常重要,以确保在此帧速率运行您的经验。您还需要确保你可以将其保持在该设备的内存要求 (如编写本文时这就意味着 900 MB 可用 RAM 为你的应用)。如果您是初次接触开发图形体验,它很容易获取任何艺术资产,并将其放在场景中。您可能认为,"我可以通过抓取我的城市的 3D 模型并将其放到我的场景和浏览该模型 !" 但这可能会在任何平台上导致问题。请记住大多数游戏实现许多技巧以减少绘制调用、 遮蔽几何、 显示是进一步远离 (调用的级别的详细信息或 LOD) 的较低分辨率模型以及其他更多 HoloLens 也不例外。在列出性能建议 bit.ly/2besJxQ。优化的一些示例所示的"优化游戏"模块处 bit.ly/2dBqMxw。
仿真程序 HoloLens 仿真程序可使您很远的开发过程。从技术上讲,您无需 HoloLens,就可以开发一种体验,就像您不需要要开发一部电话的电话号码。在某些时候,但是,您显然需要在设备上进行测试。仿真程序可模拟笔势、 头位置和声音,但它确实有限制。举例来说,当您处于一个仿真程序,您将看现实生活中您全息周围作为 图 5 所示,尽管可以将着色器分配给您空间的网格中,将在下一篇文章中予以介绍。
图 5 使用 HoloLens 仿真程序
有四个可在仿真程序中选择的预定义的房间模型。因为在您头上没有 HoloLens,仿真程序应了解有关房间和如下所示从 3D 角度来看。我跳转继续到下一篇文章中有点影响,但 HoloLens 了解您周围的空间,并在不断地更新此空间,它对理解,如中所示 图 6。"幕后"视图 HoloLens 所看到的内容非常默认情况下,在模拟器中加载并显示在 Windows 设备门户中,您可以访问的仿真器或真实的 HoloLens 设备的空间。可以保存一个房间模型已使用 HoloLens 扫描并将程序加载到仿真程序 — — 这意味着您还可以开发使用 HoloLens 和模拟器或仿真程序的多个实例的多个用户体验,然后在要测试您自己自定义聊天室中加载。
图 6 显示仿真程序中加载的默认空间模型
Windows 全息版
Windows 10 全息版 Windows 平台包含 Api,可跨桌面、 移动和 Xbox。正是通过这些 Api,您可以与交互 HoloLens 不仅其他将来使用的设备,同样,包括来自其他供应商,如 Intel 的新项目 Alloy 无约束的耳机、 HTC、 Qualcomm,以及许多其他计划。某些 Api 的 Windows 全息版可在以下新的命名空间 (我建议查看这些内容以了解一些基础类和结构的)︰
- Windows.Graphics.Holographic (bit.ly/2bFbeqv)
- Windows.Perception (bit.ly/2bVNMHj)
- Windows.Perception.Spatial (bit.ly/2bwjB8h)
- Windows.Perception.Spatial.Surfaces (bit.ly/2bG9jCZ)
- Windows.UI.Input.Spatial (bit.ly/2bipBOo)
有三个支柱 HoloLens 输入 — 对此、 手势和语音和这些是什么我将重点现在。如果已读取所有游戏开发上我以前的文章,或为 Microsoft 虚拟学院观看过我的在线视频,您知道我非常喜欢的游戏引擎 Unity 中,因此请按照这些代码示例是基于 Unity C# 的。
对此本质上是其中 HoloLens 是,尽管它是最简单时要考虑它位于您 h e a d。若要了解什么对此表示,让我们看在 Windows.Perception.People 命名空间中 HeadPose 类,该类包含三种 Vector3 类型 (Vector3 结构包含 x、 y 和 z 单个值)︰
- ForwardDirection: 获取 HoloLens 的向前方向。
- 位置︰ 获取 HoloLens 的位置。
- UpDirection: 获取到 HoloLens 了方向。
此信息有助于您确定该用户的位置和所要查找的方向。当应用程序启动 HoloLens 上时,起始位置位于 0,0,0。从该位置它就可以方便地确定用户位置和方向移动。我们首先来了解一下如何检测用户正在的对象。要求是此对象具有上它可以检测,即在 Unity 中轻松地将添加到任何对象的碰撞体组件。在 Unity 中,而不是 HeadPose,只需使用 Camera.main 信息,映射到 HeadPose (后台) 的。如果您习惯于在 Unity 中使用相机,执行任何操作会不同。使用此信息,可以给的不可见的箭头,并了解它遇到 (强制转换的 3D 编程调用 ray 的常见技术)。我只是需要如 Interactible 脚本的多维数据集的游戏对象 (图 7) 和另一台单独空的游戏对象与 InteractibleManager (图 8) 在其上。
图 7 Interactible 类
public class Interactible : MonoBehaviour
{
// The materials we’ll set to highlight.
private Material[] defaultMaterials;
void Awake()
{
// Get the materials from our renderer.
// A material contains a shader which lights/colors object.
defaultMaterials = GetComponent<Renderer>().materials;
}
void GazeEntered()
{
for (int i = 0; i < defaultMaterials.Length; i++)
{
// This assumed we're using a shader that has a Highlight
// property, as does the Custom/SpecularHighlight one
// from Holograms 210. This adds lighting color to it
// to "highlight" it.
defaultMaterials[i].SetFloat("_Highlight", .25f);
}
}
void GazeExited()
{
for (int i = 0; i < defaultMaterials.Length; i++)
{
defaultMaterials[i].SetFloat("_Highlight", 0f);
}
}
}
图 8 InteractibleManager 类
public class InteractibleManager : MonoBehaviour
{
private GameObject lastHit;
// Every frame see if we are looking at a HoloGram (i.e. a game object).
void Update()
{
RaycastHit hitInfo;
if (Physics.Raycast(
Camera.main.transform.position,
Camera.main.transform.forward,
out hitInfo,
10.0f,
Physics.DefaultRaycastLayers))
{
// The game object we've hit.
var tempGO = hitInfo.collider.gameObject;
// See if this object contains our Interactible class.
if(tempGO.GetComponent<Interactible>() != null)
{
lastHit = tempGO;
// Loosely coupled way to call a method in Unity on our g.o.
lastHit.SendMessage("GazeEntered");
}
}
else
{
// No object detected in Gaze, lets deselect the last one.
if(lastHit!=null)
{
lastHit.SendMessage("GazeExited");
lastHit = null;
}
}
}
}
我将介绍仅仅概述主要的观点。您会发现更多详细信息中全息 210 全息学院课程上对此概念,包括稳定的头的位置,若要选择的对象时避免平稳移动 (bit.ly/2b9TWlR)。简单地说,Camera.main 是 HoloLens 位置。排除您不可见 ray 从此位置中找到您遇到的第一个碰撞体的 Camera.main.forward 方向。如果您发现的内容,只需要是以突出显示它通过设置着色器将使用的变量。例如,在 图 7, ,我使用从全息 210 着色器,只需将 _Highlight 值设置为.25 当选中。可以使用标准 Unity 着色器,同样,并设置发出颜色的亮度相反,如下所示︰
defaultMaterials[i].SetFloat("_EmissionColor", Color(0,0,0,.2f);
您需要注意的着色 HoloLens 的性能的影响。此设备,同时惊人,受约束其大小通常是与硬件这种情况。几乎每个经验和今天所做的游戏有时间进行优化,分配并没有什么不同 HoloLens。开发使用 Unity HoloLens,您需要做的第一个操作时,交换出位于在 HoloToolkit 的优化变体的着色器 bit.ly/2bO6cH2。
HoloToolkit 包含多个帮助器函数和对象,可以极大地帮助 HoloLens 开发,包括游标,看一下稳定、 笔势和分发管理器、 平面检测器,请按照-我的脚本,用于共享跨多个 HoloLens 和其他更多的示例。大部分此功能是在 HoloToolkit Unity 中 bit.ly/2bO8XrT, ,因此请确保在正确的存储库和不仅要看在基本 HoloToolkit 查找 bit.ly/2bPCbas, ,而后者但是,可在自己的权限,并且包含各种独立示例项目和 HoloToolkit Unity 利用其他库代码。
如果您有不在可视区域中的对象,无论该游戏在屏幕、 VR,AR 或混合的现实,很有用提供较小的指示器,以告知用户他们应查找对象在启动时消失,如中所示查找方向 图 9。这是很常见技术在很多视频游戏中,并在混合现实世界中是非常有用。
图 9 显示方向指示器
中的代码 图 10 可用来确定特定全息图是否可见。
图 10 确定是否是可见的一张全息图
[Tooltip("Allowable percentage (to 30%) inside the holographic frame to continue to show a directional indicator.")]
[Range(-0.3f, 0.3f)]
public float TitleSafeFactor = 0.1f;
// Determine if sgame object is visible within a certain percentage.
// The Viewport is 0,0 to 1,1 (bottom left of screen to top right).
private bool IsTargetVisible()
{
// This will return true if the target's mesh is within the Main
// Camera's view frustums.
Vector3 targetViewportPosition =
Camera.main.WorldToViewportPoint(gameObject.transform.position);
return (targetViewportPosition.x > TitleSafeFactor &&
targetViewportPosition.x < 1 - TitleSafeFactor &&
targetViewportPosition.y > TitleSafeFactor &&
targetViewportPosition.y < 1 - TitleSafeFactor &&
targetViewportPosition.z > 0);
}
一旦您知道如果对象不是可见的 (或几乎看不到),则可以找出的方向,以显示方向指示器。由于你有权访问照相机位置和游戏对象的任意位置,很容易就可以计算出一张全息图中与用户正在进行比较。若要获取从照相机传送到特定的游戏对象的一个箭头方向向量表示数减去从另一个位置然后规范化以使其基于 1 的 (它是最简单的方法在许多计算中使用规范化的向量),如下所示︰
Vector3 camToObjectDirection =
gameObject.transform.position - Camera.main.transform.position;
camToObjectDirection.Normalize();
显示方向指示器的确需要一些其他事情进行设置,但这是功能的要点。一旦您知道 HoloLens (camera) 全息图的方向,可以在屏幕上显示一个指示符。您可以签出此功能的更详细地介绍 bit.ly/2bh0Hz7。
手势是下一步的方式来处理 HoloLens 的输入。手势手、 控制器或语音命令执行。手手势的扫描中是否有通过其中一种正面中所谓的手势框架中,扩展的全息图,它允许你可以将您的手更接近保留到您的身体,而不是让它的各边的查看区域广度照相机出每个时间的方式。您通常不点击全息,但改为点击并确定哪些用户看看一下通过。
HoloLens 支持两种类别的手势。第一个包括离散的手势,如中所示空气点击一次快速操作如 图 11, ,单击包含蓝牙 clicker,告知命令"Select,"或者甚至是一个双精度的分流点。第二种类型包括连续手势,而随着时间的推移发生这种情况通常被触发时您按住,接下来您手中。连续手势为导航和操作提供支持。导航笔势为您提供 0,0,0 的起始位置 — 即开始手势的任何位置 — 然后约束,您可以继续从-1 到 1 该多维数据集内的任何轴 (以及其他用例) 提供的空间中的虚拟多维数据集和平滑围绕一个或多个轴或平滑滚动旋转角度。操作手势,而不是虚拟的多维数据集,将约束允许他人之手和全息之间 1:1 移动 — — 几乎绘制或很好的流畅动作来定位您在环境; 全息的思考时间相对于世界上的位置信息参与 x,y,z。
图 11 无线 Tap
作为开发人员可以当然,挂钩到手势,如空气 tap 中,保存,导航和操作。目前不支持的自定义特定动作,但必须对通过上述手势相当多的数据的访问。您还可以跟踪手 (当在中的就绪状态或按下的状态) 放置在 x、 y、 z 和了解手中时或者在手势框架情况下,这可以提供有用的反馈向用户太多的事情正准备离开手势帧时。
图 12 GestureManager 类
public class GestureManager : MonoBehaviour
{
private GestureRecognizer gestureRecognizer;
void Start()
{
gestureRecognizer = new GestureRecognizer();
// We can register here for more than just tap (ex Navigation).
gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap);
gestureRecognizer.TappedEvent += (source, tapCount, ray) =>
{
// A tap has been detected.
// Raycast using the provided ray and get the hit game
// object and perform some action on it as was done previously.
};
gestureRecognizer.StartCapturingGestures();
}
void OnDestroy()
{
gestureRecognizer.StopCapturingGestures();
}
}
您可以添加一个 GestureManager 类如中所示 图 12 若要注册分流事件,这可让您知道,例如,当用户已执行了一个点击手势通过选择语音命令、 控制器或手的形状 (无论点击其中)。然后,您需要确定什么要查找在当用户点击,就像以前做什么。值得注意的是在 TappedEvent 图 12 中表示其中 h e a d 时该事件发生的一条射线传递。在快速磁头运动的情况下,你想要确保 raycast 从看一下所在当用户点击,位置无关时该事件到达时,这可能会稍有从原始位置。
语音命令上 HoloLens Cortana,通过某一系统级别上支持,但也共享相同的语音引擎为所有其他 UWP 应用程序,并因此需要在项目的 package.appxmanifest 文件中的麦克风设备功能。音频处理是硬件加速,并提供 16 khz 48khz 至 24 位音频流的用户的声音和环境的环境。内置 Cortana 命令包括"Select""您好 Cortana < 命令 >",并且在应用程序命令包含"Select"(而不是无线点击) 和"放置"。
对自定义语音命令的响应,并且可能非常简单。只需添加关键字并委托代码来执行,并开始侦听,如中所示 图 13。
图 13 中添加关键字和委托代码
public class SpeechManager : MonoBehaviour
{
KeywordRecognizer keywordRecognizer;
Dictionary<string, System.Action> keywords =
new Dictionary<string, System.Action>();
void Start()
{
keywords.Add("Reset level", () =>
{
// Call the OnReset method on every descendant object to reset their state.
this.BroadcastMessage("OnReset");
// We could also do a full-level reload via
// SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
});
// Tell the KeywordRecognizer about our keywords.
keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());
// Register a callback for the KeywordRecognizer and start recognizing!
keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
keywordRecognizer.Start();
}
private void KeywordRecognizer_
OnPhraseRecognized(PhraseRecognizedEventArgs args)
{
System.Action keywordAction;
if (keywords.TryGetValue(args.text, out keywordAction))
{
keywordAction.Invoke();
}
}
}
对于那些希望进行语音到文本,听写可用,则同样,使用 DictationManager 类来获取 DictationHypothesis、 DictationResult、 DictationComplete 和 DictationError 事件。请注意这要求将 WiFi 连接。我的同事 Jared Bienz 添加了文本到语音,同样,可以在 Unity HoloToolkit 中找到一些很好的支持。
总结
HoloLens 打开如何,您可以体验您混合现实情况和虚拟世界周围世界中一个新时代。开始在 HoloLens.com 并监视公告。将映射到继续关注我将讨论了我最喜欢的 HoloLens 功能,空间的下一篇文章。
Adam Tuliper 是与生活在阳光明媚 SoCal Microsoft 的资深技术推广人员。 他是 Web 开发者/游戏开发者、Pluralsight.com 作者以及全面技术的爱好者。在 Twitter 上了解他︰ @AdamTuliper 或 channel9.msdn.com/Blogs/AdamsGarage。
衷心感谢以下 Microsoft 技术专家对本文的审阅: Jackson 字段
Jackson 字段是在 Microsoft 的软件工程师