AR Plane Manager(平面追踪对象管理器)

简介: 平面管理器是一种可跟踪的管理器。平面管理器为环境中每个检测到的平面创建游戏对象。平面是由位姿、尺寸和边界点表示的平面。边界点是凸的(每个检测出来的边界角都是大于90°)。环境中可以被检测为平面的特征示例包括水平桌子、地板、工作台面和垂直墙壁。




负责管理平面以及管理检测出的这些平面,但不负责渲染平面,由其Plane Prefab属性指定的预制体负责

两个属性组件:

  1. Plane Prefab:平面预制体,不赋值的会自动实例化一个空对象
  2. Detection Mode:设置平面检测方式,如水平平面(Horizontal),垂直平面(Vertical),水平和垂直平面(Everything),不检测平面(Nothing)

可视化平面

要可视化平面,您需要创建一个 Prefab 或 GameObject,其中包含一个订阅 ARPlane 的 boundaryChanged 事件的组件。 ARFoundation 提供了一个 ARPlaneMeshVisualizer。该组件从边界顶点生成网格并将其分配给 MeshCollider、MeshFilter 和 LineRenderer(如果存在)。

要创建一个新的 GameObject,然后您可以使用它来创建您的 Prefab,请在您的 Scene 视图中单击鼠标右键,然后从出现的上下文菜单中选择 GameObject > XR > AR Default Plane

新建一个AR Default Plane对象作为预制体(默认平面预制体)

其中各属性的说明:

AR Plane:负责各类属性事宜,如是否在移除平面时销毁此实例化对象

AR Plane Mesh Visualizer:主要从边界特征点和其他特征点三角化生成一个平面网格

Mesh Renderer:使用Mesh Renderer采用合适材质渲染平面

Line Renderer:负责渲染平面可视化后的边界连线

演示视频:默认浅黄色的平面,黑色的边界线

https://www.bilibili.com/video/BV1pZ4y1f7Ru?spm_id_from=333.999.0.0

创建 AR Default Plane 后,将其分配给 ARPlaneManager 的 Plane Prefab 字段。您可以直接使用它,也可以通过将AR Default Plane 拖到 Assets 文件夹中来创建 Prefab。默认平面如下所示:

个性化渲染平面

我下载的是官方的demo

  1. 首先将AR Default Plane对象下的Line Renderer组件移除
  2. 编写一个c#脚本ARFeatheredPlaneMeshVisualizer,并将其作为组件添加到AR Default Plane对象上

usingSystem.Collections.Generic;

usingUnityEngine;

usingUnityEngine.XR.ARFoundation;

 

/// <summary>

/// This plane visualizer demonstrates the use of a feathering effect

/// at the edge of the detected plane, which reduces the visual impression

/// of a hard edge.

/// </summary>

[RequireComponent(typeof(ARPlaneMeshVisualizer), typeof(MeshRenderer), typeof(ARPlane))]

publicclassARFeatheredPlaneMeshVisualizer : MonoBehaviour

