Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsPartly. Kotlin Multiplatform (KMP) can carry a game’s Kotlin logic across targets, and Compose Multiplatform (CMP) can share menus, settings screens, and overlays. Neither one, by itself, makes the 3D renderer common across platforms, and neither guarantees five working targets or 60 frames per second. This article separates those three claims so each can be tested on its own.
What KMP and CMP each contribute to a game
KMP is the code-sharing technology. You write Kotlin once in common source sets, compile it for each target, and add platform-specific code where a platform API is needed. JetBrains describes this gradual approach in its Kotlin Multiplatform overview. CMP supplies a way to share UI code across platforms, so a game’s menus, options screens, and heads-up displays can be written once.
As an Amazon Associate I earn from qualifying purchases.
For a 3D game, that leaves three layers to assess separately:
- Shared logic: rules, simulation, game state, and data models written in common Kotlin. This is the part KMP is designed to carry.
- Shared UI: menus, options, and overlays, which CMP can share.
- Rendering: the 3D surface and its draw calls. Using KMP or CMP does not make this layer common. It depends on the renderer you choose and how that renderer is integrated on each platform.
JetBrains’ KMP Survey (Q2 2024) reported that 55% of respondents saw improved collaboration after adopting KMP, and 65% of teams reported improved performance and quality. These are self-reported survey results, not controlled comparisons, and they do not measure frame rates in a game.
#1 Best Overall
Can Compose Multiplatform render 3D?
Not as a game renderer. CMP’s documented role is UI sharing. A 3D view inside a Compose screen has to come from a renderer or an integration library. The one integration named in the sources is SceneView, whose project README describes its CMP integration as alpha and covering a viewer subset. A 3D viewer embedded in a Compose screen is a plausible path. A full game pipeline driven from CMP is not something these sources establish.
Does one codebase really target Android, iOS, desktop, web, and server?
The official Kotlin Multiplatform quickstart creates a sample project with Android, iOS, desktop, web, and server targets. That shows a project can be configured for those target categories. It does not show a 3D game running on any of them, and those five categories are not necessarily your release targets. Server has no screen to render to, so it can host simulation or backend logic but not a visible game client.
Rank #2
Name your five release targets before planning the renderer. The table below shows what each category means for a 3D game. Your own list might look like Android, iOS, Windows, macOS, and a browser build, but that is an example, not a recommendation.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →| Target | Covered by the quickstart sample | Rendering surface | What a 3D game must verify |
|---|---|---|---|
| Android | Yes | Device screen | Renderer path on Android, and behaviour when the app is paused and resumed |
| iOS | Yes | Device screen | Renderer path on iOS; builds require a Mac with Xcode |
| Desktop | Yes | Application window | Which operating systems you ship, and renderer support on each (Filament lists Linux, macOS, and Windows) |
| Web | Yes | Browser canvas | Whether the JavaScript or WebAssembly build is used, and renderer support for that build |
| Server | Yes | None | Headless simulation or backend use only; not a visible game client |
Setup costs that differ by target
- iOS: JetBrains’ build and run guide says iOS targets require a Mac with Xcode. Windows and Linux machines cannot complete that build step, so plan a macOS machine into your pipeline from the start.
- Run configurations: the same guide describes platform-specific run configurations, so each target has its own launch path that must be tested separately.
- Web: the guide describes a web compatibility mode that can produce both JavaScript and WebAssembly builds. Your renderer must support the build you ship.
Which 3D renderers can you evaluate?
Two candidates appear in the sources. Treat both as options to evaluate, not as drop-in game engines that cover the full target list.
Rank #3
Google Filament
Filament describes itself as a real-time, physically based renderer. Its repository lists Android, iOS, Linux, macOS, Windows, and WebAssembly among its targets. Because Filament is a native library, each target needs its own binding or integration layer to reach it from Kotlin. The repository listing does not establish that the API is identical on every target, or that Filament supplies the scene management, input handling, and asset pipeline a game needs.
SceneView
SceneView’s README describes a community KMP core with platform-specific rendering integrations, and labels its CMP integration alpha with a viewer subset. The shared part is the core; the rendering path differs per platform. Because the project is community maintained, its status can change, so check the README before each decision.
How the two compare
| Aspect | Google Filament | SceneView |
|---|---|---|
| Stated purpose | Real-time, physically based renderer | Community KMP core with platform-specific rendering integrations |
| Documented targets | Android, iOS, Linux, macOS, Windows, WebAssembly | Per-platform integrations; no single target list stated in the README |
| Compose Multiplatform integration | Not stated in the Filament repository | Alpha, viewer subset |
| Native or shared rendering | Native library; a binding or integration is needed per target | Shared core; rendering path per platform |
| Shader and asset workflow | Not stated in the Filament repository | Not stated in the README |
| Input and lifecycle integration | Not stated in the Filament repository | Not stated in the README |
| Profiling and frame-time tooling | Not stated in the Filament repository | Not stated in the README |
| Maintenance status | Repository maintained by Google | Community project; status can change |
Can you reach a steady 60 fps on every platform?
Nothing in the cited documentation measures a frame rate for a 3D game built this way. Treat 60 fps as a target until your own measurements show it. The arithmetic is simple: 1,000 ms ÷ 60 ≈ 16.7 ms. Each frame must finish its simulation, render submission, GPU work, and presentation within that budget on the slowest device you intend to support.
An average frame rate can hide the failures players notice. Consider a hypothetical run of 1,000 frames in which 950 take 14 ms and 50 take 50 ms. The average works out to about 63 fps, yet 5% of frames miss the budget by a wide margin. These figures are illustrative arithmetic, not measured data, but they show why frame-time distribution matters more than the mean.
Best Value
What each 60 fps claim requires
| Claim | What must be shown |
|---|---|
| “60 fps target” | Nothing measured. Label it as a goal and state the frame budget of about 16.7 ms. |
| “Reaches 60 fps on a named device” | A release build on that physical device, stated graphics settings, a fixed scene, the run length, and frame-time percentiles. |
| “Holds 60 fps on all five targets” | The same test on each target’s device set, with every result reported, including misses. |
| “Runs at 60 fps in the simulator” | A simulator observation only. It does not support a device claim. |
How to define the test matrix before measuring
- Name the five release targets and, for each, the exact device, OS version, or browser you will test.
- Assign one renderer path per target and record which integration it uses.
- Fix a scene workload: draw calls, triangle counts, light and shadow setup, animation, and physics load.
- Fix graphics quality settings and keep them identical across runs.
- Build release configurations and run them on physical hardware.
- Warm up the app, then discard the first seconds before recording.
- Log per-frame times and report the median, the 95th and 99th percentile frame times, and the number of frames over 16.7 ms. Note device temperature or power mode where the platform exposes it.
Architecture: what stays common and what does not
A workable split keeps game rules, simulation, and data in common code, and isolates the rendering surface behind an interface. KMP lets you start this way and move code into shared source sets gradually. Platform-specific pieces are written with expect/actual declarations or native APIs, and they sit behind the same interface.
| Layer | Shared in common Kotlin | Platform-specific work |
|---|---|---|
| Game rules and simulation | Yes, when written in pure Kotlin | None, unless a platform service is used |
| Data and configuration | Models and parsing logic | File access, behind expect/actual or an interface |
| Input | Input events and mapping to game actions | Touch, mouse, keyboard, and controller sources |
| Rendering | Scene description and an abstract renderer interface | Renderer binding, GPU surface, and draw submission per target |
| Menus and HUD | Compose Multiplatform UI | Only where a platform hook is needed |
| Project structure and dependencies | Shared Gradle configuration | Xcode on a Mac for iOS; per-target run configurations |
The sources do not show a single graphics backend that covers all five targets. If your renderer differs per platform, your team owns one integration per target and must test each one.
Quick Recap
Before you commit
- Which renderer path covers each of your five release targets, and is it documented by its maintainers or shown only in a community project?
- If you need 3D inside a Compose screen, does the integration you chose support that use at a stability level you can accept?
- Have you chosen a device floor and a frame-time threshold in advance, so the 60 fps claim has a defined test behind it?
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




