Slicer / Slicer

Multi-platform, free open source software for visualization and image computing.
https://www.slicer.org
Other
1.7k stars 549 forks source link

Improve rendering speed of many markups #5398

Open lassoan opened 3 years ago

lassoan commented 3 years ago

3D view updates are slower than they should be. For example:

Need to test and optimize performance after Slicer switched to VTK9.

Steps to reproduce

Expected behavior

Rendering should be much faster (nearly 60fps) when rotating a 3D view.

Environment

lassoan commented 2 years ago

Selecting visible points is still a performance bottleneck a RelWithDebInfo build shows that about 50% of time is spent in Update() of this filter when rendering 300 lines in the 3D view.

vtkFastSelectVisiblePoints is a huge improvement over vtkSelectVisiblePoints in that the Z buffer is only computed once per rendering. However, considering how little the filter does (checks if a point is visible using the z buffer and it only copies the point to the output if it is visible), it is very inefficient due to the VTK filter overhead (check if the input is up-to-date, delete and recreates output points, cells, 4 pointdata arrays, etc.). For markups that contain only a small number of points (e.g., lines) this overhead is very significant.

Probably the best would be to add a method that computes visibility of points and stores it directly in LabelControlPointsPolyData member (update of vtkSelectVisiblePoints is always performed manually anyway, so we would not lose anything by switching from a filter to a simple explicit method call).

After that we could add a vtkMaskPoints filter to remove invisible points from the label mapper input, but this could lead to the same kind of slowdown due to excessive pipeline updates as in vtkSelectVisiblePoints. Instead, the label mapper could be improved to take an additional "visibility" scalar and that could be used for prevent rendering of occluded point labels. The label mapper might deserve some refactoring anyway, because it is way too complicated, and automatic rearrangement of labels to prevent overlaps does not work, and it would be nice to have support for displaying spokes and allow users to drag labels.

lassoan commented 2 years ago

Another idea to make rendering faster (moved over from #5752): reduce the number of actors.

We added a separate actor for displaying control points with different properties (normal, selected, active), just with different colors. We could modulate the color (and even the markup glyph type) using a point data array. Merge the Unselected+Selected+Active pipeline and the Project+ProjectBack pipeline? That would allow us to go from 5 actors to 2 actors per control point, which could be a significant improvement.

Connor-Bowley commented 2 years ago

Another idea to make rendering faster (moved over from #5752): reduce the number of actors.

I don't know if this will make much of a difference during times when all or nearly control points are of the same property (usually selected). If a property doesn't have any control points (e.g. unselected, active), then its actor is not rendered into the viewport during RenderOverlay, RenderOpaqueGeometry, and RenderTranslucentPolygonalGeometry. The actors are still returned by GetActors and called by ReleaseGraphicsResources however. https://github.com/Slicer/Slicer/blob/d572b87936f89dc590b52046d1fd5d46d06dd2f3/Modules/Loadable/Markups/VTKWidgets/vtkSlicerMarkupsWidgetRepresentation3D.cxx#L337 https://github.com/Slicer/Slicer/blob/d572b87936f89dc590b52046d1fd5d46d06dd2f3/Modules/Loadable/Markups/VTKWidgets/vtkSlicerMarkupsWidgetRepresentation3D.cxx#L831-L834

Also note that the Project and ProjectBack pipelines are never rendered in the 3D viewer. https://github.com/Slicer/Slicer/blob/d572b87936f89dc590b52046d1fd5d46d06dd2f3/Modules/Loadable/Markups/VTKWidgets/vtkSlicerMarkupsWidgetRepresentation3D.cxx#L258

Also note if the interactive handles are enabled they cause a massive hit to FPS.