{

   [Tooltip("The width of the texture feathering (in world units).")]

   [SerializeField]

   floatm_FeatheringWidth=0.2f;

 

   /// <summary>

   /// The width of the texture feathering (in world units).

   /// </summary>

   publicfloatfeatheringWidth

   {

       get { returnm_FeatheringWidth; }

       set { m_FeatheringWidth=value; }

   }

 

   voidAwake()

   {

       m_PlaneMeshVisualizer=GetComponent<ARPlaneMeshVisualizer>();

       m_FeatheredPlaneMaterial=GetComponent<MeshRenderer>().material;

       m_Plane=GetComponent<ARPlane>();

   }

 

   voidOnEnable()

   {

       m_Plane.boundaryChanged+=ARPlane_boundaryUpdated;

   }

 

   voidOnDisable()

   {

       m_Plane.boundaryChanged-=ARPlane_boundaryUpdated;

   }

 

   voidARPlane_boundaryUpdated(ARPlaneBoundaryChangedEventArgseventArgs)

   {

       GenerateBoundaryUVs(m_PlaneMeshVisualizer.mesh);

   }

 

   /// <summary>

   /// Generate UV2s to mark the boundary vertices and feathering UV coords.

   /// </summary>

   /// <remarks>

   /// The <c>ARPlaneMeshVisualizer</c> has a <c>meshUpdated</c> event that can be used to modify the generated

   /// mesh. In this case we'll add UV2s to mark the boundary vertices.

   /// This technique avoids having to generate extra vertices for the boundary. It works best when the plane is

   /// is fairly uniform.

   /// </remarks>

   /// <param name="mesh">The <c>Mesh</c> generated by <c>ARPlaneMeshVisualizer</c></param>

   voidGenerateBoundaryUVs(Meshmesh)

   {

       intvertexCount=mesh.vertexCount;

 

       // Reuse the list of UVs

       s_FeatheringUVs.Clear();

       if (s_FeatheringUVs.Capacity<vertexCount) { s_FeatheringUVs.Capacity=vertexCount; }

 

       mesh.GetVertices(s_Vertices);

 

       Vector3centerInPlaneSpace=s_Vertices[s_Vertices.Count-1];

       Vector3uv=newVector3(0, 0, 0);

       floatshortestUVMapping=float.MaxValue;

 

       // Assume the last vertex is the center vertex.

       for (inti=0; i<vertexCount-1; i++)

       {

           floatvertexDist=Vector3.Distance(s_Vertices[i], centerInPlaneSpace);

 

           // Remap the UV so that a UV of "1" marks the feathering boudary.

           // The ratio of featherBoundaryDistance/edgeDistance is the same as featherUV/edgeUV.

           // Rearrange to get the edge UV.

           floatuvMapping=vertexDist/Mathf.Max(vertexDist-featheringWidth, 0.001f);

           uv.x=uvMapping;

 

           // All the UV mappings will be different. In the shader we need to know the UV value we need to fade out by.

           // Choose the shortest UV to guarentee we fade out before the border.

           // This means the feathering widths will be slightly different, we again rely on a fairly uniform plane.

           if (shortestUVMapping>uvMapping) { shortestUVMapping=uvMapping; }

 

           s_FeatheringUVs.Add(uv);

       }

 

       m_FeatheredPlaneMaterial.SetFloat("_ShortestUVMapping", shortestUVMapping);

 

       // Add the center vertex UV

       uv.Set(0, 0, 0);

       s_FeatheringUVs.Add(uv);

 

       mesh.SetUVs(1, s_FeatheringUVs);

       mesh.UploadMeshData(false);

   }

 

   staticList<Vector3>s_FeatheringUVs=newList<Vector3>();

 

   staticList<Vector3>s_Vertices=newList<Vector3>();

 

   ARPlaneMeshVisualizerm_PlaneMeshVisualizer;

 

   ARPlanem_Plane;

 

   Materialm_FeatheredPlaneMaterial;

}

 

  1. 在project窗口的Assets下新建一个文件夹Shaders,在其中右键-》create-》shader-》Unlit Shader创建一个shader文件,并命名为FeatheredPlaneShader

Shader"Unlit/FeatheredPlaneShader"

{

   Properties

   {

       _MainTex("Texture", 2D) ="white" {}

       _TexTintColor("Texture Tint Color", Color) = (1,1,1,1)

       _PlaneColor("Plane Color", Color) = (1,1,1,1)

   }

       SubShader

       {

           Tags { "RenderType"="Transparent""Queue"="Transparent" }

           LOD100

           BlendSrcAlphaOneMinusSrcAlpha

           ZWriteOff

 

           Pass

           {

               CGPROGRAM

               #pragma vertex vert

               #pragma fragment frag

 

               #include "UnityCG.cginc"

 

               structappdata

               {

                   float4vertex : POSITION;

                   float2uv : TEXCOORD0;

                   float3uv2 : TEXCOORD1;

 

                   UNITY_VERTEX_INPUT_INSTANCE_ID

               };

 

               structv2f

               {

                   float4vertex : SV_POSITION;

                   float2uv : TEXCOORD0;

                   float3uv2 : TEXCOORD1;

 

                   UNITY_VERTEX_OUTPUT_STEREO

               };

 

               sampler2D_MainTex;

               float4_MainTex_ST;

               fixed4_TexTintColor;

               fixed4_PlaneColor;

               float_ShortestUVMapping;

 

               v2fvert(appdatav)

               {

                   v2fo;

 

                   UNITY_SETUP_INSTANCE_ID(v);

                   UNITY_INITIALIZE_OUTPUT(v2f, o);

                   UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

 

                   o.vertex=UnityObjectToClipPos(v.vertex);

                   o.uv=TRANSFORM_TEX(v.uv, _MainTex);

                   o.uv2=v.uv2;

                   returno;

               }

 

               fixed4frag(v2fi) : SV_Target

               {

                   UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);

 

                   fixed4col=tex2D(_MainTex, i.uv) *_TexTintColor;

                   col=lerp(_PlaneColor, col, col.a);

                   // Fade out from as we pass the edge.

                   // uv2.x stores a mapped UV that will be "1" at the beginning of the feathering.

                   // We fade until we reach at the edge of the shortest UV mapping.

                   // This is the remmaped UV value at the vertex.

                   // We choose the shorted one so that ll edges will fade out completely.

                   // See ARFeatheredPlaneMeshVisualizer.cs for more details.

                   col.a*=1-smoothstep(1, _ShortestUVMapping, i.uv2.x);

                   returncol;

               }

               ENDCG

           }

       }

}

 

  1. 然后在Materials文件下创建一个新的材质,右键-》create-》material,并命名为Plane Mat,其下有一属性Shader,在其中搜索刚写好的shader脚本代码,添加进来

  2. 在project窗口的Assets下新建一个文件夹Textures,将一个png格式的渲染图片拖到此文件夹下,自动生成一个同名的(Texture 2D)文件

  3. 选中Plant Mat,在Inspector窗口下,有一个Texture属性,选择我们刚拖进来的png图片,其中Texture Tint Color为纹理显示的颜色,Plane Color为平面的颜色,再将这个材质拖动添加到AR Default Plane对象上去,


  4. 至此个性化渲染平面已经制作完成,总结一下:不同于默认的黄色平面,黑色边界线,自定义的平面效果可以设置Shader脚本渲染Texture图片纹理属性,并将Texture图片设置在一个新材质material上,material可以设置纹理颜色和平面背景颜色(一般是透明),最终在Android手机上跑一下效果:https://www.bilibili.com/video/BV16P4y1j7Po?spm_id_from=333.999.0.0
