网站开发汇报ppt模板,设计公司品牌策划,光明新区城市建设局网站,怎么查看网站的pv uv一、深度API 本小节内容摘自ARCore官方文档。 ARCore 深度API
Depth API 可助力实现对象遮挡、提升沉浸感和新颖的互动体验#xff0c;从而增强 AR 体验的真实感。
在下图中#xff0c;右侧画面是采用深度API进行遮挡后的效果#xff0c;与左侧图相比更加真实。 深度值
给…一、深度API 本小节内容摘自ARCore官方文档。 ARCore 深度API
Depth API 可助力实现对象遮挡、提升沉浸感和新颖的互动体验从而增强 AR 体验的真实感。
在下图中右侧画面是采用深度API进行遮挡后的效果与左侧图相比更加真实。 深度值
给定实测几何图形上的点 A 和代表深度图像中同一点的 2D 点 aDepth API 在 a 处给出的值等于投影到主轴上的 CA 的长度。这也可称为 A 相对于相机原点 C 的 z 坐标。使用 Depth API 时请务必注意深度值不是光线 CA 本身的长度而是光线的投影。 应用场景
启用遮挡 遮挡即准确渲染虚拟物体在现实物体后面对于沉浸式 AR 体验至关重要。假设有一个虚拟 Andy用户可能需要放置在包含门边有后备箱的场景中。渲染时没有遮挡Andy 会不切实际地与树干边缘重叠。如果您使用场景的深度来了解虚拟 Andy 相对于木箱等周围环境的距离就可以准确地渲染 Andy 的遮挡效果使其在周围环境中看起来更逼真。 改变场景 您可以渲染虚拟雪花让其坐在沙发的扶手和枕头上或者在雾气弥漫的客厅中飘散让用户进入身临其境的新世界。您可以使用“深度”创建虚拟光线互动、隐藏后方以及重新照亮真实物体的场景。 距离和景深 需要显示距离较远的物体您可以通过 Depth API 使用距离测量并添加景深效果例如对场景的背景或前景进行模糊处理。 支持用户与 AR 对象互动 让虚拟内容通过碰撞和物理与现实世界互动让用户能够通过您的应用“触摸”世界。让虚拟物体绕过现实世界的障碍物或让虚拟彩弹击中并泼洒到真实的树上。将基于深度的碰撞与游戏物理学相结合可以打造栩栩如生的体验。 改进点击测试 深度可用于改进点击测试结果。平面点击测试仅适用于具有纹理的平面表面而深度点击测试则更加详细甚至适用于非平面和低纹理区域。这是因为深度命中测试使用来自场景的深度信息来确定点的正确深度和方向。
在以下示例中绿色 Andys 代表标准平面命中测试红色 Andys 代表深度命中测试。 二、 AR Foundation 本小节记录如何在Unity中开发通过 AR Foundation 使用“深度”功能。 配置安卓权限 这里需要配置安卓清单以下方式二选一。 自定义AndroidManifest
在清单中添加users-feature其值设为“com.google.ar.core.depth配置Unity 项目
导航到 Edit Project Settings XR Plug-in Management ARCore。 Depth 默认设置为 Required。修改为optional
启用深度
为节省资源ARCore 默认情况下不会启用 Depth API。如需在支持的设备上充分利用深度您必须通过 Camera 和 ARCameraBackground 组件手动将 AROcclusionManager 组件添加到 AR 相机游戏对象。如需了解详情请参阅 Unity 文档中的自动遮盖。
在新的AR Session中检查用户的设备是否支持深度示例如下
// Reference to AROcclusionManager that should be added to the AR Camera
// game object that contains the Camera and ARCameraBackground components.
var occlusionManager …// Check whether the users device supports the Depth API.
if (occlusionManager.descriptor?.supportsEnvironmentDepthImage)
{// If depth mode is available on the users device, perform// the steps you want here.
}获取深度图像
从AROcclusionManager中获取环境的深度图
// Reference to AROcclusionManager that should be added to the AR Camera
// game object that contains the Camera and ARCameraBackground components.
var occlusionManager …if (occlusionManager.TryAcquireEnvironmentDepthCpuImage(out XRCpuImage image))
{using (image){// Use the texture.}
}
提取深度图的距离
如需将 Depth API 用于遮蔽虚拟对象或直观呈现深度数据之外的用途请从深度图像中提取信息。
Texture2D _depthTexture;
short[] _depthArray;void UpdateEnvironmentDepthImage()
{if (_occlusionManager _occlusionManager.TryAcquireEnvironmentDepthCpuImage(out XRCpuImage image)){using (image){UpdateRawImage(ref _depthTexture, image, TextureFormat.R16);_depthWidth image.width;_depthHeight image.height;}}var byteBuffer _depthTexture.GetRawTextureData();Buffer.BlockCopy(byteBuffer, 0, _depthArray, 0, byteBuffer.Length);
}// Obtain the depth value in meters at a normalized screen point.
public static float GetDepthFromUV(Vector2 uv, short[] depthArray)
{int depthX (int)(uv.x * (DepthWidth - 1));int depthY (int)(uv.y * (DepthHeight - 1));return GetDepthFromXY(depthX, depthY, depthArray);
}// Obtain the depth value in meters at the specified x, y location.
public static float GetDepthFromXY(int x, int y, short[] depthArray)
{if (!Initialized){return InvalidDepthValue;}if (x DepthWidth || x 0 || y DepthHeight || y 0){return InvalidDepthValue;}var depthIndex (y * DepthWidth) x;var depthInShort depthArray[depthIndex];var depthInMeters depthInShort * MillimeterToMeter;return depthInMeters;
}三、示例Demo 这里记录当前ARFoundation关于深度API使用点云的示例Demo。不同的是这里新增的“点云采集”和“点云导入”功能。 官方示例arcore-depth-lab
版本信息 com.unity.xr.arfoundation: 4.1.5,com.unity.xr.arcore: 4.1.5,com.unity.xr.arkit: 4.1.5相机配置
在“AR Session Origin”-“AR Camera中添加AROcclusion Manager组件” 此外在示例demo中这里挂载了DepthSource脚本。这个脚本一个场景只可有且仅有一个激活 这个脚本主要作用是处理深度图纹理。
点云采集
示例场景
Demo场景路径Assests/ARRealismDemos/PointCloud/Scenes/RawPointClouds.unity
点云渲染
场景中找到“RawPointCloudBlender”游戏对象其挂载的组件如下图 PointCloudMaterial是ARCore示例提供的渲染点云的材质(这个后续会用到)。
“RawPointCloudBlender”是渲染点云的核心脚本它会在MeshFilter上生成Mesh。
点云保存
在运行时点云实时渲染的Mesh在“RawPointCloudBlender”-MeshFilter上。
因此这里可直接获取Mesh的顶点数据进行保存。
保存为PTS public void SaveMeshToFile(string filePath){if (meshFilter null || meshFilter.sharedMesh null){Debug.LogWarning(MeshFilter or Mesh not assigned.);return;}Mesh mesh meshFilter.sharedMesh;// 获取网格数据Vector3[] vertices mesh.vertices;//int[] triangles mesh.triangles;//点云无需三角顶点索引Color[] colors mesh.colors;int minCount Math.Min(vertices.Length, colors.Length);// 创建保存网格数据的文件using (StreamWriter writer new StreamWriter(filePath)){// 写入顶点数据for (int i 0; i minCount; i){//PTS格式前三个是 xyz 坐标 其中第四个是“强度”值最后三个是“颜色值”RGB Vector3 vertex vertices[i];Color c colors[i];//这里暂用ALPHA表示强度值writer.WriteLine(vertex.x vertex.y vertex.z (int)(c.a * 255) (int)(c.r * 255) (int)(c.g * 255) (int)(c.b * 255));}}}保存为OBJ
将上述循环中替换为如下内容 // 创建保存网格数据的文件using (StreamWriter writer new StreamWriter(filePath)){// 写入顶点数据foreach (Vector3 vertex in vertices){writer.WriteLine(v vertex.x vertex.y vertex.z);}//...}点云加载
扩展编辑器
编写脚本新增点云数据导入功能
public class PTSLoaderEditor : EditorWindow
{private string ptsFilePath;private Material material;[MenuItem(EQ/点云数据/\加载 *.pts\)]public static void ShowWindow(){EditorWindow.GetWindow(typeof(PTSLoaderEditor));}private void OnGUI(){//...LoadPointCloud(string filePath);//...}private void LoadPointCloud(string filePath){//...// 创建点云 MeshMesh pointCloudMesh new Mesh();for (int i 0; i count; i){string[] parts lines[i].Split( );if (parts.Length 7){float x float.Parse(parts[0]);float y float.Parse(parts[1]);float z float.Parse(parts[2]);_vertices[i] new Vector3(x, y, z);byte a byte.Parse(parts[3]);byte r byte.Parse(parts[4]);byte g byte.Parse(parts[5]);byte b byte.Parse(parts[6]);_colors[i] new Color32(r, g, b, a);_indices[i] i;}}#if UNITY_2019_3_OR_NEWERpointCloudMesh.SetVertices(_vertices, 0, count);pointCloudMesh.SetIndices(_indices, 0, count, MeshTopology.Points, 0);pointCloudMesh.SetColors(_colors, 0, count);
#else// Note that we recommend using Unity 2019.3 or above to compile this scene.ListVector3 vertexList new ListVector3();ListColor32 colorList new ListColor32();Listint indexList new Listint();for (int i 0; i count; i){vertexList.Add(_vertices[i]);indexList.Add(_indices[i]);colorList.Add(_colors[i]);}pointCloudMesh.SetVertices(vertexList);pointCloudMesh.SetIndices(indexList.ToArray(), MeshTopology.Points, 0);pointCloudMesh.SetColors(colorList);
#endif // UNITY_2019_3_OR_NEWER//...}
} 导入点云
在编辑器中操作如下
“EQ/点云数据/“加载 *.pts”” 查看点云 注这里使用点云材质可以给点赋予之前传入的颜色值