Pupil Labs Neon Integration for SightLab
This guide covers connecting and configuring the Pupil Labs Neon eye tracker with SightLab/Vizard.

Quick Start
Add Quest 3 eye tracking to your SightLab Experiments with Neon
- See instructions here https://docs.pupil-labs.com/neon/neon-xr/
- pip install pupil-labs-realtime-api (in Vizard - Tools- Package Manager - CMD)
- May need to also run this after pupil-labs-realtime-api: install --upgrade protobuf==3.20.3
- Make sure the Neon Device mount is attached to your Quest 3 according to instructions
- Download the Companion App for Neon
- Plug the USB-C cable from the Neon mount to your smartphone
- Start the Companion App on your phone
- Ensure both devices are on the same network
- Find your device IP in the Companion app (Settings → Device Info)
- Run your SightLab experiment using the
Pupil Labs Neon Quest 3config
Connection Settings
Edit these in vizconnect_quest_3_pupil_labs.py → postInit():
pupil = PupilLabsEyeTracker(
device_address="10.24.0.22", # Your phone device's IP address
device_port="8080", # Default port (usually unchanged)
verbose=True # Print connection status
)
| Parameter | Description |
|---|---|
device_address |
IP address from Companion app. Set to None for auto-discovery |
device_port |
Usually "8080" (default) |
verbose |
Print discovery/connection messages |
Calibration & Accuracy
Adjust if the gaze point is consistently offset from where you're looking:
pupil.pitch_offset = 0.0 # Vertical adjustment (degrees)
pupil.yaw_offset = 0.0 # Horizontal adjustment (degrees)
| Problem | Solution |
|---|---|
| Gaze too high | Increase pitch_offset (e.g., 2.0) |
| Gaze too low | Decrease pitch_offset (e.g., -2.0) |
| Gaze too left | Increase yaw_offset (e.g., 2.0) |
| Gaze too right | Decrease yaw_offset (e.g., -2.0) |
Smoothing
Controls the trade-off between responsiveness and jitter:
pupil.smooth_alpha_dir = 0.4 # Direction smoothing
pupil.smooth_alpha_pos = 0.4 # Position smoothing
| Value | Effect |
|---|---|
0.1 - 0.2 |
Very smooth, noticeable lag (best for heatmaps) |
0.3 - 0.4 |
Balanced (recommended) |
0.5 - 0.7 |
Responsive, some jitter |
1.0 |
No smoothing (raw data) |
Mount Calibration
The Neon scene camera is tilted 12° downward. This is compensated automatically:
mount_rotation=(-12.0, 0.0, 0.0) # (pitch, yaw, roll) in degrees
Only adjust if using a non-standard mount.
Debugging
Enable debug output to verify data is flowing:
pupil.debug = True # Print gaze data every second
Console output will show:
[PupilLabs Tick #60]
Matrix Euler: yaw=5.23°, pitch=-3.12°, roll=0.00°
Raw Left Axis: (0.091, -0.054, 0.994)
Raw Right Axis: (0.088, -0.051, 0.995)
Set to False for production use.
Troubleshooting
| Issue | Solution |
|---|---|
| "No device found" | Check IP address, ensure Companion app is running |
| Gaze not moving | Verify pupil.debug = True shows changing values |
| Very laggy | Increase smooth_alpha_dir to 0.5+ |
| Too jittery | Decrease smooth_alpha_dir to 0.2 |
| Connection drops | Check WiFi stability, try phone hotspot |
Files in Sightlab_Utils
| File | Purpose |
|---|---|
pupil_labs_sightlab_converter.py |
Main converter class |
vizconnect_quest_3_pupil_labs.py |
VizConnect configuration |