Gaze specs
Updated: Sep 1, 2026
This page documents the technical parameters behind gaze interactions. These values set how wide the targeting cone is. They also control how the system holds a target steady while the eyes move, how it resolves competing candidates, and how it draws the hover affordance. Use them to tune and reproduce familiar gaze behavior in your app.
Gaze is a noisy input. Eyes drift and make small involuntary movements even while a user holds a steady fixation. For that reason, the system does not test a single thin line against the scene. It sweeps a narrow cone along the gaze direction. Every interactable inside that cone becomes a candidate.
| Parameter | Value | Description |
|---|
Targeting cone half-angle | 2.0 degrees | The largest angle allowed between the gaze ray and a candidate interactable |
Targeting cone aperture | About 4 degrees | The full width of the cone, or twice the half-angle |
Maximum gaze distance | Configurable, with an engine-specific default | How far along the gaze direction the system looks for candidates. Read the current default from your engine. |
The 2.0 degree half-angle is a tolerance, not a size. It sets how far off center a gaze can land and still reach a target. An element that sits alone on a surface stays reachable even when aim is loose. Cone length differs between engines. Treat the maximum distance as a value you set for your own content, not a fixed platform number.
Targeting tolerance is not target size
The targeting cone widens the area around the gaze ray that the system searches. It does not help a user see or fixate on a small control. Minimum target size is a separate rule with its own value. Both have to hold for gaze to feel reliable. For the target sizing guidance, see [Eyes best practices](/design/eyes-best-practices/). A single frame of gaze data is a poor basis for changing the target. Saccades and blinks would make the target flicker between neighbors. To prevent that, the interactor reads gaze across a short rolling window. A challenger must win most frames in that window before it takes over.
| Parameter | Value | Description |
|---|
Consensus window | 0.2 s | How much gaze history the interactor checks when it picks the target |
Handover condition | Majority of frames in the window | A challenger must win the most frames across the window before it replaces the current target |
The window is short. A deliberate look at a new control moves the target almost at once. A brief glance away does not. This is the gaze form of the hysteresis used by touch and grab. The cost of changing target is higher than the cost of keeping it.
Stabilization is not dwell-to-activate
The consensus window decides which interactable is targeted. It does not select, press, or activate anything. Holding a gaze on a control for the length of the window produces a hover state and nothing more. Activation always comes from a separate commit action such as a pinch or a button press. Several interactables can sit inside the targeting cone at once, especially on a dense panel. The system compares them in a fixed order. That order makes the result match what the user believes they are looking at.
| Parameter | Value | Description |
|---|
Resolution order | Angle first, then distance | Candidates are compared by angular offset from the gaze ray. Remaining ties are broken by distance. Unreal applies a specificity term as a third comparison. |
Equal angle threshold | 0.001 degrees | Candidates within this range count as equally well aimed at, so the comparison moves on to distance |
Tiebreaker score | 0 (default) | Set per interactable. When candidates remain tied, the higher score wins. |
Ordering by angle before distance is what makes gaze feel correct. A nearby object slightly off axis loses to a farther object the user looks straight at. The result follows the user’s intent rather than the scene layout. An equal-distance threshold also exists for the second comparison. Its default is engine-specific.
The public gaze hover affordance paints a soft radial spotlight onto the mesh at the gaze hit location. The spotlight lives in world space and follows the geometry it lands on. It bends across curved panels and stops at surface edges.
A falloff exponent packs the light near the center and leaves the outer edge diffuse. The affordance reads as a soft pool, not a hard disc with a visible edge. That softness keeps attention on the middle of the target, where gaze targeting is most reliable. Support for two pointers lets a second gaze source light up at the same time, without one replacing the other.
There is no gaze cursor or reticle
The system draws no dot, ring, or crosshair for gaze. The surface spotlight is the whole affordance. Do not design a layout that leans on a persistent pointer glyph. Do not assume a reticle exists as a fallback when a target has no surface to paint. Engine-specific parameters
Five more parameters shape the affordance. Their defaults differ between engines. Read the current value from the engine you build on rather than assuming a shared number.
| Parameter | What it controls |
|---|
State transition duration | How long the affordance takes to move between its visual states |
Dwell fade duration | How long the affordance takes to fade while gaze rests on a target |
Dwell fade value | How far the affordance fades once that fade completes |
Falloff distance | The distance over which spotlight brightness drops off |
Color alpha | The opacity of the spotlight color |
The two dwell parameters set how the affordance settles while a gaze stays on one target. They soften a static highlight that would otherwise sit at full strength in the user’s central vision. Neither one activates anything.
There is no published minimum spacing value for gaze. Spacing is governed by the targeting cone and the consensus window rather than by a fixed gap between elements.
Two controls inside the roughly 4 degree aperture become candidates in the same frame. Disambiguation then has to separate them by angle. The consensus window sets how long that contest runs before the target changes. Pack elements tightly enough and gaze error moves the winner from frame to frame. The target turns unstable, even though each comparison behaves correctly.
Spacing rules from other modalities do not carry over. Direct hand input is measured as a physical gap at the surface. Gaze is angular. The same layout separates well at one viewing distance and fails at another. For the design guidance on separating interactive elements, see
Eyes best practices.
Meta XR Interaction SDK (Unity) | |
Meta XR Interaction SDK (Unreal) | |
Meta Spatial SDK | |
More design resources on gaze
More design guidance for your app: