Gunnar

mikronova/kyokkou

kyokkou (極光)

極光 — polar light. The aurora. Light created at the extremes.

Stack: Rust · egui · egui_graph · Blender 5.1.1 · FalkorDB

Intent in. Raytraced beauty out.


Sibling projects — shared hardware, independent stacks

All three projects run on the same machine (ThinkPad T14s AMD 360 · gfx1150 · 32 GB shared VRAM). Each project manages its own ROCm stack independently — no project depends on another.

ProjectROCm strategy
text-analysislemonade-sdk bundled ROCm 7 — fully self-contained
klient-t14sinstalls ROCm + HIP system-wide — self-contained installer
kyokkouROCm + HIP inside container — fully isolated

What it is

An intent-driven visual generator. You pick what you want to create. The tool handles ALL Blender settings — materials, lighting, sim params, camera, render quality. One button: Create image or Create animation.

You never touch Blender directly.


Origin

"I want great Blender creations — raytraced god rays, metal and water reflections, fluid animations through pipes, 3D system maps with information flowing as fluid. A Blender setup acting as Grafana, or a render export feeding my Rust egui engine with live system metrics."


Architecture

Rust egui UI (kyokkou)
    → validated scene_config.yaml
        → bpy scene script (one per scene type)
            → Blender headless (container)
                → PNG / EXR / MP4 / glTF
                       ↑
          egui live viewer ←┘

Three layers:

LayerResponsibility
Rust egui UIInput, preview, validation, parameter rescaling, render trigger
scene_config.yamlValidated contract — bpy script trusts this completely
bpy scene scriptOne hand-crafted Blender scene, parameterised from yaml

Fluid strategy

Two distinct methods. Each semantically correct for its category.

MethodWhat it isWhen
Mantaflow LiquidPhysics fluid — splashes, pours, chaosCategory 1 art
Mantaflow GuideDirected flow along a curve — no walls, no leakingCategory 2 & 3 info flow

Guide is the key insight for information flow. The curve is the pipe. No collision geometry → no leaking. The pipe mesh is visual-only — glass tube, conduit, laser channel — zero physics role. The fluid is mathematically steered along the graph edge path. No walls exist, so nothing can leak through them.

This matches the semantics: information doesn't slosh and leak. It travels a path. It has direction and intent. It follows the graph topology.

Speed and colour of each guided flow come directly from edge data — high-traffic connections flow faster, weighted edges glow brighter.


Category 1 — Art scenes

Fluid method: Mantaflow Liquid (physics)
Inputs: Scalars + enums + asset (logo / image)
Validator: Geometry + quality constraints
Preview: Parameter checklist + logo rescale handle
Output: PNG / EXR / MP4

      ╲  │  ╱      
       ╲ │ ╱       
   ─────[◈]─────     ← logo
       ╱ │ ╲       
      ╱  │  ╲      
   ≋≋≋≋≋≋≋≋≋≋≋≋≋     ← fluid

Scenes:

Build this first. One hand-crafted Blender scene. Extract 5–8 parameters.


Category 2 — System topology

Fluid method: Mantaflow Guide (information flow)
Inputs: Structural graph — what connects to what
Validator: Graph structure validator
Preview: egui_graph editor — confirm layout before render
Output: PNG / MP4 OR glTF → egui live viewer

   ●━━━━●━━━━━━━●    line A
        ┃          
   ●━━━━◉━━━●        ← interchange
        ┃          
        ●━━━━━━━●    line C

Each graph edge becomes a bezier curve. Guide flow attaches to the curve. The pipe mesh is purely visual — glass tube around the curve, no physics. Information visibly travels the dependency graph, directed and leak-free.

Input sources:

Graph validator:


Category 3 — Data graphs (cinematic portrait)

Fluid method: Mantaflow Guide (information flow)
Inputs: Property graph — nodes and edges carry real values
Validator: Schema + value range validator
Preview: 2D graph + value→visual mapping config
Output: PNG / MP4 OR glTF → egui live viewer

   ◉━━━━━━◎             ← small
   │╲              
   │  ◉               ← mid
   │    ╲          
   ◎━━━━━◉              ← large

The scene:

Value → visual mapping (configured in egui):

Input sources:

Validator concerns:

Live path: FalkorDB → poll → egui graph viewer live. Blender = the beautiful artifact export.


Category 4 — Physical rack topology

Inputs: Server inventory — rack units, slots, hardware specs, cable routes
Validator: Rack geometry validator (U-count, slot conflicts, power budget)
Preview: egui rack diagram — side-on RU view, confirm layout before render
Output: PNG / EXR / MP4 fly-through OR glTF → egui live viewer

   ╔══════════════╗  
   ║ ▬▬  srvA  ● ║   ← cool
   ║ ▬▬  srvB  ● ║   ← normal
   ║ ▬▬▬ srvC  ● ║   ← hot
   ║ ░░  [empty]  ║  
   ╚══════════════╝  

The scene:

Value → visual mapping (configured in egui):

Validator concerns:

Input sources:


Visual style reference

Network and topology views follow a schematic transit-map aesthetic — lines as routes, nodes as stations, edges carrying weight through thickness and glow intensity. Orthogonal routing, interchange dots, color-coded layers.

   ●━━━━━━━━━━━●━━━━━●    line A
               ┃       
   ●━━━━━━━━━━━◉━━━━━●    line B
               ┃       
               ●           ← interchange

