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;
///
/// 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.
///
[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;
///
/// The width of the texture feathering (in world units).
///
public float featheringWidth
{
get { return m_FeatheringWidth; }
set { m_FeatheringWidth = value; }
}
void Awake()
{
m_PlaneMeshVisualizer = GetComponent();
m_FeatheredPlaneMaterial = GetComponent().material;
m_Plane = GetComponent();
}
void OnEnable()
{
m_Plane.boundaryChanged += ARPlane_boundaryUpdated;
}
void OnDisable()
{
m_Plane.boundaryChanged -= ARPlane_boundaryUpdated;
}
void ARPlane_boundaryUpdated(ARPlaneBoundaryChangedEventArgs eventArgs)
{
GenerateBoundaryUVs(m_PlaneMeshVisualizer.mesh);
}
///
/// Generate UV2s to mark the boundary vertices and feathering UV coords.
///
///
/// The ARPlaneMeshVisualizer has a meshUpdated 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.
///
/// The Mesh generated by ARPlaneMeshVisualizer
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 s_FeatheringUVs = new List();
static List s_Vertices = new List();
ARPlaneMeshVisualizer m_PlaneMeshVisualizer;
ARPlane m_Plane;
Material m_FeatheredPlaneMaterial;
}
10.打包运行,大功告成!
1.下载替换我处理过的贴图:链接:https://pan.baidu.com/s/1Pt7ygv0zCEMiKq6J3Kti0Q 密码:vyte
2.打包运行,效果如下!
using UnityEngine;
using UnityEngine.XR.ARFoundation;
/// AR平面显示管理器
public class ARPlaneDisplayManager : MonoBehaviour
{
private ARPlaneManager m_ARPlaneManager = null;
private Color m_DefaultPlaneColor = Color.white;
private Color m_TransparentPlaneColor = new Color(255f / 255f, 255f / 255f, 255f / 255f, 0);
private void Awake()
{
m_ARPlaneManager = FindObjectOfType();
}
public void SetAllPlanesActive(bool value)
{
if (value) m_ARPlaneManager.planePrefab.gameObject.GetComponent().material.SetColor("_TexTintColor", m_DefaultPlaneColor);
else m_ARPlaneManager.planePrefab.gameObject.GetComponent().material.SetColor("_TexTintColor", m_TransparentPlaneColor);
foreach (var plane in m_ARPlaneManager.trackables)
{
if (value) plane.gameObject.GetComponent().material.SetColor("_TexTintColor", m_DefaultPlaneColor);
else plane.gameObject.GetComponent().material.SetColor("_TexTintColor", m_TransparentPlaneColor);
}
}
}
参考资料:
官方API:https://docs.unity3d.com/Packages/[email protected]/manual/plane-manager.html
ARFoundation Samples:https://github.com/Unity-Technologies/arfoundation-samples
欢迎对AR技术感兴趣的朋友,加入QQ群:883655607 讨论