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

World-space grid #872

Open
emilk opened this issue Jan 23, 2023 · 4 comments
Open

World-space grid #872

emilk opened this issue Jan 23, 2023 · 4 comments
Labels
🟦 blueprint The data that defines our UI 🧑‍🎨 Design Requires UX/UI designer input 🔺 re_renderer affects re_renderer itself user-request This is a pressing issue for one of our users

Comments

@emilk
Copy link
Member

emilk commented Jan 23, 2023

The 3D spatial view should have an option to show the X^Y, X^Z, and Y^Z planes as grids, as common in 3D apps.

@emilk emilk added the 🔺 re_renderer affects re_renderer itself label Jan 23, 2023
@chengguizi
Copy link

Hi Rerun team, I am also interested in this feature. Showing a grid to tell the scale of the world is pretty useful feature!

@nasteyi
Copy link

nasteyi commented Mar 13, 2024

Hi!
+1, it would be very useful to have a 3D floor in a global coordinate system with adjustable cell size depending on the specifics of data you have to work with.

@Wumpf Wumpf added the user-request This is a pressing issue for one of our users label Apr 17, 2024
@Wumpf Wumpf added the 🟦 blueprint The data that defines our UI label Jul 9, 2024
@Wumpf
Copy link
Member

Wumpf commented Aug 1, 2024

There's three intertwined items we have to figure out for this:

  • what should it look like (out of the box at least) and how does it behave under zoom
  • what should be configurable
  • how do we render it in a clean fashion

References:

Both of these have a whole bunch of things in common

  • very thin, ui-constant sized lines (lines don't get smaller in the distance)
    • generally try not to get in the way!
  • fading everything but cardinal lines (every tenth line?)
  • fading in the distance

On cardinal lines: The problem mostly arises with zooming out. Fading lines is pretty much a must, otherwise the screen becomes gradually fully opaque no matter how small the lines are. So typically one would just fade everything but every tenth line (configurable?). That introduces a cardinality which likely should be expressed with a slightly different shader and/or thickness. Blender does this really well imho.

Another thing shown here is highlighting for cardinal axis. Blender has this configurable (for all axis independently!) but I'd keep this out for the moment, worth considering adding to the options.

Also seen in the blender clip is fading of the unlimited grid with distance which can be important to avoid artifacts as well. Unity actually just clips the lines off at some point. Which is also perfectly fine as long as the lines stay thin!


Unlike back in the day when this was first logged we now have a system in place for configuring views, and this is a great fit for that, so let's start by what the rough data modelling for this could look like:

table LineGuides3D {
    /// Whether the grid is visible.
    ///
    /// Default is true.
    visible: rerun.components.Visible ("attr.rerun.component_optional", nullable);

    /// The type of the grid.
    grid_type: rerun.blueprint.components.LineGuides3DType ("attr.rerun.component_optional", nullable);

    /// How the grid is oriented.
    orientation: rerun.blueprint.components.PlaneOrientation ("attr.rerun.component_optional", nullable);

    /// How thick the lines should be.
    ///
    /// Default is 0.5 ui unit. TODO: figure out exact value.
    // TODO: should we restrict this to small ui-based values? Scene values might be problematic.
    // TODO: alternatively, don't support this at all? Many professional tools don't seem to bother
    line_thickness: rerun.components.Radius ("attr.rerun.component_optional", nullable);

    /// Grid spacing of one line to the next.
    ///
    /// May differ per direction.
    ///
    /// Default is 1.0 in both directions.
    spacing: rerun.blueprint.components.GridSpacing ("attr.rerun.component_optional", nullable);

    /// Color of the grid lines.
    ///
    /// Default depends on background color
    // TODO: can we do inter-property in a sane way?
    color: rerun.components.Color ("attr.rerun.component_optional", nullable);

    /// Optional center of the grid, only relevant for non-infinite grids.
    center: rerun.components.Position3D ("attr.rerun.component_optional", nullable);

    /// Optional extent of the grid, only relevant for non-infinite grids.
    extent: rerun.components.HalfSize3D ("attr.rerun.component_optional", nullable);
}

enum LineGuides3DType: byte {
    /// A quasi-infinite grid is shown.
    Infinite (default),
    /// A finite grid anchored at a certain position.
    FinitePositioned,
}


enum PlaneOrientation: byte {
    /// A grid is shown in the XY plane.
    Xy (default),
    /// A grid is shown in the YZ plane.
    Yz,
    /// A grid is shown in the XZ plane.
    Xz,
}

Which brings us to the surprisingly hard topic of rendering:

There's Ben Golu's pristine grid shader which is quality-wise perfect (also comes in versions for grid zooming and cardinal line highlighting) and can easily handle all fading out requirements. However, getting intersection with objects (we don't want a plane) can be tricky. And most importantly, all the complexity in it comes from the fact that it's not after constant pixel width lines, which all of the reference examples used:

But there’s a catch. Most example grid shaders, like this one, use screen space width lines. That can be preferred over a texture based grid in a lot of use cases, and honestly probably what most people want. But it’s not what I’m trying to achieve.

That said there's still a lot to be learned from this article regardless!

As long as we use thin constant-pixel-width-lines our line shader may just do the right thing for us.
However, distance fade is still a concern for infinite grid that's hard to address since all lines converge to a solid (likely flickery) color.
For sufficiently thin lines it could be sufficient to have half of them shortened just when we know that they're getting too close together (this may be a shader or just some simple logic upon feeding the line renderer, note this is camera dependent). Questionable if this is quality-wise good enough.

Considerations for using a "shader on the plane" approach instead of a geometry (line renderer) based one

  • much better filter/blending can be achieved easily (see linked blog post above)
    • especially fading becomes easy
  • clean intersection / depth buffer interaction gets hard quickly!
    • possible workaround is to render the line-plane with alpha blending after the background (today background is rendered last). In order to facilitate some degree of interaction with alpha blended objects that render later, depth buffer write stays enabled and pixels that are barely visible are discarded
    • Counter point: Unity just ignores transparent object interaction with the grid!
    • Opaque: image
    • Transparent with alpha=255 (so fully opaque still, but different rendering mode): image
    • this indicates that the grid itself is seen as an object with transparency and Unity doesn't sort order independent transparency, so it can't solve this.
      • I believe if everything else is right, the same compromise is acceptable for us!
  • Potential quality & cpu side perf advantages need to be weighed against added complexity in render pipeline and perf costs on what amounts to almost a fullscreen pass (although technically drawn as a plane, it may fill the entire screen most of the time!)

So what should we do? I'm not sure right now. It's likely worth starting with our line renderer and see how bad it gets before working through an adjusted version of the "pristine grid" shader.

Not supporting world-space line widths seems the right way forward regardless, I don't think there's any practical reason for it.

@Wumpf
Copy link
Member

Wumpf commented Aug 1, 2024

Found blender's grid shader
https://github.com/blender/blender/blob/main/source/blender/draw/engines/overlay/shaders/overlay_grid_frag.glsl
(Don't copy anything as is, it's GPL licensed!)There's interesting things to be learned here - for instance lines are faded in the moment they are apart more than 4 pixels

The fact that there's so much going on in there to get the fading right makes me think more and more that using the general purpose line renderer is a dead end.

@emilk emilk added the 🧑‍🎨 Design Requires UX/UI designer input label Aug 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🟦 blueprint The data that defines our UI 🧑‍🎨 Design Requires UX/UI designer input 🔺 re_renderer affects re_renderer itself user-request This is a pressing issue for one of our users
Projects
None yet
Development

No branches or pull requests

4 participants