Blender 2.8: 3D Viewport performance issues (Cycles, Eevee, Workbench)

Hi,

I would like to start a discussion about 3D Viewport performance issues in Blender 2.8 (or newer version). I found some issues - mainly in scene with a lot of particles with dupli-objects. I have some ideas, but I need help how to fix it.

3D Viewport performance issues:

1) Cycles renderer: scene->camera resolution is changed for each sample (in Session::update_scene()) – BlenderCamera rewrites width and height in blender_camera_sync(…)
2) Cycles renderer: “Updating Camera Volume” issue for none volume scene when lot of objects/particles is used (in Scene::device_update()) – there is for loop over all objects (include dupliobjects) in Camera::device_update_volume() for each movement in 3D Viewport
3) Cycles renderer: extreme calling of BlenderSync::sync_data() for each movement in 3D Viewport – If some shader in the scene uses object_dependency then 3D viewport is very slow
4) Cycles, Eevee, Workbench: depsgraph iterator removes and recreates all dupliobjects/particles – object_dupli/make_duplis is called everytime for each movement in 3D Viewport

3D Viewport performance issues – how to fix it?:

Add 1) blender_camera.cpp -> void blender_camera_sync(…):

cam->width = width; // bcam->full_width;
cam->height = height; //bcam->full_height;

Add 2) camera.cpp -> void Camera::device_update_volume(…):

  // Add checking of use_volumes in the scene
  KernelIntegrator* kintegrator = &dscene->data.integrator;
  if (!kintegrator->use_volumes) return; 

  // Add openmp
  # pragma omp parallel for
  for (size_t i = 0; i < scene->objects.size(); ++i) {...}

Add 3) blender_session.cpp -> BlenderSession::synchronize(…):

  // Add checking of user settings in 3D viewport panel
  If (GUI_3D_VIEWPORT_PANEL->CHECKBOX_SKIP_SYNC_DATA) sync->sync_data(…)

Add 4) object_dupli.c -> ListBase *object_duplilist(…):

 // Add cache of duplilist for object
 ListBase* duplilist = BKE_object_cache_duplilist_get(ob);
 if (duplilist == NULL) {
    duplilist = MEM_callocN(sizeof(ListBase), "duplilist");
    ...
 }
 return duplilist;

Thanks.
Milan

5 Likes
  1. Is it changed for every sample, or just the first few samples as it renders progressively higher resolutions at sample 1? And if so, why is that a performance issue?

  2. Good suggestion, we can indeed do this only when there are volumes and also use parallel_for.

  3. object_dependency no longer exists in the latest version of the code, this should be fixed already.

  4. This code could indeed be optimized. Caching on the Blender side would make sense, though of course adds memory usage as well. Alternatively we could find a way to do partial updates here so only changed objects need to be iterated over, and the caching happens on the Cycles / Eevee side.

1 Like
  1. Yes it is for all samples - There is calling const_copy_to (KernelData->GPU) for every sample.
  2. Could I make a patch?
  3. object_dependency looks fine in B2.9. But BlenderSync::sync_data calls depsgraph iterator (and other synchronizations) everytime when view is changed - what do you think about checkbox in panel which disables this BlenderSync::sync_data?
  4. Is there some flag (in object or in depsgraph) how could be detect the object changes?
1 Like
  1. Ok, then we need to figure out why exactly that happens, since the actual size is clearly not changing sample to sample.
  2. Yes.
  3. No, we should not add options for this but solve it in a way that is automatic.
  4. No, this requires deeper design changes to the depsgraph.
1 Like

I’ve committed a fix for 1).

For 4) with Cycles I guess this happens when the camera is locked to the viewport (and so there is an object change detected) or it is the overlay engine that is looping over duplis rather than Cycles itself.

6 Likes
  1. I have uploaded a patch: D8261
4 Likes