bevyengine / bevyengine/bevy

Geometric primitives in UI (canvas / gizmo equivalent)

Open
#20,787 1 comment 5 reactions 0 assignees View on GitHub
A-UI C-Feature D-Complex S-Needs-Design X-Contentious
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## What problem does this solve or what need does it fill?

There are a number of use cases for drawing geometric primitives within a UI context. This includes things like lines, curves, polygons, and so on. For example, a Blender-style node graph needs a way to draw quadratic splines.

Bevy already has the ability to draw arbitrary meshes in a 2D or 3D context, but what it doesn't have is the ability to do so in a UI context, that is, as part of a UI hierarchy using `UiTransform`.

Although there are various third-party crates for doing this, as well as some fairly complex ways of doing this (Custom SDF shaders, rendering to an off-screen buffer, synchronized gizmos), what is lacking is a simple means to do this in vanilla Bevy.

## What solution would you like?

Bevy already has various flavors of UI node: `Node`, `ImageNode`, `ViewportNode`, `Text` and so on. What I propose is to add a new type of node, `Mesh2DNode`, or perhaps `Mesh2DUiNode`. (Bevy uses the convention that the suffix `Node` indicates an entity meant for drawing in UI contexts, but this term is highly overloaded.)

This new node would be somewhat equivalent in functionality to `Mesh2D`, but would use the `UiTransform`. For now, this would only support 2D meshes; a 3D version is conceivable (for things like drawing 3D icons in a UI), but has additional complexities.

It should support both triangle and line drawing modes.

Interaction with layout: because layout sets the global UI transform, the position of the mesh should naturally be set to the appropriate position determined by the node's layout properties.

The question, then, is how to treat the layout size (width and height). Most likely, we should treat it similarly to how we treat images: we have an enum of scaling options in the node. One option might be to set the transform such that the coordinates (-1, -1 to 1, 1) cover the entire node rectangle. Alternatively, I think that in many cases people will want to work in pixel coordinates, which means that the node's width and height are ignored, and only the mesh vertex coordinates are used. This will require some design work.

We can determine the "auto" size of the mesh by computing the AABB, but this may not be meaningful depending on the scaling options.

Other node properties such as border and padding would likely be ignored for this node type.

## What alternative(s) have you considered?

Previously I did this using a custom SDF shader, but it has numerous complexity issues.

Contributor guide

Open the contributing guide

Research direction

Start by reviewing Bevy's existing UI node types, Mesh2D, and UiTransform to understand how drawing and layout currently work. The issue leaves scaling, coordinate conventions, automatic sizing, and layout interaction open; done would require an agreed design supporting 2D triangle and line meshes in the UI hierarchy.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend, game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.