Skip to content

Releases: ReactVision/viro

v2.53.1

12 Mar 00:34

Choose a tag to compare

Hotfix: In MALI GPU devices, the camera texture may get frozen while switching AR scenes.

v2.53.0

11 Mar 00:34

Choose a tag to compare

@reactvision/react-viro v2.53.0 — Release Notes

⚠️ Breaking Changes

ViroARSceneNavigatorprovider replaces cloudAnchorProvider and geospatialAnchorProvider

The two separate props are merged into a single provider prop that controls both backends simultaneously. provider defaults to "reactvision" so the prop can be omitted entirely in most cases.

Before:

<ViroARSceneNavigator
  cloudAnchorProvider="reactvision"
  geospatialAnchorProvider="reactvision"
  initialScene={{ scene: MyARScene }}
/>

After:

// defaults to "reactvision" — prop can be omitted
<ViroARSceneNavigator initialScene={{ scene: MyARScene }} />

// Or to override:
<ViroARSceneNavigator provider="arcore" initialScene={{ scene: MyARScene }} />

ViroCloudAnchorProvider and ViroGeospatialAnchorProvider are now deprecated aliases for the new ViroProvider type. They still compile with a deprecation warning.

Expo plugin (withViro) — provider replaces cloudAnchorProvider and geospatialAnchorProvider

Before:

["@reactvision/react-viro", {
  "cloudAnchorProvider": "reactvision",
  "geospatialAnchorProvider": "reactvision",
  "rvApiKey": "...",
  "rvProjectId": "..."
}]

After:

["@reactvision/react-viro", {
  "provider": "reactvision",
  "rvApiKey": "...",
  "rvProjectId": "..."
}]

ViroARPlaneSelector requires manual anchor wiring

The component no longer self-discovers planes. You must now forward ViroARScene anchor events to it via a ref:

const selectorRef = useRef<ViroARPlaneSelector>(null);

<ViroARScene
  anchorDetectionTypes={["PlanesHorizontal", "PlanesVertical"]}
  onAnchorFound={(a)   => selectorRef.current?.handleAnchorFound(a)}
  onAnchorUpdated={(a) => selectorRef.current?.handleAnchorUpdated(a)}
  onAnchorRemoved={(a) => a && selectorRef.current?.handleAnchorRemoved(a)}
>
  <ViroARPlaneSelector ref={selectorRef} alignment="Both" onPlaneSelected={...}>
    <MyContent />
  </ViroARPlaneSelector>
</ViroARScene>

What's new

ReactVision Cloud Anchors (RVCA)

Place persistent AR content that other users can find — no Google Cloud account required. RVCA is a proprietary closed-source SDK; its implementation is not part of the open-source ViroCore or react-viro distribution.

The "reactvision" provider routes hostCloudAnchor / resolveCloudAnchor through the ReactVision platform. The existing hostCloudAnchor, resolveCloudAnchor, and onCloudAnchorStateChange API is unchanged.

  • Hosting: scan your environment briefly, then call hostCloudAnchor. Returns an error immediately if the environment has not been sufficiently observed — no silent fallback.
  • Resolving: the SDK matches the live camera feed against stored anchor data and returns a pose once a confident localisation is established. Cross-platform (iOS host → Android resolve and vice versa) is fully supported.
  • TTL: hostCloudAnchor accepts a ttlDays parameter (1–365) to control anchor expiry on the backend.
  • GPS tagging: set the device location before hosting to embed GPS coordinates as anchor metadata. Enables proximity search via rvFindNearbyCloudAnchors.

8 new methods on arSceneNavigator for full CRUD and analytics on cloud anchors:

Method Description
rvGetCloudAnchor(anchorId) Fetch a single anchor record
rvListCloudAnchors(limit, offset) Paginated list of all project anchors
rvUpdateCloudAnchor(id, name, desc, isPublic) Rename / re-describe an anchor
rvDeleteCloudAnchor(anchorId) Permanently delete an anchor and its assets
rvFindNearbyCloudAnchors(lat, lng, radius, limit) GPS proximity search
rvAttachAssetToCloudAnchor(id, url, size, name, type, userId) Attach a hosted file
rvRemoveAssetFromCloudAnchor(anchorId, assetId) Remove an attached asset
rvTrackCloudAnchorResolution(...) Record resolve analytics manually

