Implementing Feathered Planes for Plane Detection in AR Foundation
Tutorial
·
intermediate
·
+0XP
·
15 mins
·
(57)
Unity Technologies

In this tutorial, we’ll implement feathered planes for plane detection in AR Foundation. Feathered planes fade out at the edges, giving your Scene a more polished appearance. This is achieved via a combination of custom Shader/Material and a new AR Plane Mesh Visualizer script that builds on the one included in AR Foundation.
Languages available:
1. Implementing Feathered Planes for Plane Detection in AR Foundation
This tutorial has been verified using Unity 2019.4 LTS, AR Foundation 2.1.10 and ARCore XR Plugin 2.1.12
In this tutorial, we’ll implement feathered planes for plane detection in AR Foundation. Feathered planes fade out at the edges, giving your Scene a more polished appearance. This is achieved via a combination of custom Shader/Material and a new AR Plane Mesh Visualizer script that builds on the one included in AR Foundation.
2. Setting up the Project
1. Open the Package Manager by going to Window > Package Manager (Figure 01).

Figure 01: Opening the Package Manager
2. In the Package Manager, make sure you are in the Unity Registry section and then install AR Foundation. This will also install the AR Subsystems package (Figure 02).

Figure 02: Installing the AR Foundation package
3. Now install either the ARCore XR Plugin (for Android) or the ARKit XR Plugin (for iOS). For this tutorial, we will be using ARCore.
3. Creating the Feathered Plane Shader
1. In the Project view, right-click and select Create > Shader > Unlit Shader. Name it FeatheredPlaneShader and open it in the Script Editor (Figure 03).

Figure 03: Creating an Unlit Shader
2. Our Shader will need the ability to set a tint for the plane Texture and a color for the plane. Inside Properties, add:
3. Our Shader needs to handle transparency a bit differently than the default unlit Shader. In Subshader, set the RenderType tag to Transparent, and add a queue tag with the same value:
4. After LOD 100, add:
5. We won’t need fog, so remove these two lines inside CGPROGRAM:
6. Our Shader will use the second UV slot to hold information about where to begin feathering. Inside the struct appdata, add:
7. Inside the v2f struct definition, replace the line:
with:
8. In order to access the properties we’ve added to the Shader, including a property that will be set by the script later in this tutorial, add the following to the data members after the line float4 _MainTex_ST;:
9. Remove the following line from the vertex function (vert):
Instead, we’ll pass the extra UV containing the feathering information. In place of the removed line, add:
10. Inside our fragment function (frag), we’ll modify the first line to use the tint as well as the Texture. Change it to:
Remove:
11. We want to interpolate between the tinted Texture and the chosen plane color based on the opacity of col. Add the following line immediately after the line from the previous step:
12. Finally, we want to modulate the opacity of col using the information stored in the extra UV and the ShortestUVMapping variable, which will be covered in more detail later in this tutorial. After the line from Step 12, add:
13. Without comments, the code should look like this:
14. Save changes and return to the Unity Editor.
15. In the Project view, right-click and select Create > Material. Name it FeatheredPlaneMaterial. Set it to use our Shader by selecting Unlit/FeatheredPlaneShader from the Shader drop-down (Figure 04).

Figure 04: Custom Material and Shader for the FeatheredPlaneMeshVisualizer
4. Creating the AR Feathered Plane Mesh Visualizer Script
The Feathered Plane Mesh Visualizer builds on, but does not directly extend, the default AR Plane Mesh Visualizer. It’s attached to the Plane Prefab, which also must contain the AR Plane, AR Mesh Visualizer, and MeshRenderer components. It monitors changes in the boundary of the AR Plane, and correspondingly sets properties in the MeshRenderer's Material so that the edges of the generated AR Plane Mesh are feathered. The width of this feathering is adjustable in the Inspector.
The AR Feathered Plane Mesh Visualizer uses the following data members:
- s_FeatheringUVs: List of Vector3s that contain information about where feathering begins. This list is generated when the AR Plane boundary changes and is passed to the Material.
- m_PlaneMeshVisualizer: Stores a reference to the required ARPlaneMeshVisualizer script, which creates and controls the Plane Mesh we're feathering.
- s_Vertices: List of boundary vertices. This is populated by the ARPlaneMeshVisualizer script’s Mesh and updated when the ARPlane boundary changes.
- m_Plane: Stores a reference to the ARPlane component, which holds information about the plane we're visualizing. When the boundaries of this plane change, the boundaryChanged event is fired (outside of this script).
- m_FeatheredPlaneMaterial: This is the Material whose properties are updated by the ARFeatheredPlaneMeshVisualizer whenever the boundary changes.
- m_FeatheringWidth: This controls the width of the feathering, adjustable via the featheringWidth field.
1. Inside the Project view, right-click and select Create > C# Script. Name it ARFeatheredPlaneMeshVisualizer and open it in the Script Editor.
2. Add the AR Foundation namespace:
3. Because our script requires the ARPlaneMeshVisualizer, MeshRenderer, and ARPlane components to be on the same GameObject to which it’s attached, add the following line just before the class definition:
4. Inside the class definition, add the following data members:
5. The first thing our script needs to do is store references to the required components. Change Start to Awake, and to it add:
6. In order to know when to update visualization, we will subscribe the event handler method, ARPlane_boundaryUpdated, to the boundaryChanged event when the ARFeatheredPlaneMeshVisualizer’s GameObject is enabled. To prevent orphaned events, we unsubscribe when the GameObject is disabled. Add:
7. Next, we define ARPlane_boundaryUpdated.
8. Finally, we define GenerateBoundaryUVs, the star of the ARFeatheredPlaneMeshVisualizer show. This method retrieves the list of vertices from m_PlaneMeshVisualizer, which stores them in s_Vertices. It assumes that the last vertex is at the plane’s center. It then iterates through the vertices, setting the mapping value for a corresponding feathering UV based on the distance of the vertex from the plane’s center and the desired feathering width. With each iteration, it checks to see if this mapping value is the shortest and, if so, stores it. In either case, it stores the calculated UV mapping in s_FeatheringUVs. After looping through all vertices, it sets the shortest UV mapping property in the Material, creates and adds a feathering UV set at the center, sets the second UV channel to use s_FeatheringUVs and uploads the Mesh data.
9. Add the GenerateBoundaryUVs method:
10. Save changes and return to the Unity Editor.
11. Load or create a Scene with an AR Session and AR Session Origin, with the AR Session Origin having an attached AR Plane Manager component. Set the AR Plane Manager’s Plane Prefab to the new Prefab.
12. Create or load a Prefab based on the AR Default Plane (or one that satisfies the requirements). If you need more help with this step, please refer to the Configuring Plane Detection for AR Foundation tutorial.
13. Change the Material for the MeshRenderer to the one created earlier in this tutorial. Add the AR Feathered Plane Mesh Visualizer component and save the Prefab (Figure 05).

Figure 05: The completed AR Default Plane Prefab
14. Assign this new Prefab to the Plane Prefab variable in the AR Plane Manager script on the AR Session Origin object (Figure 06).

Figure 06: Setting the Plane Prefab in the AR Plane Manager script
15. Save the Scene and build the project. Make sure to have the ARCore XR Foundation package installed if building for Android. If you need more help with this step, please refer to the Configuring Plane Detection for AR Foundation tutorial.
16. Launch the app on your device. Move the device around to capture information about your environment. Notice how the feathered edges allow your detected planes to exist more naturally in the environment.
5. Conclusion
Feathered planes give a more professional appearance to your AR project, allowing a smoother transition between the virtual and physical worlds.