Replies: 1 comment 1 reply
I really like Bevy, and proper ECS is generally go things that care about performance should be done, but if bevy-style ECS doesn't require deep internal integration, then leaving it out to be built out as a separate package if desired make sense here. I think the priority here is getting from 0 to 3D as fast and as frictionaless as possible, not getting from 0 to efficient, engine quality 3D state management.
I think graphical concerns only make the most sense. Physics should be outside the remit. It's a 3D graphics library, that a 3D environment one. Extra utility and demo packages can be built separately for physics and things like that.
Bevy does a lot of things right, but if the most basic abstraction of DAG render passes can be done, then v1 could be a DAG with only a fixed stage pipeline offered out of the box.
I don't think so. Users should be managing their usage of 2d/3d drawing themselves, I don't think having the libraries step in to manage that is useful or desirable, though if thought can be given to making it easy to identify where calls originate from (2D/gg or 3D/g3d) then that'll aid in debugging issues when users badly interleave calls and get weird results.
My preference is idiomatic Go. Abstractions are easy to build over the top if people want non-idiomatic styles.
I'd be inclined to lean on the ecosystem alredy being built here and not reimplement things, instead providing demos/example of how to leverage external window management via the gogpu package family.
I think as long as gg render targets can be g3d textures/buffers, and g3d render targets can be gg buffers/textures then you have all you need to combined them.
As my previous answers probably imply, I'm in favour of a tiny, focused core and then building out extensions/support packages on top, so I'd argue to keep scope minimal and focused at first.
I'm not sure this is something that can or shoudl be solved in this. However, ultimately accessibility concerns become addressible by having first-class introspection baked into everything from the start. Apple's accessibility introspection for the UI libs are excellent in terms of the sheer depth of info that can be extracted out of them, and accessibility also ties well into headless testing as it grants multiple additional introspection systems for measuring outcomes.
As above re: introspection. Also in the Quake port I have some headless testing and also image comparison checks.
While I'd lean towards no, asset management in terms of efficient delivery into textures, geometry, etc is quite important and probably shouldn't be an afterthought, so I'd be inclined to bake in from day 1 as retrofitting efficient asset delivery with support packages is probably quite hard without support from the main g3d package.
I'm not much of a 3D programmer, so anything that makes things easy to understand: good documentation, avoidance of jargon in naming conventions, etc are key things for me. Common, but difficult, processes provided as best-effort utility/helper packages to save grunt work for less experienced 3D devs like myself are appreciated so we can spend less time fighting with understanding stuff like setting up orthogonal projections and more time getting straight to the actual problems we want to solve would be a good shout. |
Uh oh!
There was an error while loading. Please reload this page.
RFC: g3d — Pure Go 3D Rendering Library
We're building
gogpu/g3d— a 3D rendering library for Go. Not a game engine. A reusable foundation that game engines, CAD viewers, data visualizers, and AR/VR applications can build on top of.Think Three.js for Go: simple API, powerful rendering, zero opinion about your application architecture.
Why now? We already have the complete vertical stack — shader compiler (naga), GPU abstraction (wgpu with 5 backends), 2D graphics (gg), windowing (gogpu), GUI toolkit (ui). The only missing piece is 3D. Community members like @darkliquid are already building 3D on our wgpu directly (Quake 1 port).
Research
We studied 4 major 3D frameworks at the source code level (all cloned locally):
Full research reports (
3D-*.md) and the ADR (ADR-012-3D-GRAPHICS-LIBRARY.md) are in the repo.The Gap
We analyzed 14 existing Go 3D projects. Every single one has a fatal flaw:
Nobody has zero-CGO + modern GPU (Vulkan/Metal/DX12) + 3D. That's our gap.
Architecture
Not a game engine. A rendering library that engines build on top of:
graph TD subgraph "Community Builds On Top" GE["Game Engines"] CAD["CAD / BIM Viewers"] DV["Data Visualization"] AR["AR / VR"] end subgraph "gogpu Ecosystem" G3D["<b>g3d</b><br/>Scene Graph + PBR + GLTF<br/>Render Pipeline + Cameras + Lights"] WGPU["<b>wgpu</b> (Pure Go WebGPU)"] NAGA["<b>naga</b> (Shader Compiler)"] end GE --> G3D CAD --> G3D DV --> G3D AR --> G3D G3D --> WGPU G3D --> NAGA style G3D fill:#2d5a3d,stroke:#4a9,color:#fff style WGPU fill:#1a3a5c,stroke:#4a9,color:#fff style NAGA fill:#1a3a5c,stroke:#4a9,color:#fffKey Design Decisions
1. Scene graph, not ECS (Three.js pattern). ECS is a game engine concern — 30K+ LOC in Bevy just for ECS. g3d provides a simple Node hierarchy. Community builds ECS on top if they need it.
2. PBR from day one — metallic-roughness workflow (GLTF standard). Not "add PBR later" — it's the default material:
3. Forward rendering first — works on ALL backends including GLES and Software. 3-bucket sorting: opaque (front-to-back), alpha mask, transparent (back-to-front). Deferred rendering as a future option.
4. 4-level draw grouping (Kaiju pattern) — minimizes GPU state changes:
5. GLTF as first-class format — the standard 3D interchange format. Not an afterthought loader, but the primary way to get content into g3d.
6. Standalone — g3d depends on wgpu + naga (down), NOT on gogpu/gg/ui (up). Use it with gogpu, with Ebiten, with your own windowing, or headless.
7. Zero-alloc render path — no GC pressure during frame rendering. Allocations only on scene mutation.
Quick Start Target
About 20 lines for a lit, rotating cube:
Roadmap
Open Questions — We Need Your Input
We're at the early architecture stage where decisions are cheap to change. Once we start coding, it gets expensive. So now is the time to discuss.
Architecture:
Scene graph vs ECS — we're leaning scene graph (Three.js pattern) because it's simpler and g3d is a rendering library, not an engine. But should we include a lightweight ECS from the start? Or provide it as a separate optional package (
g3d/ecs)? Bevy proves ECS works great for games, but adds 30K+ LOC of complexity.Scope boundary — where does g3d end and "game engine" begin? Should g3d include basic physics (raycasting, bounding box collision)? Or is that strictly external?
Render graph — Bevy uses a render graph (DAG of render passes). Three.js doesn't. Should g3d have a configurable render graph, or is a fixed forward pipeline sufficient for v1?
Integration:
Shared DeviceProvider — g3d uses the same
gpucontext.DeviceProviderandwgpu.Deviceas gg (2D). Both renderers share one GPU device. No separategpucontext3dneeded. Any concerns with this approach?API style — Three.js-like (
scene.Add(mesh)) or more Go-idiomatic (functional options, interfaces, builders)?Standalone vs framework — g3d should work without gogpu. But how far do we go? Should g3d include its own minimal windowing for quick prototyping (
g3d.Run(func(r *Renderer) {...}))? Or always require external window management?2D/3D mixing — how should g3d and gg coexist? Shared render target? g3d renders 3D scene, then gg overlays 2D HUD? Or completely separate?
Features:
GLTF priority — should GLTF loading be Phase 1 (people can immediately load existing 3D models) or Phase 3 (after core rendering is solid)?
Animation — skeletal animation from the start, or add later? Many use cases (CAD, data viz) don't need animation. Games do.
Compute shaders — should g3d expose GPU compute for particle systems and terrain generation? Or leave that to direct wgpu usage?
WebAssembly — g3d + wgpu WASM target for browser 3D is technically possible. Should we plan for this from day one (architecture implications)?
What are we missing?
Accessibility — 3D accessibility is an unsolved problem industry-wide. Any ideas?
Testing — how do you test a 3D renderer in CI without a GPU? Headless software rendering? Golden image comparison?
Asset pipeline — texture compression (KTX2/Basis), mesh optimization (meshoptimizer), LOD generation — should any of this be built-in?
What else? — what features, patterns, or concerns are we not thinking about? What would make or break a Go 3D library for your use case?
Your Use Cases
What would YOU build with a Pure Go, zero-CGO 3D library that runs on Vulkan/Metal/DX12/GLES?
Understanding real use cases helps us prioritize. A library for game devs looks different from one for CAD developers.
Repository
The repo is live: gogpu/g3d — README, architecture, and roadmap are there. Code coming soon.
The full ADR (
ADR-012-3D-GRAPHICS-LIBRARY.md) covers all architectural decisions in detail — we can share relevant sections in the comments.This is the time to shape g3d while the architecture is still on paper. We'd love to hear from anyone who has experience with 3D in Go, has opinions about 3D API design, or just wants to build something cool with Pure Go 3D. Every perspective helps — from "I just want a rotating cube" to "I need deferred rendering with compute-based culling."
Don't hesitate to challenge any of our decisions, propose alternatives, or ask questions. We'll respond to everything.
All reactions