Giter Site home page Giter Site logo

foresightminingsoftwarecorporation / bevy_polyline Goto Github PK

View Code? Open in Web Editor NEW
152.0 5.0 35.0 24.14 MB

Polyline Rendering for Bevy

Home Page: https://crates.io/crates/bevy_polyline

License: Apache License 2.0

Rust 89.90% WGSL 10.10%
bevy-plugin bevy rendering polyline

bevy_polyline's Introduction

Bevy Polyline

High performance instanced polyline rendering for bevy

nbody_demo.mp4

crates.io docs.rs CI Bevy tracking

About

Bevy Polyline is a plugin for Bevy Engine that adds instanced rendering of Polylines. The plugin comes courtesy of Foresight Mining Software Corporation who sponsor its creation and maintenance. Special thanks to mtsr for the initial implementation of this plugin.

Implementation

Bevy Polyline closely mimics the way Meshes are rendered in Bevy. It works internally by passing a minimal Instance Buffer to the GPU, containing only the line segment endpoints and then completely determines all vertex positions within the vertex shader, such that the triangles form a line that is rotated around it's longitudinal axis to face towards the camera. The shader code is based on this great tutorial by Rye Terrell.

Usage

See the minimal example for basic usage.

Transform

Polylines respect positioning through GlobalTransform, so you can position them directly, or through the use of a Transform hierarchy.

PolylineMaterial

Currently the main way of customizing a Polyline is by changing the PolylineMaterial, which, as can be seen above, has fields for width, color and perspective. width directly correlates to screen pixels in non-perspective mode. In perspective mode width gets divided by the w component of the homogeneous coordinate, meaning it corresponds to screen pixels at the near plane and becomes progressively smaller further away.

Aliasing/shimmering

Bevy Polyline does some work to reduce aliasing, by implementing the line thinness fade from https://acegikmo.com/shapes/docs/#anti-aliasing. But if your line segments are very short, you will still see shimmering, caused by triangles < 1 pixel in size. This can be reduced by only adding segments of a minimum length.

Performance

Due to instancing, Bevy Polyline only makes one drawcall per PolyLine, one for the line segments and one for the miter joins (not currently enabled). We've tested the nbody demo at some 500 lines with 4096 segments being updated every frame (in addition to a 4th order Yoshida integrator for the nbody simulation) running at 60fps. There is still some room for performance optimization, particularly reducing to one drawcall per Polyline (depending on join and cap types) and more efficient updates of the instance buffer for updated lines.

Bevy Version Support

We intend to track the main branch of Bevy. PRs supporting this are welcome!

bevy bevy_polyline
0.12 0.8
0.11 0.7
0.10 0.5, 0.6
0.9 0.4
0.8 0.3
0.7 0.2
0.6 0.1

Community Support

If you want some help using this plugin, you can ask in the Bevy Discord at https://discord.gg/bevy.

License

bevy_polyline is free and open source! All code in this repository is dual-licensed under either:

at your option. This means you can select the license you prefer! This dual-licensing approach is the de-facto standard in the Rust ecosystem and there are very good reasons to include both.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

bevy_polyline's People

Contributors

aevyrie avatar bonsairobo avatar dgriffin91 avatar donvlouss avatar icesentry avatar irate-devil avatar julianruiseco avatar loispostula avatar mattatz avatar mtsr avatar nicopap avatar shatur avatar therawmeatball avatar wizzeh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bevy_polyline's Issues

Instanced rendering not the fastest

According to some comments and https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau, instanced rendering of small meshes is not the fastest and can be outperformed by one or more larger draw calls.

I've tested a simple 4 vertex index buffer alternative in this branch, but it's not any faster and possibly slower. This was already suggested to be slower by cwfitzgerald/DrawCallYeeter, who tested this in another case.

The current method using the vertex-buffer-as-instance-buffer, storing [p0, p1, p2, ..] with an instance stride of 1 point, only works well for instanced rendering. For non-instanced a 4x (indexed) or 6x (non-indexed) duplication of points is required.

One alternative is to store the points in a SSBO and manually index into it using instance_index = vertex_index / 6. The indexing into coefficients in the shader can be done using coefficient_index = vertex_index % 6.

One downside is SSBOs have a WGPU default limit of 128MB, which means we can store at most 128MB / 12 bytes segments per SSBO (without querying for SSBO size limit). So we'd need to render in chunks for anything larger than that.

We should also test whether doing the above SSBO solution is faster with or without an index buffer. A single index buffer of say 8096 can be reused for every line and chunk, which is something at least.

Lines with perspective disappear at certain camera angles

With perspective: true, moving the camera close to lines or in certain angles makes them disappear. I'm not exactly sure if they're being culled or if something else is going on:

2023-05-04.21-32-09.mp4

(Don't mind the strangely uncropped window)

Feature request: Depth test bypass

Hi. Thank for the great library.

I've been using bevy_polyline for a debugging library. And one feature I would really like is the ability to draw some polyline on top of everything else.

Given that often time, in a debugging context, you'll have your debug lines inside or very close to polygons, they are often occluded. Therefore, it would be very useful to be able to tell bevy_polyline to draw some lines on top of the rest of the geometry.

It would probably work by uploading a toggle (or a value saying how closer to the camera the line should be drawn) to the shader through a uniform (I'm very new to shader programming). On the user side, it would just be an additional field to the PolylineMaterial.

I'm going to experiment with this, see if I can come up with something clean enough to open a PR.

OrthographicCameraBundle does not render

When rendering using OrthographicCameraBundle nothing renders to the screen. From what I can tell, this used to work. Maybe an issue specific to a newer version of bevy.

color not rendering sometimes from one side

image

I'm creating rainbows and from one side they're perfect. From the other side if your up close they render colorful, and then if you're further away they are fine. I figured out the problem is something to do with the bevy atmosphere plugin. I thought I would just drop a note here to say thankyou for the lines (I'm planning on a lot of rainbows!!!) and to de-puzzle someone else that stumbles across this combo.

Feature request: Defining polyline starts and ends

Hey there - I'm building an L-system visualizer with bevy_polyline. With one component, I get great fps with a single polyline, even with complex shapes

image

However, the way that polyline is defined, I am unable to define start or end areas. To attempt to solve this on my own, I figured I could use child components whenever my L-system branched.

image

I did this by building a Vec<Vec<Vec3>> of lines, where each line would contain a new PolylineBundle. While it works, it is very slow. Looking at the docs, it appears there is 1 draw call per line which makes sense.

Is there a way to define multiple lines within a single PolylineBundle?

I am unsure if this is a goal of this crate, so I understand if this is not considered.

Dotted line

It would be great to add an option to create a dotted line.

Line is blinking if perspective set to false

์ œ๋ชฉ์—†์Œ3

While above gif seems line randomly blinks because of low frame, actually it blinks periodically and short term.

Below is the spawn of line with set off perspective since default value of perspective is false.

PolylineBundle {
        transform: Transform::from_xyz(0., 3., -10.),
        polyline: polylines.add(Polyline {
            vertices: vec![Vec3::new(2., 2., 0.), Vec3::new(-2., -2., 0.)],
            ..default()
        }),
        material: polyline_materials.add(PolylineMaterial {
            color: Color::WHITE,
            ..default()
        }),
        ..default()
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.