ReactVision Geospatial Anchor Management

5 new management methods for GPS-tagged anchors (backed by the proprietary RVCA SDK):

Method Description
rvListGeospatialAnchors(limit, offset) Paginated list
rvGetGeospatialAnchor(anchorId) Fetch a single geospatial anchor
rvFindNearbyGeospatialAnchors(lat, lng, radius, limit) GPS proximity search
rvUpdateGeospatialAnchor(id, sceneAssetId, sceneId, name) Update metadata
rvDeleteGeospatialAnchor(anchorId) Permanently delete

createGeospatialAnchor, createTerrainAnchor, and createRooftopAnchor are now supported with provider="reactvision". No VPS, no ARCore Geospatial API, and no ARCore pods are required.

Asset upload:

rvUploadAsset(assetType, filename, data, appUserId) — uploads a file to ReactVision storage and returns a URL and asset ID. Supported assetType values: "3d-model", "image", "video", "audio". The returned asset ID can be linked to a geospatial anchor via rvUpdateGeospatialAnchor or to a cloud anchor via rvAttachAssetToCloudAnchor.

New geospatial utilities

  • gpsToArWorld(devicePose, lat, lng, alt) — converts a GPS coordinate to an AR world-space [x, y, z] offset from the device's current geospatial pose.
  • latLngToMercator(lat, lng) — converts a GPS coordinate to a metric 2D position. Building block for gpsToArWorld and custom geo math.

Both are exported from @reactvision/react-viro.

New ViroProvider type

Canonical union type "none" | "arcore" | "reactvision" exported from the package. Replaces the deprecated ViroCloudAnchorProvider and ViroGeospatialAnchorProvider types.

Shader modifier system — major expansion

Shader modifiers now support the full range of custom GPU effects:

  • Custom textures — declare uniform sampler2D in modifier code and pass textures via materialUniforms. Swap them at runtime with updateShaderUniform.
  • Vertex → fragment data — use the new varyings field to pass typed values from a Geometry modifier to a Surface or Fragment modifier (e.g. displacement amount driving roughness).
  • Scene depth access — set requiresSceneDepth: true on a fragment modifier to receive scene_depth_texture automatically. Enables soft particles, contact glow, and intersection effects.
  • Live camera feed on geometry — set requiresCameraTexture: true to sample the AR camera on any surface. Platform differences (samplerExternalOES vs sampler2D) handled invisibly. Enables magnifying glass, portal, refraction, and warp effects.
  • Deterministic ordering — modifiers now have a priority field so engine internals never override your effects regardless of attachment order.

AR plane detection improvements

  • Plane detection now defaults to both horizontal and vertical — no need to set anchorDetectionTypes explicitly.
  • Objects placed via ViroARPlaneSelector now appear at the exact tap point, not the plane centre.
  • onPlaneSelected receives the tap position as a third argument: (plane, tapPosition?) => void.
  • New props: onPlaneRemoved, hideOverlayOnSelection, material.
  • useActualShape now defaults to true — polygon boundary used instead of bounding rect.
  • New public method handleAnchorRemoved on ViroARPlaneSelector for use in the onAnchorRemoved callback.

Depth sensor access

ViroARSceneNavigator has three new props for apps that need depth data without full occlusion:

  • depthEnabled — activates LiDAR / monocular depth / ARCore Depth for DepthPoint hit tests.
  • depthDebugEnabled — overlays the depth map on the camera feed.
  • preferMonocularDepth (iOS only) — forces monocular depth even on LiDAR devices.

