ARFoundation系列讲解-10平面检测二

六、更改可视化平面样式(请参考ARFoundation Samples )

1.新建一个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" }
        LOD 100
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
 
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
 
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 uv2 : TEXCOORD1;
            };
 
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 uv2 : TEXCOORD1;
            };
 
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _TexTintColor;
            fixed4 _PlaneColor;
            float _ShortestUVMapping;
 
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv2 = v.uv2;
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = 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);
                return col;
            }
            ENDCG
        }
    }
}

2.新建一个材质球,使用上面写的 FeatheredPlaneShader Shader,命名为 FeatheredPlaneMaterial 

3.将 FeatheredPlaneMaterial 材质球中的 Texture 替换成为右侧链接中下载的图片,贴图下载链接:https://pan.baidu.com/s/1TBVeZ7sN03dVj0iKt-nWPQ  密码:cb3f

4.Hierarchy->XR->AR Default Plane 创建AR Default Plane 命名为 AR Feathered Plane Fade

5.将 AR Feathered Plane Fade 身上的 Line Renderer 组件移除掉

6.将 AR Feathered Plane Fade 身上的Mesh Renderer材质球改成 FeatheredPlaneMaterial

7.将 AR Feathered Plane Fade 制作成为预制体,并且将 Hierarchy 中的AR Feathered Plane Fade删除掉

8.将ARPlaneManager->Plane Prefab 设置成  AR Feathered Plane Fade

9.新建一个脚本命名为 ARFeatheredPlaneMeshVisualizer 挂载在 AR Feathered Plane Fade 上,代码如下 

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.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))]
public class ARFeatheredPlaneMeshVisualizer : MonoBehaviour
{
    [Tooltip("The width of the texture feathering (in world units).")]
    [SerializeField]
    float m_FeatheringWidth = 0.2f;
 
    /// <summary>
    /// The width of the texture feathering (in world units).
    /// </summary>
    public float featheringWidth
    {
        get { return m_FeatheringWidth; }
        set { m_FeatheringWidth = value; }
    }
 
    void Awake()
    {
        m_PlaneMeshVisualizer = GetComponent<ARPlaneMeshVisualizer>();
        m_FeatheredPlaneMaterial = GetComponent<MeshRenderer>().material;
        m_Plane = GetComponent<ARPlane>();
    }
 
    void OnEnable()
    {
        m_Plane.boundaryChanged += ARPlane_boundaryUpdated;
    }
 
    void OnDisable()
    {
        m_Plane.boundaryChanged -= ARPlane_boundaryUpdated;
    }
 
    void ARPlane_boundaryUpdated(ARPlaneBoundaryChangedEventArgs eventArgs)
    {
        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>
    void GenerateBoundaryUVs(Mesh mesh)
    {
        int vertexCount = mesh.vertexCount;
 
        // Reuse the list of UVs
        s_FeatheringUVs.Clear();
        if (s_FeatheringUVs.Capacity < vertexCount) { s_FeatheringUVs.Capacity = vertexCount; }
 
        mesh.GetVertices(s_Vertices);
 
        Vector3 centerInPlaneSpace = s_Vertices[s_Vertices.Count - 1];
        Vector3 uv = new Vector3(0, 0, 0);
        float shortestUVMapping = float.MaxValue;
 
        // Assume the last vertex is the center vertex.
        for (int i = 0; i < vertexCount - 1; i++)
        {
            float vertexDist = 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.
            float uvMapping = 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);
    }
 
    static List<Vector3> s_FeatheringUVs = new List<Vector3>();
 
    static List<Vector3> s_Vertices = new List<Vector3>();
 
    ARPlaneMeshVisualizer m_PlaneMeshVisualizer;
 
    ARPlane m_Plane;
 
    Material m_FeatheredPlaneMaterial;
}
  

10.打包运行,大功告成!

 

七、仿ARCore可视化平面样式

1.下载替换我处理过的贴图:链接:https://pan.baidu.com/s/1Pt7ygv0zCEMiKq6J3Kti0Q  密码:vyte

2.打包运行,效果如下!

 

推荐学习资料

1.ARFoundation系列讲解-教程目录

2.Unity官方API:学习一门技术,官方教程是最权威的

3.ARFoundation Samples : ARFoundation 示例地址

欢迎对AR技术感兴趣的朋友,加入QQ群:883655607 讨论 

posted @ 2020-10-29 00:25  DaLiangChen  阅读(1179)  评论(0编辑  收藏  举报