← Back to Blog tutorials

Android AR for your GLB models: Scene Viewer, no app needed

By BitSoul Team8/14/20265 min read2 views
Android AR for your GLB models: Scene Viewer, no app needed

Ask someone to view your GLB model in AR on their Android phone and the real answer is: they already can, straight from a browser link, no app install. GLB models reach Android AR through Google's Scene Viewer — a viewer built into every ARCore-capable phone running Android 7.0 (API 24) or later. Tap a link, Scene Viewer opens, the camera comes up, the model drops into their living room. The catch is everything upstream of that tap: how the file is hosted, what unit scale it was exported at, and whether the button is wired correctly. Get any of those wrong and Scene Viewer either does nothing or launches a boombox the size of a refrigerator.

Why Scene Viewer, not a custom AR app

Building a native ARCore app just to show one 3D model burns weeks of Sceneform work for a payoff most teams don't need. Scene Viewer is Google's own AR frontend, shipped at the OS level on every ARCore-capable phone running Android 7.0 (API 24) or later. It launches by intent — from a browser tab, from a native app, from a plain link on a webpage — with no Play Store listing, no APK, no permission dialog beyond camera access. The trade-off: the reticle, the exit button, and the "view in your space" label are Google's UI, not yours. For a store listing, a portfolio page, or a "see it at scale" step before checkout, that trade is almost always worth it.

Add the AR button: model-viewer or a raw intent link

Two paths get you there. Google's model-viewer web component is the one to reach for first — a custom element you drop into a page, pointed at a `src` for the GLB and, to cover iPhone in the same breath, an `ios-src` for a USDZ version. Add the `ar` flag and it renders its own "view in your space" button, detecting Android versus iOS automatically and handing off to Scene Viewer or Quick Look accordingly — one element instead of two code paths.

Three attributes are worth setting explicitly instead of trusting the defaults. `ar-modes` controls viewer priority — put `scene-viewer` ahead of `webxr` if Google's native viewer should win over an in-page WebXR session. `ar-scale` set to `auto` lets Scene Viewer resize the model to a comfortable viewing distance; set to `fixed`, it locks to the GLB's real-world unit scale, which is what you want anywhere the visitor needs to judge true size. `ar-placement` picks `floor` or `wall`.

If the page can't carry a custom element — a CMS that strips web components, or a native app with its own UI — fire the intent directly instead: a link on scheme `intent://arvr.google.com/scene-viewer/1.0`, a `file` parameter carrying the full HTTPS URL to the GLB, `mode=ar_preferred`, and a `browser_fallback_url` for the rare phone without Scene Viewer installed. It's more plumbing for the result model-viewer gives for free.

Before wiring up either path, confirm the file is reachable the way Scene Viewer expects it — the intent fetches the URL itself, outside your page's session, so anything behind auth or a CORS block fails silently:

```bash
curl -I https://yourcdn.com/models/prop.glb
# look for: HTTP 200, and content-type: model/gltf-binary
# application/octet-stream here is the most common silent failure
```

Scale, hosting, and file size: the gotchas that break AR

Scale is the complaint that shows up most. Scene Viewer treats one GLB unit as one meter — there's no dialog asking what unit the model was exported at. A prop built at centimeter scale by habit (1 unit = 1cm, common if the default grid never got changed) turns into a coffee mug that fills the room. Test against something whose real size is already known: Chrome Boombox is close enough to an actual boombox's footprint that a scale error is obvious in the viewfinder within a second — a free account's two monthly downloads cover evaluation; commercial use is included with paid memberships. Leave `ar-scale` on `auto` and a broken import quietly shrinks to something plausible-looking, which hides the bug instead of surfacing it — set it to `fixed` while testing.

Hosting trips people up next. The file needs a public HTTPS URL — not localhost, not a signed link that expires, nothing behind a login — because Scene Viewer is a separate process fetching that URL cold, not your page's fetch context. A common failure: the GLB opens fine in a browser tab but Scene Viewer does nothing, because the server returns it as `application/octet-stream` instead of `model/gltf-binary`. Some static hosts guess content type from the extension and guess wrong for `.glb` — check the header, don't assume it.

File size is the third gotcha, and there's no official ceiling, only field reports on Google's own model-viewer issue tracker: a 5MB file opens about as fast as the camera-permission prompt itself; a 60MB file has been clocked around 30 seconds to load; a 35MB model failed to trigger AR at all on one tester's phone. Treat 15MB as the practical ceiling for anything that needs to load reliably on a three-year-old mid-range phone, not just a flagship. Running the model through in-browser poly reduction before publishing an AR link — 3D Studio's decimation tool runs on the visitor's own GPU, free — turns an 80k-triangle prop into something under 12k without a visible difference at arm's length, and that's the gap between a two-second load and a thirty-second one.

Last one: Scene Viewer can't be debugged over USB the way a webpage can. Chrome DevTools' remote inspector shows the page, not what happens once the intent hands off to the native viewer, so "it's not working" on desktop tells nothing useful. Wire up model-viewer's `ar-status` event instead and log it somewhere visible:

```js
document.querySelector('#viewer').addEventListener('ar-status', (e) => {
console.log('AR status:', e.detail.status);
// 'failed' fires before Scene Viewer gives up silently — surface it in the UI
});
```

iOS Quick Look vs Android Scene Viewer

| | iOS Quick Look | Android Scene Viewer |
|---|---|---|
| File format | USDZ | GLB |
| Trigger | anchor carrying `rel="ar"`, or model-viewer's `ios-src` | model-viewer's `ar` button, or a `scene-viewer` intent link |
| Minimum OS | iOS 12 | Android 7.0 / API 24, with ARCore |
| Default scale | respects the USDZ's real-world units | `auto` fits the view; `fixed` uses real units |
| Hosting | public HTTPS URL | public HTTPS URL, correct MIME type |

For a viewer built from scratch instead of model-viewer's defaults — custom camera controls, a branded loading state, a non-AR fallback for desktop visitors — loading the GLB directly through Three.js is the lower-level route, and the same compression rules (Draco, KTX2) carry over unchanged. Either way, Scene Viewer and Quick Look read from the same hosted file, so a model that scales and loads correctly on Android is most of the way to correct on iOS once a USDZ conversion is added.

---

*This post is part of the Ultimate Guide to Free 3D Game Assets — BitSoul's complete reference for formats, texturing, rigging, optimization, and engine integration.*

Tags: 3d-models game-assets workflow tutorials 3d-assets optimization

Skip the modelling — download it instead

A free BitSoul account gets you 2 game-ready models every month plus 25 AI Engine credits to generate one of your own, no card required. Clean topology, PBR textures, and GLB downloads that drop straight into Unreal, Unity, Godot or Blender — plus OBJ and 3D-printable STL export.

Create a free account → Browse 846 models