Bug fixes

  • Models with washed-out / overexposed colours — GLB and other 3D assets appeared too bright due to an emissive colour value being incorrectly added to all materials. Fixed.
  • iOS video recording silent failurestartVideoRecording / stopVideoRecording were broken on iOS 17+ with the New Architecture. Multiple AVAssetWriter and AVAudioSession issues fixed; recording now falls back to video-only if audio fails.
  • Android crash when closing a scene with physics — null pointer dereference on scene close for physics-enabled nodes. Fixed.
  • Android New Architecture dev menu error — "You should not use ReactNativeHost directly" error on startup. Fixed.
  • Ghost planes in ViroARPlaneSelector — pre-allocated slot index mapping was non-deterministic causing planes to appear in wrong positions or persist after removal. Fully rewritten.
  • Selected plane disappeared immediately on tap — opacity logic inversion fixed.
  • Children rendered on every plane slot — children now rendered once, only on the selected plane.
  • onPlaneDetected return value ignored — returning false from onPlaneDetected previously had no effect. Now correctly prevents the plane from being added to the visible set.
  • Removed planes not cleaned up — disappeared planes were never removed from internal state, accumulating over time. handleAnchorRemoved now deletes the entry and resets selection if needed.
  • Plane updates silently dropped for large surfaces — ARKit update threshold logic was AND instead of OR; large planes (floors, walls) rarely updated. Fixed.
  • Rapid plane updates dropped on initial detection — fixed 100 ms throttle replaced with adaptive rate (33 ms for first 20 updates, 66 ms thereafter).

v2.52.1

16 Feb 22:43
c0acb32

Choose a tag to compare

What's Changed

Full Changelog: v2.52.0...v2.52.1

v2.52.0 - Shader System & Memory Improvements

09 Feb 20:30
390da91

Choose a tag to compare

Summary

This release adds shader customization support for iOS and Android, fixes critical memory leaks, and improves AR depth functionality.

Key Features

Shader System (New)

  • Cross-platform shader support
  • Real-time shader customization for iOS and Android
  • Shader propagation down node trees
  • Standardized fragment output
  • Texture and animation support in shaders
  • Optimized material sharing for better performance

AR & Depth Improvements

  • Depth-based AR hit testing
  • Monocular depth fallback for non-LiDAR devices
  • Fixed depth frame alignment issues

Critical Bug Fixes

  • iOS Memory Leaks (Critical): Fixed all memory leaks on iOS platform
  • Material Overflow: Fixed cloned materials array overflow crashes
  • Portal Crashes: Fixed crashes when unmounting portals on iOS
  • Gravity Type Crash: Fixed Android crash (gravity now uses 3D vector [x, y, z] instead of number)
  • VRX Asset Loading: Fixed VRX asset loading issues on iOS
  • hitResultId: Fixed availability in AR hit tests

Other Improvements

  • Performance throttle to prevent system overload
  • Refactored thread lock implementation
  • Removed debug logs from production code
  • Improved TypeScript type definitions

v2.51.0

01 Feb 20:59
190295a

Choose a tag to compare

What's Changed

  • Merge develop → main (AR stability + depth estimation for non-LiDAR) by @doranteseduardo in #428

Full Changelog: v2.50.1...v2.51.0

v2.50.1

24 Dec 03:58
f6bbb89

Choose a tag to compare

What's Changed

Full Changelog: v2.50.0...v2.50.1

v2.50.0

09 Dec 00:54

Choose a tag to compare

ReactVision 2.50.0 Release Notes

New Features

All features from ViroCore 2.50.0 are included, plus React Native specific bug fixes.


Cloud Anchors

Cross-platform AR anchor sharing between iOS and Android devices.

  • Cross-Platform: Share anchors between iOS and Android devices
  • Persistent: Anchors can be stored for 1-365 days
  • Accurate: Sub-centimeter accuracy in good conditions
  • Scalable: Supports multiple concurrent users
<ViroARSceneNavigator cloudAnchorProvider="arcore">
  {/* Use sceneNavigator.hostCloudAnchor() and resolveCloudAnchor() */}
</ViroARSceneNavigator>

API Highlights:

  • hostCloudAnchor(anchorId, ttlDays) - Upload anchor to Google's servers
  • resolveCloudAnchor(cloudAnchorId) - Retrieve anchor on another device
  • cancelCloudAnchorOperations() - Cancel pending operations

Geospatial API

Location-based AR with GPS coordinates using Google's ARCore Geospatial API.

  • Earth Tracking: Track device position using GPS and Visual Positioning System (VPS)
  • Three Anchor Types: WGS84 (absolute altitude), Terrain (relative to ground), and Rooftop (relative to buildings)
  • VPS Availability Check: Verify if enhanced positioning is available at a location
<ViroARSceneNavigator geospatialAnchorProvider="arcore">
  {/* Use createGeospatialAnchor(), createTerrainAnchor(), createRooftopAnchor() */}
</ViroARSceneNavigator>

