常见网站架构,免费开放api,湖南企业网站营销设计,洛阳建设工程网站文章目录 #x1f4d5;教程说明#x1f4d5;动态开启和关闭透视⭐方法一#xff1a;OVRManager.instance.isInsightPassthroughEnabled⭐方法二#xff1a;OVRPassthroughLayer 脚本中的 hidden 变量 #x1f4d5;透视风格 Passthrough Styling⭐Inspector 面板控制⭐代码… 文章目录 教程说明动态开启和关闭透视⭐方法一OVRManager.instance.isInsightPassthroughEnabled⭐方法二OVRPassthroughLayer 脚本中的 hidden 变量 透视风格 Passthrough Styling⭐Inspector 面板控制⭐代码控制 局部透视⭐透视材质⭐设置 OVRManager.eyeFovPremultipliedAlphaModeEnabled 为 false⭐表面投射透视 Surface-projected Passthrough步骤一OVRPassthroughLayer 脚本中的 Projection Surface 参数步骤二OVRPassthroughLayer 脚本中的 AddSurfaceGeometry 方法 ⭐多个透视图层OVRPassthroughLayer 上的 Composition Depth 参数 教程说明
前期需要的一体机开发的环境配置可以参考这篇教程Unity VR 开发教程: Meta Quest 一体机开发 一 环境配置
电脑操作系统Windows
使用的 VR 设备Meta Quest 2
使用的 Unity 版本2021.3.5 LTS (这里推荐使用 2021 及以上的 LTS 版本)
Oculus Integration 版本v54 目前 v54 以上也适用
官方文档https://developer.oculus.com/documentation/unity/unity-passthrough/
注本篇教程可能具有时效性因为 Oculus 的 SDK 更新迭代得比较快如果大家使用的 SDK 版本比我的新在不方便查看官方文档的情况下也可以先试试本篇教程的配置步骤如果发现教程过时欢迎大家进行反馈我也会及时进行更改说明一切以官方文档为主。
上一篇教程我们学习了 Quest Passthrough 透视功能的环境配置实现了在透视的现实场景下看到虚拟的物体。教程链接Unity Meta Quest MR 开发教程一混合现实 MR 透视 Passthrough 环境配置强烈推荐上一篇教程看完了对设置透视场景的步骤熟悉了之后再来看这篇教程
实际上我们还可以自定义透视比如设置透视的风格、颜色设置局部透视比如一个虚拟的世界下有一小块地方是透视的现实场景等。所以这篇教程我们来学习一下如何自定义透视功能相当于对透视功能的介绍进行补充。
当我们导入 Oculus Integration 后在下图所示的路径下可以看到官方提供的几个透视 Demo它们基本上涵盖了 Quest 透视的一些用法大家可以自己体验一下。我会选取几个重点进行讲解。 动态开启和关闭透视
我们可以在程序运行过程中通过代码动态地控制透视的开启和关闭。
⭐方法一OVRManager.instance.isInsightPassthroughEnabled
我们可以用以下代码控制透视的开启和关闭。
OVRManager.instance.isInsightPassthroughEnabled true;
OVRManager.instance.isInsightPassthroughEnabled false;这个相当于控制场景中 OVRCameraRig 物体上的 OVR Manager 脚本中的 Enable Passthrough 选项。 ⭐方法二OVRPassthroughLayer 脚本中的 hidden 变量
我们可以在 OVRCameraRig 物体上添加 OVRPassthroughLayer 脚本 OVRPassthroughLayer 控制着透视图层。因为透视场景也相当于一个图层 Layer所以我们可以用以下代码控制透视图层的开启和关闭当透视的图层关闭了我们就看不到现实场景了。
public OVRPassthroughLayer passthroughLayer;
//在passthroughLayer 变量被赋值后用以下代码
passthroughLayer.hidden true;
passthroughLayer.hidden false;OVRPassthroughLayer 类下的 hidden 变量是个 bool 类型当 hidden 为 true 时透视图层被隐藏我们在头显里就看不到现实场景了。
注使用这种方法时要确保 OVRManager 脚本中的 Enable Passthrough 是勾选上的。而使用方法一时 Enable Passthrough 一开始可以不用勾选。因为这个 Enable Passthrough 勾选上了会在程序启动时就初始化透视。如果没有初始化OVRPassthroughLayer 的功能也是无效的而只有 OVRManager.instance.isInsightPassthroughEnabled 能够控制 Enable Passthrough 的开启和关闭。 透视风格 Passthrough Styling
⭐Inspector 面板控制
我们可以设置 OVRPassthroughLayer 脚本上 Style 的参数来自定义透视的风格 Opacity透视的透明度 Edge Rendering勾选之后在透视场景中现实物体的边缘的颜色会高亮显示而 Edge Color 是设置边缘的颜色。效果如下图所示图片来自 Meta 官方文档可以看到物体的边缘有绿色的高亮轮廓 Color Control可以对透视图像呈现的色彩效果进行更细致的控制它能够将设备采集到的色彩图像作为输入通过 Color Mapping 技术转换成新的色彩图像进行输出。点击 Color Control 按钮会出现以下几个选项 根据官方文档的说法它们的作用如下 None: Display passthrough images unchanged. Color Adjustment: Adjust the image’s brightness, contrast, and saturation. Saturation adjustment only has an effect on devices that support color passthrough. Grayscale: Adjust brightness and contrast and apply a posterization effect to grayscale passthrough images. Color passthrough images are converted to grayscale first if this option is chosen. Grayscale To Color: Colorize grayscale passthrough images, adjust brightness and contrast, and apply a posterization effect. Color passthrough images are converted to grayscale first if this option is chosen. Color LUT: Apply a color look-up table (LUT), which maps each RGB input color into an arbitrary RGB(A) in the passthrough image stream. Blended Color LUTs: Apply the blend between two color LUTs to the passthrough image stream. This option can be used to smoothly transition between two color LUTs. 这里介绍一下前三种它们使用起来比较简单方便。后两种的专业性更强一点使用起来略微复杂感兴趣的可以查看官方文档https://developer.oculus.com/documentation/unity/unity-customize-passthrough-color-mapping/
Color Adjustment 选择后 Inspector 面板如下 其中Contrast 表示对比度Brightness 表示亮度Saturation 表示饱和度。
Grayscale 其中Posterize 表示色调分离度。大家可以自己调整一下 Poseterize 的数值感受透视效果的不同。
Grayscale To Color 相比 Grayscale 模式多了个 Colorize 参数。在上一篇教程中我们有介绍过可以改变眼部相机的 Background 颜色来改变透视的颜色。这个 Colorize 也能调整透视的颜色它是一个 Unity 中的 Gradient 类型能够调整色彩的渐变我们可以点击 Colorize在弹出的 Gradient Editor 面板中对颜色进行调整。 ⭐代码控制
首先需要一个 OVRPassthroughLayer 类的实例
public OVRPassthroughLayer passthroughLayer;确保这个实例不为空后我们就可以用代码对透视风格进行控制了从结果上而言和在 Inpsector 面板中调整参数是一样的。
调整透明度
passthroughLayer.textureOpacity 0.5f;开启 Edge Rendering
passthroughLayer.edgeRenderingEnabled true;改变 Edge Rendering 颜色
passthroughLayer.edgeColor Color.green;改变对比度
passthroughLayer.colorMapEditorContrast 0.5f;改变亮度
passthroughLayer.colorMapEditorBrightness 0.5f;改变色彩分离度
passthroughLayer.colorMapEditorPosterize 0.5f;改变饱和度
passthroughLayer.colorMapEditorSaturation 0.5f;改变透视色彩 先定义一个 Gradient 类的变量
public Gradient colorGradient;然后我们可以在 Inspector 面板中编辑颜色 编辑完后写下如下代码
passthroughLayer.colorMapEditorGradient colorGradient;此外我们还可以用如下方法对透视风格进行设置 局部透视
局部透视的效果如下图所示 也就是在虚拟场景中有一小块区域是透视场景。
⭐透视材质
Oculus Integration 中有一个透视的 Shader我们可以新建一个材质 Material然后修改它的 Shader 为 SelectivePassthrough 另外我们还需要增大材质中的 Render Queue 的数值默认是 2000。但是如果是按默认的值我们无法看到透视材质。Render Queue 越大越后渲染。建议是设置到 2500 以上我这边设置成了 3000。确保透视材质比场景中的其他虚拟物体后渲染这样我们才能看到透视材质叠加在虚拟场景上。这时候我们的透视材质就创建成功了把透视材质赋给一个物体这个物体的表面会变成透视的区域。
为了演示我创建了一个有天空盒的场景导入 OVRCameraRig 预制体然后在眼部相机前放了一个方块将刚刚创建的透视材质赋给方块并且像前一篇教程那样设置好 OVRCameraRig 上的 OVRManager 和 OVRPassthroughLayer 脚本参数。 OVRManger OVRPassthroughLayer 相机 ⭐设置 OVRManager.eyeFovPremultipliedAlphaModeEnabled 为 false
如果这个时候尝试去运行程序你可能会发现透视材质看上去颜色比较淡太过透明不是很清晰。我们需要在代码中将 OVRManager.eyeFovPremultipliedAlphaModeEnabled 设为 falseOculus Integration 中已经为我们提供了相关的脚本。我们可以在 OVRCameraRig 物体上添加 EnableUnpremultipliedAlpha 脚本。 using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnableUnpremultipliedAlpha : MonoBehaviour
{void Start(){// Since the alpha values for Selective Passthrough are written to the framebuffers after the color pass, we// need to ensure that the color values get multiplied by the alpha value during compositing. By default, this is// not the case, as framebuffers typically contain premultiplied color values. This step is only needed when// Selective Passthrough is non-binary (i.e. alpha values are neither 0 nor 1), and it doesnt work if the// framebuffer contains semi-transparent pixels even without Selective Passthrough, as those will have// premultiplied colors.
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_ANDROIDOVRManager.eyeFovPremultipliedAlphaModeEnabled false;
#endif}
}
设置 eyeFovPremultipliedAlphaModeEnabled 为 false 的原理可以参考代码的英文注释因为本人对这方面知识的学习不是很深所以这里就不展开了也欢迎了解原理的小伙伴解释一下。
没有设为 fasle 的运行结果可以看到材质比较透明效果不是很好 设为 false 的运行效果 另外如果要确保虚拟物体和透视区域的前后遮挡关系需要将 OVRManager.eyeFovPremultipliedAlphaModeEnabled 设为 false否则因为透视区域的视觉效果太过透明导致无法看到前后遮挡的情况。
我们分析一下设置了透视材质后的视觉效果。可以看到方块的表面是透视的区域。因为 OVRPassthroughLayer 中设置了 Underlay透视图层会位于虚拟图层之下所以如果不加透视材质整个虚拟场景会覆盖在透视场景上面。而加了透视材质后相当于方块的表面变“透明”了我们就能直接看到位于虚拟场景之后的透视场景。
用简易的图来解释原本透视图层和虚拟图层的位置如下透视图层在后虚拟图层在前。 添加了透视材质后相当于在虚拟图层上开了一个洞这时候就能透过洞看到后面的透视图层 ⭐表面投射透视 Surface-projected Passthrough
这个功能相当于把透视的部分限制在某个区域。之前的透视材质只是让某个物体的表面呈现出位于虚拟图层后方的透视图层这时候我们的透视图层依然包含了整个现实场景相当于设备将整个现实环境进行重建只不过刚好加了透视材质的区域变“透明”了才能看到“藏”在虚拟图层后的现实场景。而有的时候我们想把透视图层限制在一个小的范围这时候就要用上表面投射透视 Surface-projected Passthrough它可以将透视场景投射到某些物体的表面上这时候透视图层只有在物体的表面上是可见的其余的部分的透视图层是不可见的。
官方文档https://developer.oculus.com/documentation/unity/unity-customize-passthrough-surface-projected-passthrough/
透明材质和表面投射透视的区别可以用下面这张图来描述 假设透视图层都位于虚拟图层的下方那么在右侧的表面投射透视中透视图层实际上是藏在虚拟图层之下被虚拟图层所覆盖所以我用虚线来表示。这种情况下透视图层被限定到了一个比虚拟图层更小的范围内。
步骤一OVRPassthroughLayer 脚本中的 Projection Surface 参数
如果你想要透视图层为整个现实环境你需要将 OVRPassthroughLayer 脚本中的 Projection Surface 参数设为 Reconstructed。而如果你想要用上表面投射透视将透视图层限定在指定的一个范围内你需要将 Projection Surface 参数设为 User Defined。 步骤二OVRPassthroughLayer 脚本中的 AddSurfaceGeometry 方法
在设置了 Projection Surface 为 User Defined 之后我们需要指定什么物体的表面能够投射透视场景。这时候就要用上 OVRPassthroughLayer 脚本中的 AddSurfaceGeometry 方法我们可以新建一个脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PassthroughUserDefine : MonoBehaviour
{public OVRPassthroughLayer passthroughLayer;public bool isTransformUpdate;private MeshRenderer meshRenderer;void Start(){Init();}private void Init(){if (passthroughLayer null){passthroughLayer GameObject.Find(OVRCameraRig)?.GetComponentOVRPassthroughLayer();}passthroughLayer.AddSurfaceGeometry(gameObject, isTransformUpdate);meshRenderer GetComponentMeshRenderer();meshRenderer.enabled false;}
}这个 AddSurfaceGeometry 需要传入两个参数一个是表面需要被透视投射游戏物体另一个是个 bool 值。 注 1这个方法只有在设置了 Projection Surface 为 User Defined 之后才能生效。 2第二个 bool 参数表示限定的透视区域是否会跟随物体的移动而移动。我们知道透视的场景会被投射到物体的表面上如果为 false透视区域会一直处于物体初始化的位置后续如果物体移动了透视区域的位置不会改变如果为 true透视区域会在每帧进行渲染可以随着物体的移动而移动会确保透视场景一直投射在物体的表面上。 3我在脚本中还关闭了物体的 MeshRenderer这是因为我们不希望看到虚拟物体原本的材质。如果处于 Underlay 模式并且物体的 MeshRenderer 是激活的即使透视场景被投射到了物体表面上还是会因为透视图层位于虚拟图层之上导致物体原本的材质覆盖了透视的场景。
脚本创建完毕后我们需要把它挂载到表面需要被投射的物体上。我这里重新创建了一个大方块给它添加刚刚创建的脚本 这个大方块的表面作为透视可见的区域然后我在这个方块面前放了个小的方块作为虚拟物体。 为了更加明显地看出表面投射透视的特征我又加了两个拥有透视材质的球并且让它们跟随手柄运动。
首先在下图所示的这两个物体上创建球作为子物体这时候球就会跟随手柄运动 然后把透视材质赋给球 这样我们的手柄周围就会跟随着一个拥有透视材质的球。这个时候我们运行程序看下效果 因为此时 OVRPassthroughLayer 处于 Underlay 模式所以透视图层位于虚拟图层之下一开始我们只能看到虚拟场景。而跟随手柄的球具有透视材质我们就能够通过透视材质看到位于虚拟图层下方的透视场景。然后我们发现只有设置了表面投射透视的大方块表面上可以看到透视图层而大方块区域以外之只能透过透视材质看到黑色的场景因为其余的透视图层是不可见的我们看不到其余部分的透视场景。
如果你把 Projection Surface 改成 Reconstructed透视图层的范围就不会被限定我们始终能透过球看到透视场景。
你也可以改变脚本的 isTransformUpdate 参数然后在运行过程中移动大方块就能够看出 true 和 false 的区别如果设为 true透视区域会跟随大方块移动。
此外具有透视材质的球与红色的虚拟方块还有前后遮挡的关系。当透视球放在虚拟方块前的时候虚拟方块会被球遮挡当透视球放在虚拟方块后的时候球会被虚拟方块遮挡。 不过前提是透视材质的 ZTest 设为了 LessEqual。具体原理和 Shader 渲染有关感兴趣的小伙伴可以深入研究。 ⭐多个透视图层
多个透视图层基本和表面投射透视一起使用。我们可以在虚拟场景中限定多个透视可见的区域每一个透视区域相当于一个透视图层每一个透视图层由一个 OVRPassthroughLayer 脚本来控制。沿用演示表面投射透视的场景我在场景中用一个横着的方块来表示一个新的透视可见区域那么之后我们就要在这个新的大方块上添加表面投射透视 然后创建一个空物体命名为 Second Passthrough给它添加 OVRPassthroughLayer 脚本 现在场景中有两个物体添加了 OVRPassthroughLayer 脚本一个是 OVRCameraRig一个是 Second Passthrough。
Second Passthrough 物体上的 OVRPassthroughLayer 就专门管理我们新增的大方块。因为我们想要在新增的大方块上添加表面投射透视所以我们要把这个 OVRPassthroughLayer 脚本的 Projection Surface 改为 User Defined。Placement 参数的话按自己的需求设置我这里为了方便演示把它设为 Overlay并且把 OVRCameraRig 中的 OVRPassthroughLayer 也设为了 Overlay这样透视图层位于虚拟图层之上我们能直观地看到两个透视图层。
OVRPassthroughLayer 上的 Composition Depth 参数
Composition Depth 表示图层的深度数值越小越后渲染也就是渲染在越前面。 Composition Depth 一般用于多个透视图层上比如有一个深度为 0 的物体和一个深度为 -1 的物体会先渲染深度为 0 的物体再渲染深度为 -1 的物体也就是深度为 -1 的物体会被渲染在深度为 0 的物体前面。当这个物体放在一起时深度为 -1 的物体会遮挡深度为 0 的物体。
根据摆放在场景中的两个白色大方块的前后关系我们希望摆放在前面的大方块后渲染也就是视野向前看的时候横着的大方块能够遮挡住竖着的大方块的下半部分如下图所示 原来的 OVRCameraRig 物体上的 OVRPassthroughLayer 管理着竖着的大方块因为这个方块上的 PassthroughUserDefine 脚本引用了 OVRCameraRig 上的 OVRPassthroughLayer然后调用了 这个 OVRPassthroughLayer 类的 AddSurfaceGeometry 方法才能给竖着的大方块添加表面投射透视。 类似的我们也要给横着的大方块添加 PassthroughUserDefine 脚本然后引用 Second Passtrhough 物体上的 OVRPassthroughLayer 脚本如下图所示 最后就是处于两个 OVRPassthroughLayer 的 Composition Depth。既然原先 OVRCameraRig 物体上的 Composition Depth 为 0为了让横着的大方块能够遮挡竖着的大方块我们要让 Second Passthrough 物体上的 Composition Depth 小于 OVRCameraRig 物体上的 Composition Depth。因此我将 Second Passthrough 物体上的 Composition Depth 设为 -1。 现在我们可以运行程序看看效果 可以看到横着的大方块把竖着的大方块的下面一部分给遮挡了这就是 Composition Depth 在多个透视图层中的作用。
如果你让 Second Passthrough 物体上的 Composition Depth 大于 OVRCameraRig 物体上的 Composition Depth你仍然能够看到竖着的大方块的下半部分因为这个时候竖着的大方块会渲染在横着的大方块的前面。