Quick answer: Only treat planes as real when trackingState == TrackingState.Tracking. Use ARAnchors for long-term placements. Smooth pose between updates if jitter persists.

An AR app places a virtual object on a detected table. The object flickers between positions as the plane is refined. Sometimes disappears entirely when tracking is briefly lost.

Filter by Tracking State

void OnPlaneChanged(ARTrackablesChangedEventArgs<ARPlane> args)
{
    foreach (var plane in args.added) {
        if (plane.trackingState == TrackingState.Tracking) {
            ReadyForPlacement(plane);
        }
    }
}

Skip Limited or None planes. Tracking ones are reliable for placement.

Use ARAnchors for Long-Term

var anchor = anchorManager.AttachAnchor(plane, plane.transform.GetPose());
if (anchor) {
    var obj = Instantiate(prefab, anchor.transform);
}

Anchors are AR Foundation’s stable positions; the device’s tracking system continually refines them. Objects attached to anchors stay locked to their real-world location even as the plane representation drifts.

Smooth Pose Between Updates

Pose targetPose = plane.transform.GetPose();
void Update() {
    rendered.position = Vector3.Lerp(rendered.position, targetPose.position, Time.deltaTime * 8);
    rendered.rotation = Quaternion.Slerp(rendered.rotation, targetPose.rotation, Time.deltaTime * 8);
}

Smoothing factor 8 — tighter is jittery, looser is laggy. Used when plane updates come at lower rate than render.

Plane Visualization Threshold

Add a minimum size threshold before visualizing or treating a plane as valid:

if (plane.size.x < 0.3f || plane.size.y < 0.3f) return;   // too small, ignore

Small planes are usually noise from texture detail. Filter them; treats only credibly-tracked surfaces as actionable.

Verifying

Test on a representative surface (wooden table). Plane should appear and stay stable. Lifted in odd angles, tracking state goes Limited; your visualizer should hide. Restored: visualizer reappears smoothly.

“Tracked planes only. Anchor for placement. Smooth for visualization. AR is shaky; your filtering layer is what feels stable to users.”

For demos especially, filter aggressively — players are more forgiving of “loading” than “flicker”.