API Highlights:

  • createGeospatialAnchor(lat, lng, altitude, quaternion) - WGS84 anchor
  • createTerrainAnchor(lat, lng, altitudeAboveTerrain, quaternion) - Ground-relative anchor
  • createRooftopAnchor(lat, lng, altitudeAboveRooftop, quaternion) - Building-relative anchor
  • getCameraGeospatialPose() - Get current location with accuracy metrics
  • checkVPSAvailability(lat, lng) - Check VPS support at location

Scene Semantics

ML-based scene understanding with 12 semantic labels.

  • 12 Semantic Labels: sky, building, tree, road, sidewalk, terrain, structure, object, vehicle, person, water, unlabeled
  • Real-time Processing: Per-frame label fractions
  • Use Cases: Outdoor detection, environment-aware content, safety warnings
// Enable via cloudAnchorProvider or geospatialAnchorProvider
// Use getSemanticLabelFractions() for environment detection

const { fractions } = await arSceneNavigator.getSemanticLabelFractions();
if (fractions.sky > 0.1) {
  console.log("User is outdoors!");
}

Depth Occlusion

Visual occlusion behind real-world objects for realistic AR blending.

  • Three Modes: Disabled, DepthBased, PeopleOnly
  • Realistic Blending: Virtual objects hidden behind real surfaces
  • People Segmentation: Option to only occlude behind detected people
<ViroARSceneNavigator occlusionMode="depthBased">
  {/* Virtual content properly occluded behind real surfaces */}
</ViroARSceneNavigator>

Occlusion Modes:

  • "disabled" - No occlusion (virtual objects always on top)
  • "depthBased" - Use depth data to occlude behind real surfaces
  • "peopleOnly" - Only occlude behind detected people

Extended glTF Support

Expanded glTF 2.0 support with 17 additional features for improved 3D model compatibility.

Core Geometry & Materials

  1. Non-indexed geometry support - Primitives without index buffers
  2. LINE_LOOP primitive type - Converted to line strip with closing segment
  3. TRIANGLE_FAN primitive type - Converted to individual triangles
  4. Mipmap filter modes - Proper separation of min/mip filtering
  5. Alpha masking (MASK mode) - With alphaCutoff support
  6. Emissive materials - emissiveFactor and emissiveTexture
  7. STEP animation interpolation - Discrete keyframe transitions
  8. Sparse accessor support - Override specific buffer values

Camera & Scene

  1. Perspective cameras - FOV, near/far planes, aspect ratio
  2. Orthographic cameras - xmag, ymag, clipping planes
  3. Default scene selection - Respects model.defaultScene

Lighting (KHR_lights_punctual)

  1. Directional lights - Color, intensity
  2. Point lights - Color, intensity, range/attenuation
  3. Spot lights - Color, intensity, range, inner/outer cone angles

Material Extensions

  1. KHR_materials_unlit - Constant/unlit lighting model
  2. Normal texture scale - Controls bump intensity
  3. Occlusion texture strength - Controls AO influence

Bug Fixes

Memory Leak Fix

  • Enhanced memory safety across 8 Java modules through Fabric architecture migration
  • Fixed null reference issues in prop application during React Native's pre-attachment phase
  • Improved stability during AR session transitions and low-end device scenarios
  • Migrated 30 methods to use Fabric's UIBlock pattern for safer memory management

Affected Modules:

  • ARSceneModule
  • ARSceneNavigatorModule
  • CameraModule
  • ControllerModule
  • NodeModule
  • SceneModule
  • SceneNavigatorModule
  • VRT3DSceneNavigatorModule

onClick iOS Fix

  • Fixed ViroText onClick event handling on iOS
  • Resolved issue where onClick prop was incorrectly passed to native code, interfering with event delegation
  • Fixes GitHub issue #272

AR Image Marker Fix

  • Improved ARImageMarker lifecycle management with proper weak reference patterns
  • Prevents retain cycles and memory leaks during image target tracking
  • Proper cleanup via removeARImageTarget() when updating targets

Setup

Expo Projects

{
  "expo": {
    "plugins": [
      [
        "@reactvision/react-viro",
        {
          "googleCloudApiKey": "YOUR_API_KEY",
          "cloudAnchorProvider": "arcore",
          "geospatialAnchorProvider": "arcore",
          "android": {
            "xRMode": ["AR"]
          }
        }
      ]
    ]
  }
}

