By the end of this guide you will have a fully workingDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/danielitoCode/Spatial/llms.txt
Use this file to discover all available pages before exploring further.
@Composable function that renders a Cube, a Sphere, and a ground Plane in a 3D scene, wired to a smooth orbit camera that responds to touch gestures. No OpenGL setup, no render loop management — just a composable tree that Spatial turns into a GPU-rendered frame.
Spatial is distributed as local Gradle submodules. Open your app-level
build.gradle.kts and declare the three public modules as implementation dependencies:// app/build.gradle.kts
dependencies {
implementation(project(":spatial-compose"))
implementation(project(":spatial-compose-runtime-adapter"))
implementation(project(":spatial-units"))
}
:spatial-compose — the declarative Compose API (Scene, Element, Modifier3D, rememberCameraState, Gestures):spatial-compose-runtime-adapter — provides DefaultSceneRenderHostFactory, which wires the Compose layer to the real OpenGL renderer:spatial-units — typed unit extensions (meters, cm, deg) used in modifier chainsyaw — horizontal rotation around the world Y-axis, in degrees. Positive values rotate the camera to the right of the scene.pitch — vertical tilt of the camera, in degrees. Negative values tilt the camera downward, so the scene is viewed slightly from above.zoom — a unitless multiplier controlling how close the camera sits to the orbit target. Values below 1f zoom out; values above 1f zoom in.rememberCameraState is backed by Compose’s remember, so the state survives recomposition. It also exposes animateTo for programmatic, spring-animated camera transitions.Wrap your elements inside the
Scene composable, passing the camera state, the render host factory, and your chosen gesture mode:@Composable
fun CoreOneScene(modifier: Modifier = Modifier) {
val cameraState = rememberCameraState(
yaw = 20f.deg,
pitch = (-12f).deg,
zoom = 1.25f,
)
Scene(
modifier = modifier.fillMaxSize(),
renderHostFactory = DefaultSceneRenderHostFactory,
cameraState = cameraState,
gestures = Gestures.orbit(),
) {
Element.Cube(
modifier = Modifier3D.Default
.rotateY(35f.deg)
.rotateZ(18f.deg)
.size(1.4f.meters)
.position(0f.meters, 0f.meters, (-4f).meters),
)
Element.Sphere(
modifier = Modifier3D.Default
.size(1f.meters)
.position(2f.meters, 0f.meters, (-6f).meters),
)
Element.Plane(
modifier = Modifier3D.Default
.size(8f.meters, 0.1f.meters, 8f.meters)
.position(0f.meters, (-1.2f).meters, (-5f).meters),
)
}
}
.size(all: Distance).size(width, height, depth).position(x, y, z)Distance units.rotateX/Y/Z(angle)Angle unitsDefaultSceneRenderHostFactory is the bridge between Spatial’s declarative Compose layer and the real OpenGL ES 3.0 backend. It implements SceneRenderHostFactory, creates an AndroidView-hosted GL surface, and manages the render loop lifecycle. You should always pass it as the renderHostFactory argument unless you are supplying a custom test double.Replace Both accept an optional
Gestures.orbit() with Gestures.orbitAndZoom() to also enable pinch-to-zoom:sensitivity parameter (GestureSensitivity.Adaptive by default) if you need to tune orbit or zoom response.Complete Example
Here is the full, self-contained composable with all required imports:CoreOneScene.kt