-
Notifications
You must be signed in to change notification settings - Fork 366
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
Comments
Hi Rerun team, I am also interested in this feature. Showing a grid to tell the scale of the world is pretty useful feature! |
Hi! |
There's three intertwined items we have to figure out for this:
References:
Both of these have a whole bunch of things in common
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:
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. Considerations for using a "shader on the plane" approach instead of a geometry (line renderer) based one
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. |
Found blender's grid shader 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. |
### Related This is the first half of * #872 The second half is here: * #8234 ### What Implements a "world grid" to be used later in the spatial views of the viewer. Haven't tested yet how suitable this is for 2D views, might need some adjustments. ## Video Youtube unfortunately compresses this a lot and Github doesn't let me upload any significant amount of video (click me) [![youtube video of world grid v1](http://img.youtube.com/vi/Ho-iGdmJi4Q/0.jpg)](http://www.youtube.com/watch?v=Ho-iGdmJi4Q "World Grid v1") ## Screenshots Analytical anti-aliasing (shown is what is supposed to be a 1ui unit == 2pixel wide line): <img width="1215" alt="image" src="https://github.com/user-attachments/assets/702b82ac-2629-4aa5-9304-0cd3c4d87fc5"> Distance has only the cardinal lines (== every tenth line). Those fade eventually as well: <img width="747" alt="image" src="https://github.com/user-attachments/assets/ebe6b2c9-37e5-4406-8d28-5260cf2940d4"> Fading is based on "how many lines coincide here" which makes fading view dependent rather than distance dependent: <img width="439" alt="image" src="https://github.com/user-attachments/assets/9bea7a42-9edc-4a7d-be19-9498a1f29fdf"> (this makes this hopefully robust for many usecases) Grid intersects non-transparent geometry (transparent geometry will be ignored in the future. previous surveying showed that this is common and not a biggy) <img width="426" alt="image" src="https://github.com/user-attachments/assets/19de2cc9-015d-4fdd-a275-096768119a9e"> Grid fades at acute viewing angles (because empirically and unsurprisingly it looks weird if we don't!) <img width="1437" alt="image" src="https://github.com/user-attachments/assets/2a05b8e5-9915-4dda-9a54-4db829e22ac3"> Tested image quality to be satisfying on high dpi (ui unit == 2 pixels) and low dpi (ui unit == pixel). ## How does it work * Draw a large shader generated plane (mostly because setting up vertex buffers is just more hassle 😄 ) * depth test enabled * depth write disabled * premultiplied alpha blend * make sure we draw this after the background (reminder: we first draw solid, then background) * Fragment shader looks at 2d coordinate on the plane and decides how "liney" it is * using screen space derivatives (ddx/ddy) we figure out how far to go on the plane to achieve a certain line thickness * fades: * fade if the line density gets too high * fade if view angle is too acute relative * ... lot's of details documented in the shader code! I considered just drawing a screen space triangle, but drawing a plane that moves with the camera has lots of advantages: * don't have to manipulate depth * faster since early z just works * less thinking required! * don't cover things above the horizon - even if only the grid is visible, less pixels will be shaded ## Known shortcomings * various hardcoded values around how fading works. Tricky to formalize this better, but likely good enough * Doesn't look equally good at all pixel widths, but decent for the range we care * every tenth line is a "cardinal line", that's nice but it stops there - "infinite" amount of cardinal lines would be nicer * Experimented with that but so far didn't get anything that was compelling. Having many order-of-magnitude lines looks way too busy imho, it needs a mechanism that limits that to two. * Blender's 2D view does this really well, but in 3D they only do two cardinals as well. ## Try it yourself Controls: - Space: Pause - G: Toggle camera mode native: ``` cargo run -p re_renderer_examples --bin world_grid ``` web: ``` cargo run-wasm -p re_renderer_examples --bin world_grid ``` ## Backend testing matrix * [x] Metal * [x] Vulkan * [x] WebGL * [x] WebGPU
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.
The text was updated successfully, but these errors were encountered: