Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debug Draw #1625

Closed
wants to merge 10 commits into from
Closed

Debug Draw #1625

wants to merge 10 commits into from

Conversation

The5-1
Copy link

@The5-1 The5-1 commented Mar 11, 2021

As suggested by @TheRawMeatball on discord, this PR is to coordinate efforts for a Debug Draw crate.

Primitive shapes for drawing should ideally be supplied by #1621.

The Idea is to have a convenient way to quickly visualize something in the viewport.
Ideally on par with the ease of calling println! but in order to draw visual cues.
The drawing happens in "immediate mode", meaning the lines are removed after a frame.

This requires some discussion on how a robust API should look like.

The current approach is only intended for visual debugging.
Once we establish a crate for a more general drawing solution like the ones from @lassade 's or @Toqozz 's here

Minimal Example:

fn deubg_draw_sample_system(
    mut debug_draw: ResMut<DebugDraw3D>,
) {
    debug_draw.draw_line(Vec3::ZERO, Vec3::new(5.0,2.0,1.0), Color::RED);
}

Working Example:
run with cargo run --package bevy --example debug_draw_3d --features="debug_draw"

The code in question can be seen here.
https://github.com/bevyengine/bevy/pull/1625/files#diff-c501be256b1a5d25b2ea56f6813ba342eef03e471d38e12aab026015f3365bebR17-R35


Some walktrough of the current implementation:

A Resource provides functions to draw lines.
Calling these functions pushes vertices into the resource.
At the end of the frame this vertex data is copied over into a entity's Mesh component while the data on the resource is cleared.
The entity then draws the mesh as per usual.
The Line simply uses the line primitive type rather than drawing nice, anti-aliased lines.
This is most likely sufficient for debugging purposes and keeps the implementation really simple.
Since the data is cleared every frame the lines do not persist (immediate mode debug draw).
I feel this plays quite well with most systems updating every frame anyways.
For other use cases lines with a certain lifetime or persistent ones may be implemented (e.g. using Line structs with a lifetime field).
It should be easy enough to extend the system for these cases and to accept triangles or other primitives as well.

