Use Cases¶
Real-world applications of SceneView across industries. Each example includes the key composables used and approximate line counts.
E-commerce: 3D product viewer¶
Replace static product images with an interactive 3D viewer. Customers can orbit, zoom, and inspect products from every angle.
@Composable
fun ProductViewer(productGlb: String) {
val engine = rememberEngine()
val modelLoader = rememberModelLoader(engine)
val model = rememberModelInstance(modelLoader, productGlb)
Scene(
modifier = Modifier.fillMaxWidth().height(400.dp),
engine = engine,
modelLoader = modelLoader,
cameraManipulator = rememberCameraManipulator(),
environment = rememberEnvironment(rememberEnvironmentLoader(engine)) {
createHDREnvironment("environments/studio.hdr")!!
}
) {
model?.let {
ModelNode(modelInstance = it, scaleToUnits = 1.0f, autoAnimate = true)
}
}
}
~15 lines to replace a product image with an interactive 3D viewer.
Key nodes: ModelNode, Scene
Features used: orbit camera, HDR lighting, auto-animation
E-commerce: AR try-before-you-buy¶
Let customers see how furniture looks in their room before purchasing.
@Composable
fun ARFurniturePlacer(furnitureGlb: String) {
var anchor by remember { mutableStateOf<Anchor?>(null) }
val engine = rememberEngine()
val modelLoader = rememberModelLoader(engine)
val furniture = rememberModelInstance(modelLoader, furnitureGlb)
ARScene(
modifier = Modifier.fillMaxSize(),
engine = engine,
modelLoader = modelLoader,
planeRenderer = anchor == null, // hide planes after placement
onTouchEvent = { event, hitResult ->
if (event.action == MotionEvent.ACTION_UP && hitResult != null) {
anchor = hitResult.createAnchor()
}
true
}
) {
anchor?.let { a ->
AnchorNode(anchor = a) {
furniture?.let {
ModelNode(
modelInstance = it,
scaleToUnits = 0.8f,
isEditable = true // pinch to scale, drag to move
)
}
}
}
}
}
~25 lines. Tap to place, pinch to scale, drag to reposition. All built in.
Education: interactive 3D anatomy¶
Students can rotate and explore a 3D model with labeled parts. Tap a part to see information.
@Composable
fun AnatomyViewer() {
var selectedPart by remember { mutableStateOf<String?>(null) }
val engine = rememberEngine()
val modelLoader = rememberModelLoader(engine)
val model = rememberModelInstance(modelLoader, "models/heart.glb")
Box(modifier = Modifier.fillMaxSize()) {
Scene(
modifier = Modifier.fillMaxSize(),
engine = engine,
modelLoader = modelLoader,
cameraManipulator = rememberCameraManipulator(),
onGestureListener = rememberOnGestureListener(
onSingleTapConfirmed = { _, node ->
selectedPart = node?.name
}
)
) {
model?.let {
ModelNode(modelInstance = it, scaleToUnits = 1.5f)
}
// Labels float in 3D space
TextNode(text = "Left Ventricle", position = Position(-0.2f, 0f, 0.3f))
TextNode(text = "Right Atrium", position = Position(0.3f, 0.4f, 0f))
}
// Compose overlay
selectedPart?.let { part ->
Card(modifier = Modifier.align(Alignment.BottomCenter).padding(16.dp)) {
Text("Selected: $part", modifier = Modifier.padding(16.dp))
}
}
}
}
Key nodes: ModelNode, TextNode, Scene
Features: tap interaction, 3D text labels, Compose overlay
Data visualization: 3D globe¶
Display data points on a rotating globe. Each point is a sphere positioned by latitude/longitude.
@Composable
fun DataGlobe(dataPoints: List<GeoPoint>) {
Scene(
modifier = Modifier.size(300.dp),
cameraManipulator = rememberCameraManipulator(
orbitHomePosition = Position(0f, 0f, 3f)
)
) {
// Earth sphere
SphereNode(radius = 1f, materialInstance = earthMaterial)
// Data point markers
dataPoints.forEach { point ->
val pos = point.toCartesian(radius = 1.02f) // slightly above surface
SphereNode(
radius = 0.02f,
materialInstance = redMaterial,
position = pos
)
}
}
}
Social: AR face filters¶
Apply effects to the user's face using the front camera.
@Composable
fun FaceFilter() {
var faces by remember { mutableStateOf<List<AugmentedFace>>(emptyList()) }
ARScene(
modifier = Modifier.fillMaxSize(),
sessionFeatures = setOf(Session.Feature.FRONT_CAMERA),
sessionConfiguration = { _, config ->
config.augmentedFaceMode = Config.AugmentedFaceMode.MESH3D
},
onSessionUpdated = { session, _ ->
faces = session.getAllTrackables(AugmentedFace::class.java)
.filter { it.trackingState == TrackingState.TRACKING }
}
) {
faces.forEach { face ->
AugmentedFaceNode(
augmentedFace = face,
meshMaterialInstance = filterMaterial
)
}
}
}
Architecture: 3D floor plan walkthrough¶
Navigate through a building with interactive room labels and dynamic lighting.
@Composable
fun FloorPlanViewer() {
var timeOfDay by remember { mutableFloatStateOf(12f) }
Column {
Scene(
modifier = Modifier.weight(1f).fillMaxWidth(),
cameraManipulator = rememberCameraManipulator(
orbitHomePosition = Position(0f, 5f, 8f)
)
) {
rememberModelInstance(modelLoader, "models/apartment.glb")?.let {
ModelNode(modelInstance = it, scaleToUnits = 4f)
}
DynamicSkyNode(timeOfDay = timeOfDay)
FogNode(view = view, density = 0.02f, enabled = timeOfDay < 7f || timeOfDay > 19f)
// Room labels
TextNode(text = "Living Room", position = Position(0f, 2.5f, 0f))
TextNode(text = "Kitchen", position = Position(3f, 2.5f, -2f))
}
// Time of day slider
Slider(
value = timeOfDay,
onValueChange = { timeOfDay = it },
valueRange = 0f..24f,
modifier = Modifier.padding(16.dp)
)
}
}
Key nodes: ModelNode, DynamicSkyNode, FogNode, TextNode
Gaming: physics playground¶
Interactive scene where users throw objects that bounce and collide.
@Composable
fun PhysicsPlayground() {
val balls = remember { mutableStateListOf<BallState>() }
Scene(
modifier = Modifier.fillMaxSize(),
onGestureListener = rememberOnGestureListener(
onSingleTapConfirmed = { event, _ ->
balls.add(BallState(
velocity = Position(0f, 5f, -8f),
position = Position(0f, 2f, 0f)
))
}
)
) {
// Floor
PlaneNode(size = Size(10f, 10f), materialInstance = floorMaterial)
// Balls with physics
balls.forEach { ball ->
val model = rememberModelInstance(modelLoader, "models/ball.glb")
model?.let {
val node = ModelNode(modelInstance = it, scaleToUnits = 0.15f)
PhysicsNode(
node = node,
mass = 1f,
restitution = 0.7f,
linearVelocity = ball.velocity,
floorY = 0f,
radius = 0.075f
)
}
}
}
}
Key nodes: ModelNode, PhysicsNode, PlaneNode
Industry fit¶
| Industry | Primary nodes | Key features |
|---|---|---|
| E-commerce | ModelNode, AnchorNode |
Orbit camera, AR placement, gestures |
| Education | ModelNode, TextNode |
Labels, tap interaction, animation control |
| Real estate | ModelNode, DynamicSkyNode, FogNode |
Time-of-day, atmospheric effects |
| Social | AugmentedFaceNode |
Front camera, face mesh, material overlay |
| Data viz | SphereNode, LineNode, PathNode |
Geometry primitives, 3D charts |
| Gaming | PhysicsNode, ModelNode |
Physics, collision, tap-to-throw |
| Navigation | StreetscapeGeometryNode, AnchorNode |
Geospatial, streetscape, waypoints |