In egui_graph: node size encodes property value, edge thickness encodes relationship weight, color temperature encodes load or state. The Blender export is the cinematic version of the same data.


Scene file format

All egui settings saveable and loadable as a kyokkou scene file — the full UI state: category, scene type, all parameter values, graph layout, value→visual mappings, validator state.

RON — Rust-idiomatic, enums serialize cleanly, comments allowed, readable by power users. Scene files are not machine interchange — readability wins.

// kyokkou scene — art / fluid pipe
(
    category: ArtScene,
    scene_type: FluidPipe,
    metal: Chrome,
    render_samples: 512,
    output_type: Still,
    logo_path: Some("/assets/logo.png"),
    logo_scale: 0.42,
)

Scene files load back into egui state exactly. The bpy script still receives the validated scene_config.yaml — the scene file is the egui side of the contract.


Render backend — bpy in a container

Runtime: Podman. Rust speaks the Podman socket directly via bollard (DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock). No Docker needed.

bpy (Blender as a Python module, official PyPI package) runs inside a custom container. No suitable off-the-shelf image exists. All custom images share the same Ubuntu base + bpy install + Python HTTP agent. The compute layer is the only difference.

Two deployment scenarios

Scenario A — outside (default): Rust egui runs on the host, agent runs in the container. HTTP on localhost:8080 bridges them. Rust lifecycle-manages the container via bollard.

Scenario B — bundled: Rust egui + agent both inside the container. One podman run ships everything. Entrypoint starts the Python agent then exec's the Rust binary. Display forwarded via Wayland socket or X11 socket at runtime.

Images

ImageScenarioGPUDevice passthrough
kyokkou-cpuACPU fallback—
kyokkou-rocmAAMD ROCm/HIP/dev/kfd, /dev/dri
kyokkou-cudaANVIDIA CUDA--gpus all
kyokkou-bundled-cpuBCPU fallback—
kyokkou-bundled-rocmBAMD ROCm/HIP/dev/kfd, /dev/dri
kyokkou-bundled-cudaBNVIDIA CUDA--gpus all

kyokkou-cpu / kyokkou-bundled-cpu are always the fallback. ROCm 7.2.2 + HIP confirmed working on host (klient-t14s) — reference for the ROCm images.

Target: Blender 5.1.1 · bpy 5.1

Hardware: kyokkou is not tied to any specific GPU. Cycles runs on whatever the host has — AMD ROCm, NVIDIA CUDA/OptiX, Apple Metal, or CPU fallback. Current development machine is a ThinkPad T14s with Radeon 890M (ROCm), but a 4090 or any CUDA card drops in without code changes — just pass the right device through to the container.

bpy is a Python C extension that IS Blender internals — scene graph, materials, node trees, render engine — loaded directly into a Python process. The only way to drive it from Rust is via an HTTP agent in the same process as bpy. The agent calls bpy functions directly in shared memory.

What the container solves:

Volume mounts set at container creation:

HTTP agent (stdlib only, no framework) inside the container:

EndpointBehaviour
GET /health200 when bpy is initialised and ready
POST /renderAccepts yaml body, calls bpy, blocks until done, returns 200
POST /uploadReceives texture bytes, writes to /in/textures/, calls bpy.data.images.load()

Rust owns the container lifecycle via bollard — speaks the Podman socket directly, no CLI dependency (DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock).

Dependencies: bollard 0.17 · tokio 1 (full) · reqwest 0.12 (json)

Startup: inspect via bollard → running: proceed / stopped: start / missing: create then start. Poll GET /health until 200, then unlock render button.

Render: validator green → Rust posts yaml to POST /render → tokio task awaits 200 → reads from /tmp/kyokkou/out → displays in egui preview. egui thread never blocks.


The parameter validator

Every input has a type, range, and cross-parameter constraints. egui shows live checkbox state — green / yellow / red. Render button locked until all checks pass.

Examples:

The bpy script trusts the yaml. egui guarantees correctness.


egui_graph — first-class editor


What bpy sees — after validation passes

scene_type: clouds_metal_logo
metal: chrome
cloud_type: cumulus
logo_path: /assets/logo.png
logo_scale_scene_units: 0.42
logo_position: [0.0, 0.0, 1.2]
camera_focal_mm: 35
render_samples: 512
output_type: still
output_path: /renders/out.png

Live egui path (no Blender)

FalkorDB (Cypher) → poll → parse property graph
    → egui_graph live viewer → values drive visuals
        → "Export to Blender render" → fires bpy scene

egui = live Grafana-like viewer. Blender = beautiful artifact on demand.


Build sequence

  1. One hand-crafted bpy scene — beautiful, hardcoded
  2. Extract 5–8 parameters → scene_config.yaml
  3. CLI: kyokkou render --scene fluid_pipe --config scene.yaml
  4. Rust egui UI — writes yaml, live validation
  5. Validator logic — per parameter, cross-constraints
  6. Add scene types one by one

Start here: one beautiful fluid pipe scene. Hand-craft it. Make it stunning. Extract the parameters. Everything else follows.

Files

docker/
src/
.gitignore
BACKLOG.md
Cargo.lock
Cargo.toml
README.md
design.md

Newest commits

1591e15b9833Update scenes, renderer, docker and docs2026-07-02
013ed093c7f4initial test2026-05-02
006317d16694initial2026-04-07
88b203a0b6acdone2026-04-02
4f76949e06e8first commit2026-04-02