pfx

Got questions or doubts? Ping me on Discord

What it is for

One engine for the live frame, the offline render and the rest of a game

Both frames, one material

A live renderer with shadows, baked light, TAA, text drawn from vector outlines, effects and dynamic resolution, and a GPU path tracer for stills, clips and the light bake. Both paint with the same physically based material, the bake hands path-traced light to the live frame, and live ambient occlusion and contact shadows ground what rests on the floor.

120 fps, your call

pfx aims at 120 fps, 8.33 ms a frame. VRR (adaptive sync) is on or off, on by default, and the frame rate is a 60 fps cap, a 120 fps cap, Uncapped or Auto. A game starts Uncapped; the editor times its first 60 frames and picks Auto if their median misses 8.33 ms, Uncapped if it doesn't. Auto aims at 120 and settles to a steady lower rate when a scene can't hold it.

Size, measured

An empty shipped game is 33.7 MB with its content, against Godot's 73.5 MB and Bevy's 106.6 MB. The domain code pfx needs (the denoiser, the Sobol sampler, LZ4, JPEG, the resampler) is ported into it, not linked.

Against other engines

One tool, the whole game

One tool, pfx, and a set of library crates a game links. It builds scenes from recipes, edits them in its own editor, plays them with a game's WebAssembly module, and runs the physics, sound, input and Steam a game needs.

Who it's for

Rust developers making 3D games or flat 2D arcade games who want the frame, the render, the editor and the rest of a game from one engine they can read end to end, and app makers who want their interface drawn on the GPU. Generic by design: no game keeps its names, values or assets in pfx; each game owns its content.

pfx's neutral desk scene, path traced and denoised: a wooden desk in a beige room with a white lamp column, a colour chart, a chrome ball, a red box and a white card labelled Plate, a shelf on the wall above casting a soft shadow.
Path traced3840×2160 Samples32 Time3,250 ms Ray querieson

Inside the engine

What each part does today

1

The path tracer

pfx-trace renders stills, clips and the light bake on the GPU. It traces with hardware ray queries wherever the device offers them (Vulkan, DX12, Metal on Apple Silicon) and with its own BVH elsewhere, samples with Cycles' tabulated Sobol sequence, and stops each pixel when it has converged. Past four lights it picks one per bounce through a light tree ported from Cycles.

4K workshop still
5,969 ms
128 lights, 4K
4.8 s
More on Tracer Method: docs/trace.md Method: docs/trace-lights.md
The desk scene split down the middle: on the left, labelled 8 SPP, RAW, the path tracer's grainy output after 8 samples a pixel; on the right, labelled PFX-DENOISE, the same frame clean.
2

Its own denoiser

pfx-denoise is Intel Open Image Denoise 2.5.1's RT filter ported to wgpu compute: a traced colour with its albedo and normal go in, the clean colour comes out, equal to OIDN's own output to about 1e-5, so a final stops at 16 to 64 samples a pixel and a draft at 6 to 12.

4K frame
274 ms
Against OIDN
≈ 1e-5
Method: docs/denoise.md
The flat 2D pass on a dark background: two long diagonal streams of orange, red and pale blue particles, about twenty thousand in all.
3

The flat 2D pass

Sprites, text and particles for 2D games and overlays, laid out once and scaled to any screen, from a 4K monitor to the Steam Deck's 1280×800. Under the swarm test's load it takes 0.36 ms of GPU at 4K.

Shots
2,000
Particles
20,301
GPU at 4K
0.36 ms
Method: docs/measured.md
pfx gui on a new game made by pfx new: the outliner on the left lists the scene's objects, lights and materials; the viewport in the middle shows the pfx mark and wordmark standing on a grid with the move gizmo on them; the inspector on the right shows the selected group's position, rotation and scale; a scale bar sits beside the axes; the log at the bottom says the scene opened with 4 objects, 10 materials and 1 light.
4

The editor

pfx alone opens the window and pfx <file.pitofx> opens that document in it: an outliner, the live viewport with gizmos and picking, an inspector, a TOML panel with highlighting and checks at line and column, a log and a traced preview, on one undo history. F5 plays the open scene as a game in the viewport, with a game's WebAssembly module in pfx's sandbox, and F8 puts the editor back exactly where it was. Its egui crates are reusable on their own.

Layer of cells
100 × 100
Opens, debug
97 ms
Adds, release
0.2 ms
More on Editor Method: docs/editor.md
5

Recipes and .pitofx documents

A .pitofx is pfx's own file for scenes, recipes and models: TOML inside, each chunk checksummed and compressed with LZ4 on its own, so a reader decodes only the chunks it needs. A recipe document holds the recipe, every file it reads, its built glTF and the scene built from it, so an unchanged document opens without a rebuild.

pfx build builds a recipe headless into a GLB and a scene, the same bytes on every OS. People edit a document in the editor's inspector or its TOML panel; scripts and agents edit it with pfx set and pfx get by dotted key, which write the edit and a fresh build back in one atomic replace. Other tools exchange glTF with pfx through pfx import and pfx export.

Car-sized model, warm
3.4 ms
Cold
7.9 ms
The GLB, warm
4.2 ms
Method: docs/pfx-file.md Method: docs/recipes.md
6

Scenes diff like code

A .pitofx is compressed, so plain git diff says only Binary files differ. Run pfx git setup once per clone, or let pfx new run it inside a git repository, and git diff, git log -p and git show print it as TOML: one changed value is one line, entries keep a fixed order so saves don't churn, and a packed mesh or image is one line with its size and CRC-32, listed without decompressing it. Merges stay binary.

Setup, per clone
1 command
A packed file in the diff
1 line
Decompressed to list it
0 bytes
More on Git diffs Method: docs/git.md
7

The rest of a game

Everything around the frame ships in the same workspace, each a crate a game links by tag.

  • Physics Rigid bodies, character controllers and world queries, with fluid, rope, flocks and wind.
  • Sound Live mixing, decoded streams and a deterministic mixdown; adaptive music whose stems follow a live intensity and move between sections on the bar or the beat.
  • Input Keyboard, mouse and controllers behind one action map, with glyphs, rumble and recording.
  • Arcade kit Shots, emitters, a spawn director and input journals.
  • Mods Sandboxed, deterministic WASM components, metered by fuel and capped in memory; subscribed Steam Workshop items load beside the local ones.
  • Steam Achievements, stats, Cloud saves, the overlay, leaderboards, lobbies and Steam Input.
  • Film Films rendered offline from a game; pfx film cuts between scenes with a dissolve, push or whip, under a true-peak ceiling measured as ITU-R BS.1770-4 defines it.
  • Asset sources pfx asset fetches HDRIs, textures and models from CC0 sources and your accounts, refuses licences you have not allowed, and pfx credits lists what a scene uses.
A game made with pfx new, in its own editor: cargo run --release -- edit.

Ported in, not linked

The domain code pfx needs lives inside it

  • the denoiser Intel Open Image Denoise 2.5.1
  • the Sobol sampler and the light tree Cycles
  • ambient occlusion XeGTAO
  • contact shadows, the lens flare and the lobes Filament
  • LZ4 lz4_flex
  • JPEG zune-jpeg
  • the cubic resampler kira

Build on pfx

pfx is open source under the AGPL-3.0: free for open-source projects, learning and hobby work. Read it, fork it, and send issues and pull requests on GitHub. Closed products and services built on pfx take a licence: free under $200k of yearly revenue plus funding, Indie and Pro above it.

© Catalin Ilinca, AGPL-3.0-only, with licences for closed products; releases up to 3.1.1 remain MIT. The PITO MD name, the pfx name and its logo are © Catalin Ilinca, all rights reserved.

Every picture and clip on this page is pfx's own, rendered or captured from its neutral scenes and licensed with its code (pfx's NOTICE.md); the pfx gui and game-editor clips were recorded by pfx from its v3.0.1 tag, the terminal clips with prec, the loops encoded with pito-codecs and the charts drawn with pito-compare from the numbers pfx v3.1.2 measures. Type: Exo 2 by NDISCOVER ( SIL Open Font License 1.1 ) and JetBrains Mono by JetBrains ( SIL Open Font License 1.1 ), from pfx's theme.