godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.05k stars 65 forks source link

Allow changing the line width of 3D gizmos #9299

Open passivestar opened 2 months ago

passivestar commented 2 months ago

Describe the project you are working on

Any 3d game

Describe the problem or limitation you are having in your project

This ladder has a CollisionShape3d in front of it that's almost entirely invisible:

image

Changing the gizmo color to black makes it a tiny bit better but it's still hard to see:

image

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add an editor setting that allows changing the width of the lines to make them more visible

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Could either be a value in pixels or a dropdown with some options (narrow, regular, thick)

image

If this enhancement will not be used often, can it be worked around with a few lines of script?

I don't think so

Is there a reason why this should be core and not an add-on in the asset library?

Basic editor UX

Calinou commented 2 months ago

The issue is that hardware line widths above 1 pixel aren't reliably supported by all hardware (in both OpenGL and Vulkan), so you need to draw thick lines using screen-aligned quads or triangle strips as proposed in https://github.com/godotengine/godot-proposals/issues/6151. This is also slower than using hardware line drawing, so performance will suffer for complex gizmos (such as trimesh collision shapes). On the bright side, triangle strips make it possible to draw antialiased lines without needing to use any antialiasing method in the 3D viewport.

One alternative is to draw several thin lines with a slight offset, which could also address https://github.com/godotengine/godot-proposals/issues/3322 by drawing these lines in a different color (so you can see all gizmos regardless of the background color). This is what the orange 3D selection box uses. It's noticeable if you get really close to the lines, but otherwise it looks fine at a distance.

As a workaround, enable Half Resolution in the 3D viewport's Perspective menu. This will make gizmos appear thicker because the viewport resolution will be lower.

passivestar commented 2 months ago

interesting, I wonder what approach blender uses

Screenshot 2024-03-14 at 21 06 05
Calinou commented 2 months ago

interesting, I wonder what approach blender uses

Blender's viewport is OpenGL, so if it used hardware line drawing, lines would always be 1 pixel thin on AMD and Intel GPUs. Last time I checked, only NVIDIA has reliable support for thick hardware lines on desktop platforms (up to 5 pixels IIRC).

passivestar commented 2 months ago

Also just found out that it draws it semi-transparent when unselected, maybe if it instead drew a brighter version on selection it would mitigate the visibility issue

Regular (the line color is set to #000F):

image

Selected:

image
Calinou commented 2 months ago

Also just found out that it draws it semi-transparent when unselected, maybe if it instead drew a brighter version on selection it would mitigate the visibility issue

If you draw a brighter line when it's selected, it will become less visible if the background is bright. Increasing opacity doesn't have this caveat in comparison.

passivestar commented 2 months ago

If you draw a brighter line when it's selected, it will become less visible if the background is bright. Increasing opacity doesn't have this caveat in comparison.

Yeah that's definitely true.

When you compare two approaches it's the question of "do we want to sacrifice the visibility of unselected gizmos or the visibility of selected gizmos"

Could also make both colors configurable. If that was the case I'd probably personally just set both selected and unselected to #000F because it's a priority for me to be able to see lines and I'd just rely on other UI hints to see what's selected. But I'm not sure what's the best out-of-the-box solution for everyone here tbh

Maytch commented 2 weeks ago

Toggles on the editor window for visibility against dark/light would be awesome, as well as the ability to make the shape a solid transparent shape.

EiTaNBaRiBoA commented 2 weeks ago

Also in 2D it would be nice. If there could be an line a line size to increase the thickness of colliders, UI edit lines to be able to see them

Calinou commented 1 week ago

@passivestar I salvaged a PR that provides a setting for line drawing width: https://github.com/godotengine/godot/pull/91171

However, it won't work on macOS and iOS due to a lack of driver support, so a fallback would be needed there (e.g. by drawing lines twice with slightly different offsets). I'm not sure what would be a low-code solution for this that doesn't involve doubling up draw calls though.

Ideally, we could generalize https://github.com/godotengine/godot/pull/83895 for all kinds of line drawing, but there might be obstacles to this (such as CPU usage when having lots of lines). @clayjohn Do you think this would be feasible?

Also in 2D it would be nice.

The issue is that in 2D, thick line drawing will make lines scale with viewport zoom. This is often not desired as it'll mess with your ability to perform edits at high zoom levels while still being able to see what's going on.

Something like https://github.com/godotengine/godot/pull/91171 would need to be supported in 2D first before this can be considered, but remember that thick hardware line drawing depends on vendor support.

passivestar commented 1 week ago

@Calinou alternatively could draw semi-transparent faces for selected collision shapes to make them easier to see. This will also allow you to see better where they intersect other geometry

...Although that might not work well for collision shapes generated from mesh because they'll have a matching shape...

clayjohn commented 1 week ago

Ideally, we could generalize godotengine/godot#83895 for all kinds of line drawing, but there might be obstacles to this (such as CPU usage when having lots of lines). @clayjohn Do you think this would be feasible?

Yes, I think it could be feasible. It would be a pain to update all of our gizmos to use a custom shader like this. But it would allow us to support wide lines on the broadest amount of hardware