How far can you simplify a 3D tool without hiding too much power?


I started Petunia3D with a small idea: an editor for making low-poly assets fast — sketch the silhouette, generate the mesh, do UVs, paint. Without needing to master a giant DCC. But the further I got into the interface, the more one question grew: how far can you hide complexity before you start limiting the user?

That tension runs through the whole project. The user should not need to understand the editor’s internals just to extrude a shape. At the same time, if I hide too much, the experienced artist hits the ceiling in the first week.

The problem with the UI stack

The obvious choice in Rust would be egui — mature, immediate mode, widely used. And I would not rule it out. But some of the problems I ran into may not be in the library itself, but in the attempt to make it behave like interfaces built on a different philosophy. Forcing an immediate-mode toolkit to look like a traditional dockable editor creates a layer of workarounds that later charges dearly in maintenance.

Before migrating everything, I prefer the opposite path: use egui closer to what it was designed for, lean better on the ecosystem’s auxiliary libraries, and measure how far we get that way.

And the experimental alternatives?

At the same time, I would not stay only with the well-known solutions. Rust has several new UI projects — Floem, GPUI, Slint, Iced — and even when they are not ready to carry the whole project, they often bring ideas that solve specific parts of the problem. A layout approach here, a reactivity model there.

Among these options, I would not choose by feature count alone. The most mature one carries a bigger architecture than I need; the experimental ones fit better the separation I want between the 3D viewport and the interface, but I would not put them on the critical path yet.

The separation that matters

What interests me most today is treating the 3D renderer and the interface as separate worlds from the start. If the viewport starts knowing UI rules, we create a dependency that is hard to undo later — and that kind of coupling is exactly what kills small editors when they grow.

For V1 I would start with the current stack used the native way, keeping the boundary clean enough to test an alternative GUI later without rewriting the editor.

How I will actually decide

In theory this separation should make everything faster and more maintainable, but I would not consider it settled without measuring: frame time with large scenes, selection and hit-testing cost, behavior on weak hardware. The architecture can look prettier and still be slow — and performance on modest PCs is a requirement, not a bonus.

The next experiment is instrumenting those numbers before any migration. The code is open in the repository.