版权声明:Davidwang原创文章,严禁用于任何商业途径,授权后方可转载。
在ARFoundation中,环境反射功能可以使虚拟物体反射真实世界中的环境信息,从而更好的将虚拟场景与真实世界环境混合。
(一)使用Environment Probe
AR环境反射是一个高级功能,需要学习掌握相关知识才能运用自如。在ARFoundation使用环境反射的基本步骤如下:
1、在场景中的AR Session Origin对象上挂载AR Environment Probe Manager组件并作相应设置;
2、确保需要反射的虚拟对象带有反射材质并能反射Probe;
3、使用自动或者手动方式设置反射探头捕获环境信息供反射体使用。
按照上述步骤,首先我们在AR Session Origin对象上挂载AR Environment Probe Manager组件,我们选择手动设置反射探头,因此我们不勾选“Automatic Placement”并选择纹理过滤模式为“Trilinear”,如下图所示。
然后给需要反射的虚拟物体设置反射材质,本节中我们使用的是Unity中的Standard Shader,并设置其Mesh Renderer中的Light Probes 和Reflection Probes均为Blend Probes以使其使用反射探头生成的Cubemap,勾选上Standard Shader中Forward Rendering Options节的Specular Highlights和Reflections,如下图所示。
最后我们新建一个C#脚本AppController,并编写如下脚本。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
[RequireComponent(typeof(ARRaycastManager))]
public class AppController : MonoBehaviour
{
public GameObject spawnPrefab;
static List<ARRaycastHit> Hits;
private ARRaycastManager mRaycastManager;
private AREnvironmentProbeManager mProbeManager;
private AREnvironmentProbe mProbe;
private GameObject spawnedObject = null;
private void Awake()
{
Hits = new List<ARRaycastHit>();
mRaycastManager = GetComponent<ARRaycastManager>();
mProbeManager = GetComponent<AREnvironmentProbeManager>();
}
void Update()
{
if (Input.touchCount == 0)
return;
var touch = Input.GetTouch(0);
if (mRaycastManager.Raycast(touch.position, Hits, TrackableType.PlaneWithinPolygon | TrackableType.PlaneWithinBounds))
{
var hitPose = Hits[0].pose;
var probePose = hitPose;
probePose.position.y += 0.2f;
if (spawnedObject == null)
{
spawnedObject = Instantiate(spawnPrefab, hitPose.position+ new Vector3(0f,0.05f,0f), hitPose.rotation);
mProbe = mProbeManager.AddEnvironmentProbe(probePose, new Vector3(0.6f, 0.6f, 0.6f), new Vector3(1.0f, 1.0f, 1.0f));
}
else
{
spawnedObject.transform.position = hitPose.position;
mProbe.transform.position = hitPose.position;
}
}
}
}
在上述代码中,我们手动添加了一个反射探头,代码的其他内容稍后详细进行分析,编译运行,效果如下,左图为没有反射的虚拟物体,右图为采用了环境反射的虚拟物体,可以看到,虚拟物体反射了计算机屏幕及其他周边环境。
(二)AR Environment Probe Manager
在ARFoundation中,由AR Environment Probe Manager负责管理环境反射相关任务,AR Environment Probe Manager有三个属性,Automatic Placement、Environment Texture Filter Mode、Debug Prefab。
- Automatic Placement
ARFoundation既允许自动放置反射探头也允许手动放置反射探头,或者两者同时使用。在自动放置模式下,由应用程序设备自动选择合适的位置放置反射探头。在手动放置模式下,由开发人员在指定位置放置反射探头。自动放置由底层SDK提供算法,自主选择在何处及如何放置反射探头,以获得比较高质量的环境信息,自动放置的确定依赖于在实际环境中检测到的关键特征点信息。手动放置主要是为了获得对特定虚拟对象的最精确环境信息,绑定反射探头与虚拟对象位置可以提高反射渲染的质量,因此,手动将反射探头放置在重要的虚拟对象中或其附近会产生为该对象生成的最准确的环境信息。通常而言,自动放置可以提供对真实环境比较好的宏观环境信息,而手动放置能提供在某一个点上对周围环境更准确的环境映射从而提升反射的质量。
反射探头负责捕获环境纹理信息,每个反射探头都有一个比例(Scale)、方向(Orientation)、位置(Position)和大小(Size)。比例、方向和位置属性定义了反射探头相对于Session空间的空间信息,大小则定义了反射探头反射的范围,无限大小表示环境纹理可用于全局,而有限大小表示反射探头只能捕获其周围特定区域的环境信息。
在手动放置时,为了使放置的反射探头能更好的发挥作用,通常反射探头的放置位置与大小设置应遵循以下原则:
1、反射探头的位置应当放在需要反射的虚拟物体顶部中央,高度应该为虚拟物体高的两倍。这可以确保反射探头下部与虚拟物体下部对齐,并捕获到虚拟物体放置的平面的环境信息。
2、反射探头的长与宽应该为虚拟物体长与宽的三倍,确保反射探头能捕获到虚拟物体周边的环境信息。
3、反射探头可以朝向任何方向,但是,Unity的反射探头只支持轴对齐模式,因此,最好在放置时就设置成轴对齐。
- Environment Texture Filter Mode
环境纹理过滤模式主要可选为Point、Bilinear、Trilinear,为达到比较好的视觉效果,一般我们选择Bilinear或者Trilinear
- Debug Prefab
该属性用于在调试时可视化反射探头,在发布时应置空。
在ARFoundation中,AR Environment Probe Manager提供了如下方法管理环境反射:
方法 | 描述 |
---|---|
AddEnvironmentProbe(Pose pose, Vector3 scale, Vector3 size) | 添加一个AREnvironmentProbe,Pose指定了放置的位置与方向,Scale指定了相对于Session空间的比例,Size指定了反射探头可探测的环境范围。 |
GetEnvironmentProbe(TrackableId trackableId) | 根据TrackableId获取一个AREnvironmentProbe。 |
RemoveEnvironmentProbe(AREnvironmentProbe probe) | 移除一个AREnvironmentProbe,如果移除成功则返回True,否则返回False。 |
environmentProbesChanged | 在反射探头发生变化是触发的事件,如一个新的environment probe创建、对一个现存的environment probes进行更新、移除一个environment probes。 |
(三)性能优化
在AR中使用反射探头反射环境可以大大的增强虚拟物体的可信度,但由于AR摄像头获取的环境信息不充分,因此为更好的扬长避短,在AR中使用反射探头反射真实环境需要注意以下几点:
1、避免精确反射
如上所述,AR中从摄像头获取的信息不足以对周围环境进行精准的再现,即不能生成完全的Cubemap,因此反射体对环境的反射也不能做到非常精准,希望利用反射探头实现对真实环境的镜面反射是不现实的。通常的做法是合理的设计,既能发挥反射增强虚拟物体可信的优势,但也要同时避免对真实环境的精确反射。同时,因为在AR中不能获取到完全的Cubemap并且Cubemap更新也不实时(为降低硬件消耗),通常在小面积上可以使用高反射率而在大面积上使用低反射率,达到既营造反射效果又避免反射不准确而来带负面作用。
2、对移动对象的处理
烘焙的环境贴图不能反应环境的变化,实时的反射探头又会带来过大的性能消耗,对移动对象的反射处理需要特别进行优化。在设置反射探针时可以考虑以下方法:
如果移动物体移动路径可知或可以预测,可以提前在其经过的路径上放置多个反射探头并进行烘焙,这样移动物体可以根据距离的远近对不同的反射探头生成的Cubemap采样。
创建一个全局的环境反射,如Skybox,这样当移动物体移动出某个反射探头的范围时仍然可以反射而不是突然出现反射中断。
当移动物体移动到一个新的位置后重新创建一个反射探头并销毁原来位置的反射探头。
3、防止滥用
在AR中,生成Cubemap不仅仅是在某个点拍摄6个方向的照片做贴图,因为真实环境信息的不充分,AR需要更多时间来收集来自摄像头的图像信息,并且还要使用人工智能算法对缺少的信息进行计算补充,这是个耗时耗性能的过程。过多的使用反射探头不仅不会带来反射效果的实质性提升,相反会导致应用卡顿和电池的快速消耗。在AR中,当用户移动位置或者调整虚拟对象大小时,应用程序都会重新创建反射探头,因此我们需要限制此类更新,如更新频率不应大于每秒1次。
4、避免突然切换
突然的移除反射探头或者添加新的反射探头会让用户感到不适。在ARFoundation中使用自动放置反射探头的模式下,只要Session开始,会创建一个全局的类似Skybox的大背景以防止反射突然的切换。在手动放置时,开发者应该确保反射的自然过渡,确保虚拟物体始终能反映适合的环境,或者使用一个全局的在各种环境下都能适应的静态Cubemap作为过渡手段。
参考文献
1、Adding Realistic Reflections to an AR Experience Adding Realistic Reflections to an AR Experience
2、AR Environment Probe Manager AR Environment Probe Manager