Page MenuHome

Blender 2.79 vs 2.8 - Selection is significantly slower in production scenes
Closed, ResolvedPublic

Description

System Information
Operating system: Ubuntu 18.04
Graphics card: GTX 1080

Blender Version
Broken: 41cb5658803bf3b96f18e93c74c6af66ecdb1e83

Short description of error
Viewport Selection is significantly slower in production scenes

Exact steps for others to reproduce the error

  1. Open attached blend file in blender 2.79
  2. select the different cubes
  3. feel how snappy it is
  4. switch to blender 2.8
  5. select the different cubes
  6. notice how it lags.

Event Timeline

Sebastian Parborg (zeddb) triaged this task as Confirmed, Medium priority.

I'm guessing that 2.79 is better at instancing particle geometry. (2.79 also only reports the number of faces on the original particle object while 2.8 reports that the scene has 3,369,273,280 tris).

I should note that the tris in the scene is only part of the actual production scene we had... it actually is over 100,000,000,000 tris... This is not uncommon for us as most of those tris are heavily instanced and the amount of GPU ram required to render the scene was around 2.5gb

We use blender for infrastructure visualisation, such as roads / bridges... which span a very large area. This (and T62512) are both created to help make blender 2.8 usable for our workflow.

Brecht Van Lommel (brecht) raised the priority of this task from Confirmed, Medium to Confirmed, High.Apr 1 2019, 1:51 PM

Seems to most time is spend in drawing the face wires (face_wireframe_pass). There is a huge performance impact between regular drawing and select drawing for the face_wireframe_pass.
Also select drawing uses a geometry shader what is slow. But even when disabling the geometry shader there is a huge performance difference (4x slower).
@Clément Foucault (fclem) do you have an idea?

Major bottleneck is because of the use of ALGO_GL_PICK instead of ALGO_GL_QUERY. I don't know why it was changed (and even removed from the option menu?) but it leads to a major performance drop.

After that there is still a performance difference in this case because the scene is still > 4 time slower to draw in 2.8 and (in my tests) selecting with ALGO_GL_QUERY is more or less 4 time slower in 2.8.

OpenGL Depth Picking was enabled by default, see T59155. The option to turn it off is still there.

Basically everyone at the studio here was alreadying using it, selection without it is too unreliable.

Maybe there's a way to make it faster? I'm not familiar with the implementation details.

Basically it uses glReadPixels for every drawcalls which create a GPU-CPU bubble. This scene has many instances and they are treated as individual objects (hence the slowdown).

Ok, that's pretty terrible. There must be a better algorithm we can find that takes into account depth without doing that for every draw call.

Quickly checked on this and it looks like culling isn't working properly.

There is only a very small region so it should only be reading the buffer for objects directly under the cursor.

Looking in draw_shgroup and it's not culling objects, so all objects in the 3d view cause buffer reads, even if they aren't near the mouse cursor.


@Brecht Van Lommel (brecht) suggests that picking could draw color ID's, clicks after the first hit would skip drawing the previously selected objects - which would allow cycling objects behind the first hit.

This would be much faster but not work for showing objects in the menu, which could still use depth picking.

@Campbell Barton (campbellbarton) I propose this workaround but i'm not 100% sure it will have no impact on all selection modes.

diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 6c3e05912b0..fc9d0eb6af3 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -479,7 +479,14 @@ static void gpu_select_load_id_pass_nearest(const DepthBufCache *rect_prev,
 bool gpu_select_pick_load_id(uint id)
 {
   GPUPickState *ps = &g_pick_state;
+
   if (ps->gl.is_init) {
+    if (id == ps->gl.prev_id) {
+      /* No need to read if we are still drawing for the same id
+       * since all these depth will be merged / deduplicated in the end. */
+      return true;
+    }
+
     const uint rect_len = ps->src.rect_len;
     glReadPixels(UNPACK4(ps->gl.clip_readpixels),
                  GL_DEPTH_COMPONENT,

That said I fixed the culling issue in rB905f2d84. The other issue regarding culling in this scene is that the instances doesn't seems to get culled.

So just to be clear, this is an optimization for instancing case where you can have multiple objects with the same selection id drawn one after another. It looks correct to me.

I guess it's a workaround in the sense that it's a good optimization for the current algorithm, but the entire algorithm would have to be different to support efficient selection of many individual objects. No reason not to commit it now I think.

Much better! But It's still something like 1,000 times slower than 2.79 in the example scene provided, resulting in ten seconds of 100% GPU utilization to switch selection between the two cubes, and then grabbing one and moving it around is similarly slow, where the operations are almost instantaneous in 2.79.

I wouldn't call this issue completely resolved.

In the examples I've seen the issue has always been in scenes with something like an instanced particle system that results in on the order of 10,000 "objects" in the scene. Is there an opportunity to optionally filter such things out in selection, like adding them to the Object Types Visibility filters somehow?

Thanks for all the developer work so far, It has improved, but not to the level that it should be.

I would like you to test with the slowdown scene attached and see if this scene is acceptable by your standards for artists to work with. Compare this to how 2.79 interacts.

This scene, was based off a production scene and isolated to just the particle system. There was about 3-5x the complexity with the full scene.

I am sorry that I have reopened the bug, but with the high impact it has to workflow, it is not appropriate to call this done.

@Gavin Scott (Zoot) reported on blender chat that recent changes to draw manager did improve the situation in his case. @Carlo Andreacchio (candreacchio) can you confirm it has?

Can confirm the fix on my machine, seems like it is back to 2.79 levels. Thanks for all your help!