Skip to content

What the Flatland pipeline owns in a frame, and when that ownership is the right trade-off.

Flatland combines a sprite-batching group (SpriteGroup) with an orthographic camera, global uniforms, post-processing and render-target output.

For setup, the render loop, post-processing, and disposal, see Set up a Flatland scene. For every constructor option and method, see the Flatland API reference.

With Flatland, you call render(renderer) to synchronize the scene and draw it through Flatland’s camera and render pipeline. Your application schedules each call, whether it uses an animation callback or React Three Fiber.

With SpriteGroup, you add the group to your own scene and render that scene with your camera. Choose it when you want to manage the camera and draw sequence yourself. Choose Flatland when you want those operations managed together.

The Flatland Pipeline — one frameleft → right: each stage hands the frame to the nextECS systemstransformSyncSystemtransforms → batchanimationSystemframe cursorsbatchSystemgroup by materiallightSystemLight2D → LightStorePre-passesLightEffect onlyOcclusionPasscaster silhouettesSDFGeneratorJFA → SDFForwardPlusLightingtile-bin lightsMain sceneSprite2DMaterialdraw call / batchMaterialEffect chainper-instance:tint · outline · dissolveNormalMapProviderLightEffectDefault · SimpleDirect · Radiancereads tiles + SDFPost-processPassEffect chain — insertion orderposterizelcdGridvignette… more effects
Per-frame render pipeline

Each render() call updates global uniforms and sprite batches before drawing. Flatland also checks the render-surface dimensions. Camera and lighting resize work runs when those dimensions change or a sizing change requires synchronization.

Flatland also tracks the render surface. It reads the active render target size, the canvas drawing buffer for its pixel-perfect camera, or the active canvas viewport for a regular camera, and updates its managed camera when that size changes. Camera synchronization needs no separate resize listener, but your application must still resize the renderer when its canvas size changes. React Three Fiber handles renderer resizing for its Canvas.

Surface-dependent GPU resources use physical pixels. Device pixel ratio relates physical drawing-buffer pixels to logical CSS pixels; a render-target texel is one pixel in the target texture. globals.viewportSize reports the renderer’s logical size, paired with globals.pixelRatio. See pixel-perfect rendering for camera and drawing-buffer sizing.

The default camera, PixelPerfectCamera, selects an integer scale and centers the resulting viewport inside the surface. Unused pixels form bars around the centered viewport, and resolvedAspect reports the ratio of the viewport rather than of the whole surface.

Supplying your own camera preserves its authored visible bounds, called its frustum, rather than reframing it. resolvedAspect reports that camera’s actual frustum ratio.

add() dispatches on type, so the caller does not choose a destination. Sprite2D instances go to the internal SpriteGroup and become batch candidates, and Light2D instances register with the lighting system. Anything else is a plain Object3D that joins the internal scene directly.

Flatland connects global uniforms to a sprite’s material when add() places it. This holds regardless of when the sprite joins the scene, so every sprite reads the same global uniform values, including time.

globals.time is undefined by default, and Flatland accumulates elapsed seconds automatically. Assigning it a number overrides that: shaders read the value you set instead, and Flatland stops advancing it.

A LightEffect is the lighting pipeline a Flatland instance runs each frame. An attached instance belongs to the Flatland that holds it. Replacing the active effect, or clearing it, disposes the effect’s GPU resources before detaching it. Attaching it again produces a fresh init → resize → update sequence. A handle the effect produced while attached must not be used once the effect is detached.

dispose() releases the private renderer entity-component-system (ECS) state, sprite batches, render pipeline and pass effects. This specialized renderer runtime grew from Koota , whose typed traits, structure-of-arrays storage, queries and systems made the design possible. Koota remains the recommended general-purpose ECS for application and gameplay state.

Without an active render pipeline, Flatland draws its scene directly. After you add a pass effect, the next render() call creates the automatic pipeline if needed. The pipeline renders the scene to an offscreen target and applies the enabled effect functions to its output.

The pipeline initializes during the next render after a pass is added. A later pass change rebuilds the pass sequence before drawing.