filament-kmp
0.1.3-beta02indexedPhysically-based renderer wrapper exposing Filament engine with first-class Compose integration, scene DSL, glTF/GLB asset loading, runtime material compilation, camera state and value-based post-processing.
Physically-based renderer wrapper exposing Filament engine with first-class Compose integration, scene DSL, glTF/GLB asset loading, runtime material compilation, camera state and value-based post-processing.
Filament KMP brings the same physically based renderer that powers Android's Filament to iOS, Desktop/JVM, and Web (JS & Wasm) — as a plain Kotlin Multiplatform library, with an optional Compose Multiplatform layer on top.
[!NOTE] Unofficial project. This is a community-maintained Kotlin Multiplatform wrapper around Google's Filament. It is not affiliated with, endorsed by, or supported by Google or the Filament team.
FilamentSceneView(
modifier = Modifier.fillMaxSize(),
cameraState = rememberCameraState(initialEye = Position(0f, 1f, 4f)),
skyboxState = rememberSkyboxState(SkyboxSource.Color(LinearColor(0.1f, 0.12f, 0.15f))),
postProcessing = PostProcessing(bloom = Bloom(strength = 0.2f)),
) {
DirectionalLight(direction = Direction(0.3f, -1f, -0.5f), intensity = LightIntensity.LuminousPower(100_000f))
GltfInstance(asset = rememberGltfAsset { Res.readBytes("files/Duck.glb") })
}
The world is declared in the content lambda; the viewport's look is configured by value. Need several cameras over one world? Hoist the scene with rememberFilamentScene { … } and feed it to multiple FilamentViews.
Not using Compose? filament, gltfio, filament-utils and are plain Kotlin bindings with no Compose dependency — drive / / yourself against your own , , GLFW window or , or render headless and read the pixels back:
val engine = Engine.create()!!
val swapChain = engine.createSwapChain(NativeSurface(myNativeWindow))
val renderer = engine.createRenderer()
if (renderer.beginFrame(swapChain, frameTimeNanos)) {
renderer.render(view)
renderer.endFrame()
}
See Using the Engine Without Compose.
Every platform runs on one C API generated from Filament's C++ headers, and the Kotlin API is written once in commonMain on top of it, so the API and its behavior are the same everywhere:
libfilament-c.so per ABI)libfilament-c per platform)JVM requirements: the Android artifacts ship JVM 11 bytecode (minSdk 24) and work with the standard Android jvmTarget = 11 setup. The Desktop/JVM artifacts need JDK 17+, like Compose Desktop.
Upgrading from 0.6.0? The API now follows Filament's C++ headers and the native runtimes changed on every platform; follow the migration guide.
Add the Maven Central repository and depend on the modules you need:
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}
// build.gradle.kts
kotlin {
sourceSets {
commonMain.dependencies {
// Compose integration (pulls in the engine), or just "…:filament:0.7.1" without Compose.
implementation("io.github.erkko68.filament:filament-compose:0.7.1")
}
}
}
The same coordinates work on every target — Gradle resolves one variant per target you declare, so you don't download the platforms you don't build for. (The one exception: the Desktop/JVM natives default to all five desktop platforms; one snippet narrows them — see what Gradle actually downloads.)
For the full setup (Compose Multiplatform plugin, native runtime for Desktop, iOS framework linking, Web prebuilts) see Getting Started, and Modules for the per-target dependency table.
All published under io.github.erkko68.filament. The Desktop/JVM native runtime (filament-jni-desktop) is pulled in automatically, with the natives in per-platform filament-jni-runtime-<os>-<arch> jars — all of them by default, or only your platform's if your build declares os/arch attributes (see desktop/README.md). See Modules for full coordinates and dependency graph.
Releases are plain X.Y.Z (no pre-release suffixes since 0.2.0):
X.Y.0 (minor) — the normal release channel. Any change to the public API — new bindings from an upstream release of any kind, or wrapper API additions and changes — ships as a minor bump. New upstream (1.73 → 1.74 → …) always land here. Breaking wrapper API changes may appear here and are always listed in the .All io.github.erkko68.filament:* artifacts share one version and must be upgraded together. The project is actively maintained long-term and tracks upstream Filament releases as they are published (see docs/internals/upgrading-filament.md for the process). Larger technical direction — like zero-copy GPU sharing with Compose — lives in the Roadmap.
The public API follows Filament's C++ API, the one Filament's documentation and headers describe: the same classes, method names, owners and default values, on every platform. Adapted to Kotlin only where Kotlin has its own shape:
How that API is produced, from C++ headers to a generated C API to Kotlin, is in The Generated C API.
matc reference.The samples/ directory contains a shared Compose scene running on all four targets. See samples/README.md for build commands.
The web build is also deployed live to erkko68.github.io/filament-kmp — open it on any WebGL 2.0–capable browser to try every scene without a local toolchain.
Licensed under the Apache License, Version 2.0. Filament itself is also Apache-2.0 licensed by Google.
filamatEngineRendererSwapChainSurfaceViewCAMetalLayer<canvas>filament-kmp.wasm| Artifact | Description |
|---|
filament | Core renderer — Engine, Scene, View, Renderer, Camera, Texture, Material. No Compose dependency. |
filament-compose | Compose Multiplatform integration — rememberFilamentScene / FilamentView (and the FilamentSceneView shortcut), scene DSL, camera state, value-based post-processing. |
gltfio | glTF / GLB asset loading — AssetLoader, FilamentAsset, Animator. |
filamat | Runtime material compilation — MaterialBuilder. |
filament-utils | Camera manipulators, HDR/KTX loaders, math helpers. |
X.Y.Z (patch) — no API surface change: bug fixes in the wrapper, and upstream point releases picked up without binding anything new. Safe to pick up without reading anything.X.0.0 (major) — reserved for maturity milestones and very large changes (a stabilized public API, a full architectural rework). Routine upstream tracking never triggers a major bump — expect minor releases to keep flowing for as long as Filament keeps releasing.view.scene, camera.focusDistance, engine.backend, engine.transformManager, engine.isPaused); calls that take arguments or do work stay methods (engine.getFeatureFlag(name), engine.setActiveFeatureLevel(level)).Engine.create(), Material.Builder.build()), AutoCloseable on self-destroying types, overloads instead of per-type names (engine.destroy(view), engine.isValid(material)).Engine reachable through FilamentEffect.FilamentSceneView / rememberFilamentScene / FilamentView, scene DSL, post-processing.Surfaced from shared tags and platforms — no rankings paid for.