ARFeatheredPlaneMeshVisualizer.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #if AR_FOUNDATION_PRESENT
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.XR.ARFoundation;
  5. namespace UnityEngine.XR.Interaction.Toolkit.Samples.ARStarterAssets
  6. {
  7. /// <summary>
  8. /// This plane visualizer demonstrates the use of a feathering effect
  9. /// at the edge of the detected plane, which reduces the visual impression
  10. /// of a hard edge.
  11. /// </summary>
  12. [RequireComponent(typeof(ARPlaneMeshVisualizer), typeof(MeshRenderer), typeof(ARPlane))]
  13. public class ARFeatheredPlaneMeshVisualizer : MonoBehaviour
  14. {
  15. [Tooltip("The width of the texture feathering (in world units).")]
  16. [SerializeField]
  17. float m_FeatheringWidth = 0.2f;
  18. /// <summary>
  19. /// The width of the texture feathering (in world units).
  20. /// </summary>
  21. public float featheringWidth
  22. {
  23. get { return m_FeatheringWidth; }
  24. set { m_FeatheringWidth = value; }
  25. }
  26. void Awake()
  27. {
  28. m_PlaneMeshVisualizer = GetComponent<ARPlaneMeshVisualizer>();
  29. m_FeatheredPlaneMaterial = GetComponent<MeshRenderer>().material;
  30. m_Plane = GetComponent<ARPlane>();
  31. }
  32. void OnEnable()
  33. {
  34. m_Plane.boundaryChanged += ARPlane_boundaryUpdated;
  35. }
  36. void OnDisable()
  37. {
  38. m_Plane.boundaryChanged -= ARPlane_boundaryUpdated;
  39. }
  40. void ARPlane_boundaryUpdated(ARPlaneBoundaryChangedEventArgs eventArgs)
  41. {
  42. GenerateBoundaryUVs(m_PlaneMeshVisualizer.mesh);
  43. }
  44. /// <summary>
  45. /// Generate UV2s to mark the boundary vertices and feathering UV coords.
  46. /// </summary>
  47. /// <remarks>
  48. /// The <c>ARPlaneMeshVisualizer</c> has a <c>meshUpdated</c> event that can be used to modify the generated
  49. /// mesh. In this case we'll add UV2s to mark the boundary vertices.
  50. /// This technique avoids having to generate extra vertices for the boundary. It works best when the plane is
  51. /// is fairly uniform.
  52. /// </remarks>
  53. /// <param name="mesh">The <c>Mesh</c> generated by <c>ARPlaneMeshVisualizer</c></param>
  54. void GenerateBoundaryUVs(Mesh mesh)
  55. {
  56. int vertexCount = mesh.vertexCount;
  57. // Reuse the list of UVs
  58. s_FeatheringUVs.Clear();
  59. if (s_FeatheringUVs.Capacity < vertexCount) { s_FeatheringUVs.Capacity = vertexCount; }
  60. mesh.GetVertices(s_Vertices);
  61. Vector3 centerInPlaneSpace = s_Vertices[s_Vertices.Count - 1];
  62. Vector3 uv = new Vector3(0, 0, 0);
  63. float shortestUVMapping = float.MaxValue;
  64. // Assume the last vertex is the center vertex.
  65. for (int i = 0; i < vertexCount - 1; i++)
  66. {
  67. float vertexDist = Vector3.Distance(s_Vertices[i], centerInPlaneSpace);
  68. // Remap the UV so that a UV of "1" marks the feathering boudary.
  69. // The ratio of featherBoundaryDistance/edgeDistance is the same as featherUV/edgeUV.
  70. // Rearrange to get the edge UV.
  71. float uvMapping = vertexDist / Mathf.Max(vertexDist - featheringWidth, 0.001f);
  72. uv.x = uvMapping;
  73. // All the UV mappings will be different. In the shader we need to know the UV value we need to fade out by.
  74. // Choose the shortest UV to guarentee we fade out before the border.
  75. // This means the feathering widths will be slightly different, we again rely on a fairly uniform plane.
  76. if (shortestUVMapping > uvMapping) { shortestUVMapping = uvMapping; }
  77. s_FeatheringUVs.Add(uv);
  78. }
  79. m_FeatheredPlaneMaterial.SetFloat("_ShortestUVMapping", shortestUVMapping);
  80. // Add the center vertex UV
  81. uv.Set(0, 0, 0);
  82. s_FeatheringUVs.Add(uv);
  83. mesh.SetUVs(1, s_FeatheringUVs);
  84. mesh.UploadMeshData(false);
  85. }
  86. static List<Vector3> s_FeatheringUVs = new List<Vector3>();
  87. static List<Vector3> s_Vertices = new List<Vector3>();
  88. ARPlaneMeshVisualizer m_PlaneMeshVisualizer;
  89. ARPlane m_Plane;
  90. Material m_FeatheredPlaneMaterial;
  91. }
  92. }
  93. #endif