I am not quite sure if my general approach of querying a singular entity to update its mesh is sound.

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use help wanted labels Mar 11, 2021
Cargo.toml Outdated
@@ -51,6 +51,7 @@ bevy_winit = ["bevy_internal/bevy_winit"]
trace_chrome = ["bevy_internal/trace_chrome"]
trace = ["bevy_internal/trace"]
wgpu_trace = ["bevy_internal/wgpu_trace"]
debug_draw = ["bevy_internal/debug_draw"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
debug_draw = ["bevy_internal/debug_draw"]
debug_draw = ["bevy_internal/bevy_debug_draw"]

I think it must be named this, to succesfully compile.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to help. The other crates do not require a bevy_ prefix either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is neccesary here, as you added it to bevy_internal this way:

bevy_debug_draw = { path = "../bevy_debug_draw", optional = true, version = "0.4.0" }

See the bevy_ prefix?
Those that don't need it, also don't have the prefix:

wgpu_trace = ["bevy_wgpu/trace"]
trace = [ "bevy_app/trace", "bevy_ecs/trace" ]
trace_chrome = [ "bevy_log/tracing-chrome" ]

For me applying that change allows cargo to compile, though there are still several compile errors:

  • The With<> I suggested below still needs to be imported.
  • The trait functions in the gizmo file, do not need a pub

But at least it's progress.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After fixing up the example, it also compiles successfully.
(Though I don't know why no Lines are drawn)
debug_lines

Copy link
Contributor

@MinerSebas MinerSebas Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have sent you a PR on your Fork, with all the fixes. The5-1#1

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @MinerSebas .
I merged the PR on my fork and have the same behavior.
Will try and find the bug.

The5-1 and others added 3 commits March 12, 2021 16:44
fix unused returned entity for debug_draw mesh entity

Co-authored-by: MinerSebas <[email protected]>
Fix unnecessary DebugDraw3DComponent query.

Co-authored-by: MinerSebas <[email protected]>
@lassade
Copy link
Contributor

lassade commented Mar 12, 2021

Hi you may want to also checkout my gizmos crate https://github.com/lassade/bevy_gizmos, its already usable, it's missing one thing or other;

Features

  1. Immediate mode
  2. Billboard
  3. Filled gizmos

@The5-1
Copy link
Author

The5-1 commented Mar 12, 2021

Hi you may want to also checkout my gizmos crate https://github.com/lassade/bevy_gizmos, its already usable, it's missing one thing or other;

Features

1. Immediate mode

2. Billboard

3. Filled gizmos

Thanks, I added the repos to the initial post.
Your crate definitely looks more sophisticated than my quick attempt here.
Will have a look at it and see what the minimum required code to draw something looks like.
So far the samples seem relatively complex, but you can likely wrap that in a simple call.

My wish is to ultimately have the ease of use of a println!.

@lassade
Copy link
Contributor

lassade commented Mar 12, 2021

Thats the ahole point of my crate, but it also needed to be non intrusive, this means using only Res<Gizmo> and also removing any expensive debug code that might be generating the debug lines, thats why gizmo.draw(enable_mask, |_| { ... }) which compiles down to if enable_mask & gizmo.mask != 0 { ... } allowing the debug lines or gizmos to be removed on the fly

@The5-1
Copy link
Author

The5-1 commented Mar 12, 2021

Fixed the bug and added a complete sample:
run with cargo run --package bevy --example debug_draw_3d --features="debug_draw"

@The5-1
Copy link
Author

The5-1 commented Mar 12, 2021

@lassade I am having issues running your crate.
There are local paths for bevy and flycam in the cargo.toml.
I tried to replace them with their respective master branches and 0.4.0 to no avail.
What commits/tags would I need?

@lassade
Copy link
Contributor

lassade commented Mar 12, 2021

Sorry for that, can run with my animations bevy branch, here https://github.com/lassade/bevy/tree/animations (I still didn't update the 0.4 branch), you can ping me on the discord server as well my nick is also lassade there;

@The5-1
Copy link
Author

The5-1 commented Mar 14, 2021

@lassade your minimal call to draw something seems to look like:

    gizmos.draw(|context| {
        // If gizmos are disabled this won't run
        let points = generete_your_expensive_spline(too_many_points);
        context.line_list(point);
    })

In my implementation so far it looks like this:

    debug_draw.line(vec3_a, vec3_b, Color::ORANGE );

I am in favor of my shorter syntax.
As I said my intent is to have something trivially usable like println.

Your crate already supports more shapes and filled drawing and has the potential for a general drawing crate that is not limited to only debugging but may ultimately be useful for actual, pretty drawing in release builds or the editor.

If we want to get something usable for (with the sole purpose of quick debugging) we could merge this PR right now.
Then once we establish a more general drawing solution like @lassade 's or @Toqozz 's then we could rework this debug-draw crate to actually use the proper drawing supplied by yours.

So how to proceed with this?
Maybe some input from @alice-i-cecile or @cart

If we opt for the current solution I would:

  • add some more primitives like circle, aabb and sphere
  • include this crate in the default features. It's pretty much perfect for beginners to have available out of the box.

@alice-i-cecile
Copy link
Member

add some more primitives like circle, aabb and sphere
@The5-1 have you seen #1621? I expect that this PR should build off of those once that PR is merged in :)

Then once we establish a more general drawing solution like @lassade 's or @Toqozz 's then we could rework this debug-draw crate to actually use the proper drawing supplied by yours.

I like this approach. Small PRs with basic useful functionality is a good way to go.

@aevyrie
Copy link
Member

aevyrie commented Mar 14, 2021

Yeah, I'd love your input on the primitives, especially if we want to use them in this PR eventually.

@The5-1
Copy link
Author

The5-1 commented Mar 14, 2021

Then the next steps are:

@Toqozz
Copy link

Toqozz commented Mar 15, 2021

I'm not sure if this is bevy territory, but Vulkan has the lineWidth parameter (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPipelineRasterizationStateCreateInfo.html), which would be nice to expose somehow. D3D doesn't have this though, as fair as I know.

My thoughts are if we can (without huge effort) have line thickness options then we should, as they're useful in 3d for assessing the depth of the line. This also makes the drawing a little better for prototype art, but that's mostly a moot point.

@Neo-Zhixing
Copy link
Contributor

I'm not sure if this is bevy territory, but Vulkan has the lineWidth parameter (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPipelineRasterizationStateCreateInfo.html), which would be nice to expose somehow. D3D doesn't have this though, as fair as I know.

My thoughts are if we can (without huge effort) have line thickness options then we should, as they're useful in 3d for assessing the depth of the line. This also makes the drawing a little better for prototype art, but that's mostly a moot point.

I do not believe that wgpu-rs supports lineWidth. I know that gfx-rs has it for supported targets but it'll require some work to get this implemented as an extension in wgpu-rs.

@mockersf mockersf added the S-Pre-Relicense This PR was made before Bevy added the Apache license. Cannot be merged or used for other work label Jul 17, 2021
@alice-i-cecile alice-i-cecile added the S-Needs-Design This issue requires design work to think about how it would best be accomplished label Sep 22, 2021
@alice-i-cecile
Copy link
Member

@The5-1, can you comment in #2373? We've since relicensed to MIT + Apache, and I'd like to either ensure that this can be picked up or close it out.

@The5-1
Copy link
Author

The5-1 commented Apr 25, 2022

@alice-i-cecile Ah! I didn't see my name in the list so I figured it's fine, Went ahead and gave my OK too ;)

@alice-i-cecile alice-i-cecile removed the S-Pre-Relicense This PR was made before Bevy added the Apache license. Cannot be merged or used for other work label Apr 25, 2022
@alice-i-cecile
Copy link
Member

Awesome, thank you! Yeah, you didn't have any merged PRs at the time so it wasn't automatically added :)

