Fury3D: a WIP, vibe-friendly 3D engine
I’m picking up Fury3D again — the small C++17/OpenGL engine I started almost a decade ago. The goal this time is narrower and more honest: a WIP, vibe-friendly engine for making small 3D games, one where most of the heavy lifting is done by an AI CLI and I stay in the loop as the reviewer.
The idea
Take a study-grade renderer (deferred light-pre-pass, shadows, glTF, post-FX) and bolt on the things a vibe workflow actually needs: a JSON-described pipeline, a Lua-scripted editor with ImGui, an offline CLI for headless asset conversion, and a text-driven scene format you can diff and review. No 200k-line runtime, no editor-as-product, no hidden state — just enough engine that an AI can read it end-to-end and an AI (or I) can author content for it.
Features
- C++17 + OpenGL 3.3+ core profile, with explicit per-draw state so passes don’t leak
GL_BLENDinto each other. - JSON-configurable render pipeline — every pass, shader variant, and uniform lives in a
.jsonnext to the runtime. - HDR pipeline with
RGBA16Fcomposite + ACES tonemap, plus a data-driven post-process chain (SSAO, SSR, FXAA, CRT, ACES) that orders itself bystage. - Deferred light-pre-pass renderer with cascaded shadow maps for the sun and 2D / cubemap shadow maps for spot & point lights.
- glTF 2.0 importer (vendored
tinygltf) with PBR→Lambert mapping, skins, animations; FBX routed throughFBX2glTFso the engine never links the FBX SDK. - Skinned meshes +
Animator— joint-driven bone matrices, state weights/speeds/wraps/cross-fades, console overlay for joint debugging. - Transparent rendering — back-to-front alpha base + per-light additive draws, depth-write off, premultiplied-alpha forward shader.
- OcTree spatial structure with default-cube auto-wrap and a Profiler spatial section.
- ImGui + ImGuizmo editor — Scene Inspector, Content Browser, Node Properties, viewport gizmo, native file dialogs, persisted dock layout.
- Offline
furyCLI —fury convert gltf|fbx|scene,fury info,fury exec(headless Lua),fury render-mesh; the editor’s default save form is LZ4-compressed.bin, with.jsonfor human diffs. - Lua 5.4 + sol2 scripting bridge, with a deliberately small binding surface (only what the editor exercises) so the engine API can keep refactoring.
Full architecture rundown lives in docs/ARCHITECTURE.md.
The vibe-coding bit
I’m writing it with M3 and GLM to get the bones down, then mostly K3 — it’s multimodal, easier to buy than GLM, and surprisingly powerful. K3 drives the bulk of the work; M3/GLM still help when I want a second opinion on a refactor.
That said: code is vibed and reviewed by me. Even with a strong model, code review is essential — I still have to keep an eye on the machine-made decisions. The KISS-by-default style, the openspec workflow under openspec/changes/, and the “spec first, then code” loop exist precisely so I can diff a change against intent instead of vibes. Specs that pass verification get carried over; reproductions live in the agent’s scratchpad, not in the repo.
WIP. Things will move, things will break, things will get renamed. If you want to peek under the hood, it’s all there → github.com/sindney/fury3d.




