Kotlin Multiplatform + WebGPU

Prism Engine

A modular, cross-platform 3D game engine. One Kotlin codebase for Desktop, Web, iOS, Android, and Native — powered by WebGPU via wgpu4k.

View on GitHub Get Started

Material Presets

Cook-Torrance BRDF with GGX NDF, Smith-GGX geometry, and Fresnel-Schlick reflectance. Five material presets — Gold, Chrome, Worn Metal, Ceramic, and Obsidian — each with distinct metallic and roughness properties.

Drag to orbit · Use the tabs to switch scenes.

Everything you need for 3D

Prism provides a complete engine stack — from math primitives to ECS to GPU rendering — all shared across every platform.

V

Math Library

Vec2/3/4, Mat3/4, Quaternion, and Transform with operator overloads. Inline value classes for zero-overhead abstraction.

E

Entity-Component-System

World, Entity, Component, and System with query-based iteration. Built-in TransformComponent, MeshComponent, and RenderSystem.

R

wgpu4k Renderer

WebGPU-backed PBR pipeline with WGSL shaders, Cook-Torrance BRDF, HDR rendering, and tone mapping. Metal, Vulkan, DX12, WebGPU.

P

PBR Materials & IBL

Cook-Torrance BRDF (GGX NDF, Smith-GGX, Fresnel-Schlick), CPU-side IBL (irradiance + prefiltered env + BRDF LUT), HDR + Khronos PBR Neutral tone mapping.

S

Scene Graph

Node hierarchy with MeshNode, CameraNode, and LightNode. Parent-child transforms propagate automatically.

C

Compose Integration

Embed 3D surfaces in Jetpack Compose Multiplatform UIs. MVI architecture with Store, State, and Events.

P

Native Surfaces

PrismSurface with suspend factory across JVM (GLFW), iOS (MTKView), Android (SurfaceView), macOS (GLFW + AppKitView), Flutter, and WASM (Canvas).

I

Input System

Cross-platform keyboard, mouse, and touch abstractions. InputManager dispatches events uniformly on every target.

A

Asset Management

glTF 2.0 loader with GLB binary parsing, PBR texture support, and ECS instantiation. Platform file I/O via kotlinx-io.

Modular by design

Each module has a single responsibility. Depend on only what you need.

prism-math              Vector/matrix math, transforms
  └─► prism-core        Engine core, subsystems, game loop
       ├─► prism-renderer    wgpu4k PBR pipeline + WGSL shaders
           ├─► prism-scene       Scene graph — MeshNode, CameraNode, LightNode
           ├─► prism-ecs         Entity-Component-System, query iteration
           └─► prism-assets      glTF 2.0 loader, asset pipeline
       ├─► prism-input       Cross-platform input
       └─► prism-audio       Audio engine (stub)

prism-renderer + prism-core
  └─► prism-native-widgets   Platform surfaces — GLFW, MTKView, SurfaceView, Canvas/Wasm
       ├─► prism-compose     Compose Multiplatform 3D surface + MVI
       └─► prism-flutter     Flutter plugin — PrismRenderView, engineHandle pattern, dart:ffi for native, @JS() for web

Bindings
prism-js       @JsExport → .d.mts → Dart @JS() bindings  (Kotlin/Wasm)
prism-native   @CName → libprism_api.h → dart:ffi bindings (Kotlin/Native — macOS, iOS, Linux, Windows)
prism-ios      iOS XCFramework umbrella — import Prism from Swift  (Kotlin/Native → XCFramework)

Demo & Consumer
prism-demo-core              Shared PBR scene — glTF 2.0, IBL, ECS instantiation
  ├─► prism-flutter-demo   Flutter demo — PrismEngine, PrismRenderView, glTF asset loading, all platforms
  ├─► prism-android-demo   Android standalone demo app
  └─► prism-ios-demo       iOS demo app (Xcode, links prism-ios XCFramework)

Simple from every language

Prism exposes a clean, idiomatic API in each platform's native language — no boilerplate, no glue code, just the engine.

Kotlin · JVM / Android
import com.hyeonslab.prism.core.Engine
import com.hyeonslab.prism.core.EngineConfig
import com.hyeonslab.prism.ecs.World
import com.hyeonslab.prism.ecs.components.TransformComponent
import com.hyeonslab.prism.math.Vec3
import com.hyeonslab.prism.scene.Scene
import com.hyeonslab.prism.scene.MeshNode
import com.hyeonslab.prism.scene.CameraNode

// Create engine and ECS world
val engine = Engine(EngineConfig(targetFps = 60))
val world  = World()
val entity = world.createEntity()
world.addComponent(entity, TransformComponent(position = Vec3(0f, 0f, -5f)))

// Scene graph: mesh node + camera
val scene = Scene("main")
val mesh  = MeshNode("helmet")
val cam   = CameraNode("cam")
scene.addNode(mesh)
scene.activeCamera = cam

// Query state
println("dt: ${engine.time.deltaTime}")
Swift · iOS · macOS
import Prism

// Create engine and ECS world
let engine = Engine(config: EngineConfig(targetFps: 60))
let world  = World()
let entity = world.createEntity()
world.addComponent(entity: entity,
    component: TransformComponent(position: Vec3(x: 0, y: 0, z: -5)))

// Scene graph: mesh node + camera
let scene = Scene(name: "main")
let mesh  = MeshNode(name: "helmet")
let cam   = CameraNode(name: "cam")
scene.addNode(node: mesh)
scene.activeCamera = cam

// Query state
print("dt: \(engine.time.deltaTime)")
TypeScript · JavaScript · Web
// prism-sdk.d.mts ships alongside prism-sdk.mjs for full TS type coverage
import {
  prismCreateEngine, prismEngineGetDeltaTime, prismDestroyEngine,
  prismCreateScene, prismCreateMeshNode, prismCreateCameraNode,
  prismSceneAddNode, prismSceneSetActiveCamera,
  prismNodeSetPosition, prismSceneUpdate,
  prismDestroyNode, prismDestroyScene,
} from './prism-sdk.mjs';