@alice-i-cecile
Copy link
Member

@The5-1 this is super cool; are you interested in continuing this work now that we have more merge bandwidth? If so, rebasing would be appreciated so we can review more effectively.

@alice-i-cecile alice-i-cecile added X-Controversial There is active debate or serious implications around merging this PR S-Blocked This cannot move forward until something else changes and removed S-Needs-Design This issue requires design work to think about how it would best be accomplished labels May 2, 2022
@The5-1
Copy link
Author

The5-1 commented May 2, 2022

@alice-i-cecile I have not dabbed into Bevy since half a year (was waiting for progress on the UI front), so I wound need to refresh my knowledge and get the hang of what changed with the new versions. If any of the other posters/interested on this topic are more up to speed, they can also have a go at it (if that even is technically possible, given it is my PR).

But otherwise, I am keen on getting back into it, so fixing this could be a good re-entry point ;)
I just can't make any guarantees on when I get to it.

@alice-i-cecile
Copy link
Member

Sounds good! I expect #rendering-dev on Discord will have plenty of feedback and thoughts.

If any of the other posters/interested on this topic are more up to speed, they can also have a go at it (if that even is technically possible, given it is my PR)

Yep, they can either make a PR to your branch, or if you're particularly overwhelmed, create a new PR from a fork off your branch, preserving your commit history (and credit).

@james7132
Copy link
Member

Closing in favor of #6529. Going to try to get this resolved before 0.11 releases.

@james7132 james7132 closed this Mar 8, 2023
cart added a commit that referenced this pull request Mar 20, 2023
# Objective
Add a convenient immediate mode drawing API for visual debugging.

Fixes #5619
Alternative to #1625
Partial alternative to #5734

Based off https://github.com/Toqozz/bevy_debug_lines with some changes:
 * Simultaneous support for 2D and 3D.
 * Methods for basic shapes; circles, spheres, rectangles, boxes, etc.
 * 2D methods.
 * Removed durations. Seemed niche, and can be handled by users.

<details>
<summary>Performance</summary>

Stress tested using Bevy's recommended optimization settings for the dev
profile with the
following command.
```bash
cargo run --example many_debug_lines \
    --config "profile.dev.package.\"*\".opt-level=3" \
    --config "profile.dev.opt-level=1"
```
I dipped to 65-70 FPS at 300,000 lines
CPU: 3700x
RAM Speed: 3200 Mhz
GPU: 2070 super - probably not very relevant, mostly cpu/memory bound

</details>

<details>
<summary>Fancy bloom screenshot</summary>


![Screenshot_20230207_155033](https://user-images.githubusercontent.com/29694403/217291980-f1e0500e-7a14-4131-8c96-eaaaf52596ae.png)

</details>

## Changelog
 * Added `GizmoPlugin`
 * Added `Gizmos` system parameter for drawing lines and wireshapes.

### TODO
- [ ] Update changelog
- [x] Update performance numbers
- [x] Add credit to PR description

### Future work
- Cache rendering primitives instead of constructing them out of line
segments each frame.
- Support for drawing solid meshes
- Interactions. (See
[bevy_mod_gizmos](https://github.com/LiamGallagher737/bevy_mod_gizmos))
- Fancier line drawing. (See
[bevy_polyline](https://github.com/ForesightMiningSoftwareCorporation/bevy_polyline))
- Support for `RenderLayers`
- Display gizmos for a certain duration. Currently everything displays
for one frame (ie. immediate mode)
- Changing settings per drawn item like drawing on top or drawing to
different `RenderLayers`

Co-Authored By: @lassade <[email protected]>
Co-Authored By: @The5-1 <[email protected]> 
Co-Authored By: @Toqozz <[email protected]>
Co-Authored By: @nicopap <[email protected]>

---------

Co-authored-by: Robert Swain <[email protected]>
Co-authored-by: IceSentry <[email protected]>
Co-authored-by: Carter Anderson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Blocked This cannot move forward until something else changes X-Controversial There is active debate or serious implications around merging this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants