Why SceneView¶
SceneView is the only actively maintained, Compose-native 3D and AR library for Kotlin. It delivers Filament's physically-based rendering and ARCore's full AR capabilities through a declarative API that developers already understand. SceneViewSwift (alpha) brings the same experience to iOS, macOS, and visionOS via RealityKit, and the web build plus the Flutter and React Native bridges carry it further. Android XR headsets are still on the roadmap.
The pitch in 10 seconds¶
SceneView(modifier = Modifier.fillMaxSize()) {
ModelNode(modelInstance = helmet, scaleToUnits = 1.0f, autoAnimate = true)
LightNode(type = LightManager.Type.SUN, apply = { intensity(100_000.0f) })
}
That's a production-quality 3D viewer. Five lines. Same Kotlin you write every day.
What makes SceneView different¶
Compose-native — not a wrapper¶
60% of the top 1,000 Play Store apps use Jetpack Compose. SceneView's scene graph is the Compose tree. The Compose runtime owns it.
if/elsecontrols whether nodes existState<T>drives animations, positions, visibilityLaunchedEffectandDisposableEffectwork inside scenes- Nesting nodes = nesting
Column { Row { Text() } }
Zero boilerplate lifecycle¶
val engine = rememberEngine()
val modelLoader = rememberModelLoader(engine)
val model = rememberModelInstance(modelLoader, "models/product.glb")
// All resources destroyed automatically when composable leaves the tree
No onPause/onResume dance. No destroy() calls. No leaked Filament objects.
Thread safety by default¶
Filament requires all JNI calls on the main thread. rememberModelInstance handles the
IO-to-main-thread transition automatically. You never think about it.
Gesture handling built in¶
ModelNode supports pinch-to-scale, drag-to-rotate, and two-finger-rotate out of the box.
Orbit camera in one line:
SceneView(cameraManipulator = rememberCameraManipulator()) { ... }
Multi-platform trajectory¶
SceneViewSwift (alpha) supports iOS, macOS, and visionOS via RealityKit. Flutter and
React Native bridges and a Compose Multiplatform viewer façade (sceneview-compose) ship
alongside it; Android XR headsets are still on the roadmap. One declarative API across all
target platforms.
AI-assisted development¶
SceneView ships with an MCP server (sceneview-mcp) and a machine-readable llms.txt API
reference. Whichever assistant you use, it has the current API — no hallucinated
methods, no outdated patterns.
46+ composable node types¶
| Category | Nodes |
|---|---|
| Models | ModelNode — glTF/GLB with animations, gestures, scaling |
| Geometry | CubeNode, SphereNode, CylinderNode, PlaneNode — no asset files needed |
| Lighting | LightNode (sun, point, spot, directional), DynamicSkyNode, ReflectionProbeNode |
| Atmosphere | FogNode — distance/height fog driven by Compose state |
| Media | ImageNode, VideoNode (with chromakey), ViewNode (any Composable in 3D) |
| Text | TextNode, BillboardNode — camera-facing labels and UI callouts |
| Drawing | LineNode, PathNode — 3D polylines, measurements, animated paths |
| Physics | PhysicsNode — rigid body simulation, collision, gravity |
| AR | AnchorNode, HitResultNode, AugmentedImageNode, AugmentedFaceNode, CloudAnchorNode, StreetscapeGeometryNode |
| XR | XRScene — spatial computing with the same composable API |
| Structure | Node (grouping/pivots), CameraNode, MeshNode |
Production rendering — Google Filament¶
Built on Filament, the same physically-based rendering engine used inside Google Search and Google Play Store.
- Physically-based rendering (PBR) with metallic/roughness workflow
- HDR environment lighting (IBL) from
.hdrand.ktxfiles - Dynamic shadows, reflections, ambient occlusion
- Post-processing: bloom, depth-of-field, SSAO, fog
- 60fps on mid-range devices
Full ARCore integration¶
ARSceneView(
planeRenderer = true,
onSessionUpdated = { _, frame ->
anchor = frame.getUpdatedPlanes()
.firstOrNull { it.type == Plane.Type.HORIZONTAL_UPWARD_FACING }
?.let { it.createAnchorOrNull(it.centerPose) }
}
) {
anchor?.let { a ->
AnchorNode(anchor = a) {
ModelNode(modelInstance = sofa, scaleToUnits = 0.5f)
}
}
}
- Plane detection (horizontal + vertical) with persistent mesh rendering
- Image detection and tracking (
AugmentedImageNode) - Face mesh tracking and augmentation (
AugmentedFaceNode) - Cloud anchors for cross-device persistence (
CloudAnchorNode) - Environmental HDR — real-world light estimation
- Streetscape geometry — city-scale 3D building meshes
- Geospatial API support — place content at lat/long coordinates
Real-world use cases¶
E-commerce: product viewer in 10 lines¶
Replace a static Image() with a SceneView {} on your product detail page:
SceneView(
modifier = Modifier.fillMaxWidth().height(300.dp),
cameraManipulator = rememberCameraManipulator()
) {
rememberModelInstance(modelLoader, "models/shoe.glb")?.let {
ModelNode(modelInstance = it, scaleToUnits = 1.0f)
}
}
Furniture & interior design¶
Let customers see how a sofa looks in their living room. Tap to place, pinch to resize,
rotate with two fingers. Compose UI floats alongside via ViewNode.
Education & training¶
Interactive 3D anatomy models, molecular structures, mechanical assemblies — controlled by standard Compose sliders, buttons, and state.
Data visualization¶
3D bar charts, globes, network graphs. The data is Compose State — update it and
the visualization reacts instantly.
Social & communication¶
AugmentedFaceNode for face filters and effects. Apply materials to the face mesh,
attach 3D objects to landmarks. Front-camera AR.
The numbers¶
| Metric | Value |
|---|---|
| Node types | 46+ composable nodes |
| Rendering | Google Filament — PBR, 60fps mobile |
| AR backend | ARCore — latest features |
| Platforms | Android (stable) + iOS/macOS/visionOS (alpha) |
| Setup | 1 Gradle line, 0 XML |
| Model viewer | ~5 lines of Kotlin |
| AR placement | ~15 lines of Kotlin |
| APK size impact | ~5 MB |
| License | Apache 2.0 |