Then rebuild:

npx expo prebuild --clean
npx expo run:ios
# or
npx expo run:android

Bare React Native Projects

iOS - Podfile:

use_frameworks! :linkage => :dynamic

pod 'ARCore/CloudAnchors', '~> 1.51.0'
pod 'ARCore/Geospatial', '~> 1.51.0'
pod 'ARCore/Semantics', '~> 1.51.0'

iOS - Info.plist:

<key>GARAPIKey</key>
<string>YOUR_GOOGLE_CLOUD_API_KEY</string>

Android - AndroidManifest.xml:

<meta-data
    android:name="com.google.android.ar.API_KEY"
    android:value="YOUR_GOOGLE_CLOUD_API_KEY" />

Requirements

  • iOS: iOS 12.0+, ARKit-capable device
  • Android: Android 7.0+ (API 24), ARCore-supported device
  • Google Cloud: Valid API key with ARCore API enabled
  • Depth Features: LiDAR (iOS) or ToF sensor/ARCore Depth API (Android)

v2.44.2

22 Nov 00:42

Choose a tag to compare

This is a minor patch update that removes some layers in the Android side to get 1:1 plane detection compared with direct ARCore implementations.

See at v2.44.1 for more details.

v2.44.1

19 Nov 23:07
d530ccb

Choose a tag to compare

Release Notes – v2.44.1

AR Plane Detection & Selection – Major Update

ViroARPlaneSelector – Complete Rewrite

Accurate Plane Shape Rendering

  • Planes now render using their actual geometric boundaries from ARKit/ARCore (via boundary vertices).
  • Automatic fallback to rectangular visualisation when vertex data is not available.
  • New useActualShape property to control rendering mode (default: true).

Map-Based Plane Tracking

  • Replaced array-based tracking with Map<string, ViroARPlaneType> for reliable and deterministic plane handling.
  • Plane identification now uses anchorId, eliminating index-based race conditions.
  • Improved stability for both plane selection and update cycles.

Multi-Alignment Detection

  • Added new alignment mode: "Both" for concurrent horizontal and vertical plane detection.
  • 25 detectors per alignment type for broader and more consistent scene coverage.
  • Enhanced scene understanding through simultaneous multi-plane detection.

Plane Classification Support (iOS)

  • ARKit plane classification now exposed, including: Wall, Floor, Ceiling, Table, Seat, Door, Window.
  • Classification data is included in all plane update callbacks.
  • Enables semantic placement and surface-specific logic.

Enhanced Properties & Callbacks

  • onPlaneDetected?: (updateMap) => boolean — Validate planes before adding them.
  • disableClickSelection?: boolean — Enables visual-only mode.
  • useActualShape?: boolean — Controls shape rendering behaviour.

Visual Improvements

  • Updated material to a bright, translucent blue (rgba(0, 122, 255, 0.5)) for improved visibility.
  • cullMode: "None" enabled for better Android rendering compatibility.
  • Corrected alpha blending and depth buffer behaviour.

ViroARPlane Improvements

Improved Vertex Handling

  • More accurate 3D-to-2D vertex conversion for shape mapping.
  • Unified coordinate system handling across iOS and Android.
  • Corrected rotation logic for horizontal and vertical surfaces.

Enhanced Anchor Data

  • Plane anchors now provide full metadata: position, rotation, scale, centre, and dimensions.
  • Classification and vertex data included in all callbacks.
  • Consistent and reliable anchorId tracking throughout the plane lifecycle.

Architecture & Performance

16KB Page Size Support

  • Full compatibility with modern Android devices using 16KB memory pages.

Breaking Changes

Removed Properties (ViroARPlaneSelector)

  • maxPlanes removed (replaced by dynamic 25-detector-per-alignment behaviour).
  • ViroCommonProps and ViroObjectProps removed from type definitions.
    • These properties were previously documented but non-functional.
    • The component now exposes only explicit, fully supported props.

Internal State Refactor

  • Internal state has been migrated from an array to a Map.
    • (This affects only direct internal state access and does not impact typical usage.)

v2.43.6

09 Oct 04:41

Choose a tag to compare

This is a patch release targeting the pod installation issues happening in EAS mainly. We have tested this update in different installation scenarios all with success.