相关文章
|
定位技术 vr&ar
哈迷福利!这个小哥租下一座城堡,用AR和GPS做了张“活点地图”,实时追踪入侵者
哈迷福利!这个小哥租下一座城堡,用AR和GPS做了张“活点地图”,实时追踪入侵者
135 0
|
7月前
|
设计模式 测试技术 vr&ar
提升你的Android开发技能:从AR/VR沉浸到UI设计和故障排除(三)
提升你的Android开发技能:从AR/VR沉浸到UI设计和故障排除
|
7月前
|
人工智能 机器人 区块链
提升你的Android开发技能:从AR/VR沉浸到UI设计和故障排除(二)
提升你的Android开发技能:从AR/VR沉浸到UI设计和故障排除
|
16小时前
|
定位技术 vr&ar Android开发
AR与VR在安卓开发中的应用案例
【4月更文挑战第14天】AR和VR技术在安卓开发中日益普及,改变生活和工作方式。AR应用于导航、教育、零售,如AR导航、解剖学教学工具和虚拟家居预览。VR则创造虚拟环境,用于游戏、旅游和健身,如VR游戏“Beat Saber”、虚拟旅游和VR健身应用。这些技术在医疗、房地产等领域也展现潜力,未来将有更多创新应用出现,开发者应关注并探索其可能性。
|
17小时前
|
数据可视化 安全 vr&ar
VR vs AR到底谁更有潜力改变未来?
VR vs AR到底谁更有潜力改变未来?
31 0
|
17小时前
|
人工智能 物联网 vr&ar
AR与VR技术的融合:开启全新的现实体验
在当今快速发展的科技领域中,混合现实(AR)和增强现实(VR)技术成为引人注目的热门话题。本文将探讨AR与VR技术的融合应用,以及它们给我们带来的全新现实体验。通过结合虚拟和真实世界的元素,AR与VR技术正逐渐改变着我们对于交互、娱乐、教育和工作的理解。
|
17小时前
|
vr&ar 开发者 Python
探索未来的现实世界:混合现实(AR)与增强现实(VR)技术的应用Python异步编程:解放性能的重要利器——异步IO库深入解析
在当今科技飞速发展的时代,混合现实(AR)和增强现实(VR)技术正迅速改变着我们对现实世界的认知和体验。本文将介绍这两种技术的基本原理以及它们在不同领域的广泛应用,包括教育、医疗、旅游、娱乐等。混合现实和增强现实技术为我们带来了全新的沉浸式体验,将人与数字世界融合在一起,为未来的现实世界带来无限可能。 在当今信息爆炸的时代,高效的编程方式成为开发者追求的目标。Python异步编程与其强大的异步IO库(例如asyncio)成为了解放性能的重要利器。本文将深入解析Python异步编程以及异步IO库的原理和使用方法,帮助读者进一步掌握这一技术,提升开发效率。
|
17小时前
|
编解码 数据可视化 vr&ar
干货! 2023 VR/AR行业全貌深度剖析!
干货! 2023 VR/AR行业全貌深度剖析!

热门文章

最新文章