Skip to content

Core concepts

A quick tour of the ideas you’ll meet everywhere in insomni. Each is a one-paragraph summary that links to its full page under Core Renderer.

  • Renderer2D — owns the device, the camera uniforms, the single instance storage buffer, and the per-frame encode. One call, render(layers), draws a whole frame: it uploads every layer’s pack into one buffer and runs the merged draw commands in a single render pass (opaque first, then transparent). Build one with the createRenderer(gpu, canvas) factory. See Renderer & frame loop.

  • Layer — the universal drawable: a bag of shapes backed by one UberPack, plus a coordinate space and a little metadata (zIndex, cache, visible, label). Layers are dynamic by default (re-uploaded each frame); content that rarely changes can be retained (renderer.retainLayer, a stable GPU buffer) or baked (cache: "always" / cacheLayer, a cached RTT texture) so it isn’t re-rasterized every frame. See Layers & groups.

  • Group — a lightweight, shareable transform container. A group holds one Mat3 and an optional parent; a child’s effective transform compounds up the chain. Tag shapes (or a whole layer) with a group and the renderer routes them to a dedicated per-(space × group) camera slot, so mutating group.transform between frames moves the geometry live with no repack. See Groups.

  • Packing — every primitive packs into a single flat instance buffer (UberPack) at a fixed 16-float (64-byte) stride; adjacent instances of the same kind, opacity, and group merge into one DrawCommand. The buffer grows geometrically and is reused frame to frame. See Packing & buffers.

  • Spaces & cameras — each layer declares a LayerSpace of "world" | "ui". world content is camera-transformed (pan / zoom / rotate); ui maps CSS pixels straight to the screen (overlays, text, chrome). Raw device pixels are renderer-internal (backbuffer, scissors, viewports) — author in "ui" and scale by devicePixelRatio yourself for density-aware drawing. The renderer keeps one camera slot per space, and groups add extra slots on demand. See Spaces & cameras.

  • Damage / partial redraw — a persistent backbuffer plus scissored damage regions let the renderer re-rasterize only what actually moved, so idle frames are cheap. Any camera / size / background change demotes to a full repaint. See Damage & partial redraw.

  • OIT transparency — order-independent transparency is on by default via a bounded-K A-buffer, so overlapping translucent shapes blend correctly without manual depth sorting. See Transparency (OIT).

Once these click, the whole API is just: author shapes into layers, optionally tag them with groups and spaces, and call render(layers) once per frame.