WebXR Precision Issues with Large Coordinates
You're encountering a common issue when working with WebXR and large global coordinates. The WebXR API internally uses 32-bit floating-point precision, which has limited precision for very large values like the GPS/global coordinates you're using.
Suggested Workarounds
- Use a local coordinate system: Instead of passing the global coordinates directly to WebXR, create a local coordinate system centered around your current position:
// Store your global origin
const globalOrigin = new Vector3(4485948.637198923, 476198.0416370128, 4497216.056600053);
// For WebXR, use relative coordinates (0,0,0 or small offsets)
const transform = new XRRigidTransform(new Vector3(0, 0, 0), quat);
const baseReferenceSpace = xr.getReferenceSpace();
const teleportSpaceOffset = baseReferenceSpace.getOffsetReferenceSpace(transform);
xr.setReferenceSpace(teleportSpaceOffset);
// Then in your render loop, apply the offset to position objects
function positionObject(globalPosition) {
const localPosition = globalPosition.clone().sub(globalOrigin);
// Use localPosition for rendering
}
- Apply coordinate transformation: Convert your global coordinates to a local system before passing to WebXR:
// Create a transformation matrix that moves the origin to your reference point
const originMatrix = new THREE.Matrix4().makeTranslation(
-4485948.637198923,
-476198.0416370128,
-4497216.056600053
);
// Apply this transformation to all your coordinates before using them with WebXR
// Then use small local offsets for the XRRigidTransform
- Use double precision in your application logic: Keep your calculations in double precision as much as possible, only converting to WebXR's float32 format at the final step.
These approaches should help eliminate the staircase effect by ensuring that the values passed to WebXR's float32 arrays are small enough to maintain precision.