// Create engine and scene graph
const engine = prismCreateEngine('MyApp', 60);
const scene  = prismCreateScene('main');
const mesh   = prismCreateMeshNode('helmet');
const cam    = prismCreateCameraNode('cam');
prismSceneAddNode(scene, mesh);
prismSceneSetActiveCamera(scene, cam);
prismNodeSetPosition(mesh, 0, 0, -5);

// Render loop
prismSceneUpdate(scene, prismEngineGetDeltaTime(engine));
console.log('dt:', prismEngineGetDeltaTime(engine));

// Cleanup
prismDestroyNode(mesh); prismDestroyNode(cam);
prismDestroyScene(scene); prismDestroyEngine(engine);
Dart · Flutter · iOS · Android · macOS · Web
import 'package:prism_flutter/prism_sdk.dart';

// Create engine and ECS world
final engine = Engine(EngineConfig(targetFps: 60));
final world  = World();
final entity = world.createEntity();
world.addComponent(entity, TransformComponent(position: Vec3(0, 0, -5)));

// Scene graph: mesh node + camera
final scene = Scene('main');
final mesh  = MeshNode('helmet');
final cam   = CameraNode('cam');
scene.addNode(mesh);
scene.activeCamera = cam;

// Query state
print('dt: \${engine.time.deltaTime}');

Write once, render everywhere

Prism targets every major platform through Kotlin Multiplatform and wgpu4k's WebGPU abstraction.

Platform Backend Status
JVM Desktop (macOS) Metal via wgpu4k + GLFW Working
JVM Desktop (macOS) Metal via wgpu4k + Compose/AWT Working
Web (WASM/JS) WebGPU Working
iOS Metal via wgpu4k + MTKView Working
macOS Native Metal via wgpu4k + GLFW Working
Android Vulkan via wgpu4k Working
JVM Desktop (Linux) Vulkan via wgpu4k + GLFW Planned
JVM Desktop (Windows) DX12/Vulkan via wgpu4k + GLFW Planned
Flutter (iOS/Android) Platform channels + native rendering Working
Flutter Web WebGPU via HtmlElementView + Kotlin/WASM Working
Flutter macOS Direct C API (@_silgen_name) + PrismNative.xcframework · progressive glTF texture loading Working
Flutter Desktop (Windows, Linux) Dart FFI → libprism.so / prism.dll Planned

Progress

Prism is under active development. Here's where things stand.

M1

Triangle on screen

JVM Desktop with wgpu4k

M2

Rotating cube

Camera, depth buffer, transforms

M3

Lit cube

Materials, directional lighting, WGSL shaders

M4

ECS-driven rendering

World, Entity, Component, System pipeline

M5

Compose integration

Embedded 3D in Compose Desktop via MVI

M6

Web/WASM

WebGPU rendering in the browser

M7

iOS native

MTKView + wgpu4k, Compose iOS demo

M7.5

PrismSurface + macOS native

Suspend factory, GLFW window, drag-to-orbit

M8

Android support

Vulkan via wgpu4k, SurfaceView + Choreographer

M9

PBR materials

Cook-Torrance BRDF, IBL, HDR tone mapping

M10

glTF asset loading

glTF 2.0 meshes, materials, textures, ECS instantiation

M11

Flutter integration

Platform channels, native rendering, and Flutter Web via Kotlin/WASM

M12

Auto-generated bindings

prism-js: @JsExport → .d.mts → Dart @JS() bindings · prism-native: @CName → libprism_api.h → dart:ffi bindings

M13

Flutter macOS

FlutterPlatformView + direct C API (dart:ffi) + PrismNative.xcframework · Metal rendering, drag-to-orbit, progressive glTF texture loading

M14

Generalized Flutter plugin

prism-flutter-demo consumer module · engineHandle pattern across all platforms · 20+ unit tests across KMP + Dart

Up and running in minutes

1 Build wgpu4k dependencies from source

# Three forked repos must be published to Maven local in order.
# Pinned commits are in gradle/libs.versions.toml.

git clone https://github.com/hyeons-lab/webgpu-ktypes.git
cd webgpu-ktypes && ./gradlew publishToMavenLocal && cd ..

git clone https://github.com/hyeons-lab/wgpu4k-native.git
cd wgpu4k-native && ./gradlew publishToMavenLocal && cd ..

git clone https://github.com/hyeons-lab/wgpu4k.git
cd wgpu4k && ./gradlew publishToMavenLocal && cd ..

2 Clone and build Prism

git clone https://github.com/hyeons-lab/prism.git
cd prism
./gradlew build

3 Run the demo

# JVM — GLFW window, Metal on macOS (DamagedHelmet glTF)
./gradlew :prism-demo-core:jvmRun

# JVM — Compose Desktop with embedded 3D + PBR sliders
./gradlew :prism-demo-core:runCompose

# macOS native binary
./gradlew :prism-demo-core:runDebugExecutableMacosArm64

# Web — Kotlin/WASM + WebGPU (serve build/dist/wasmJs/developmentExecutable/)
./gradlew :prism-demo-core:wasmJsBrowserDistribution

# iOS — build XCFramework, then open prism-ios-demo/ in Xcode
./gradlew :prism-ios:assemblePrismDebugXCFramework

# Android — open prism-android-demo/ in Android Studio
./gradlew :prism-android-demo:assembleDebug

# Flutter — iOS, Android, macOS, or Web
cd prism-flutter-demo/example
flutter pub get
flutter run -d macos   # or: ios  android  chrome