Proposal for fast high poly mesh editing #74186

Closed
opened 2020-02-25 00:38:36 +01:00 by Campbell Barton · 32 comments

Stage 1, Minimize Unnecessary Work


This should bring Blender's performance back to what we had in 2.7x.

The first step for this planning will be to perform benchmarks to
get an idea how much time these operations are taking,
so we can estimate how much of a speed improvement
we can expect to see for each proposed change.

This can help us prioritize changes.

Skip EditMesh to Mesh Conversion

Blender 2.7x supported edit-mesh without the creation of an "evaluation mesh".

For Blender 2.8x development it was convenient to always create this mesh
however this adds significant overhead, especially when making interactive mesh edits.

Exactly how to do this needs some design discussion with other module owners,
since it impacts the:

  • Depsgraph.
  • Modifier stack.
  • Render engine API.
  • Python API & file IO.

Exact details for this may change.

  • Support Delayed Mesh Creation:
Initially this may mean locking the object upon request for an evaluation mesh,
for common editing operations there would be no need to create this data.
For cases where we know the evaluation mesh is needed,
the depsgraph could create this.
The end result should be that locking is avoided in common cases.
Ideally we could avoid it entirely, however there may end up being some operations
that require mesh data that we can't predict ahead of time.
  • Modifier Stack Support for EditMesh:
Support deformations without converting to a "Mesh".
  • Support edit-mesh for tools & UI code: Currently which assume an evaluation mesh is present. Listing this here since it's going to take time to go over all uses of
`Object.runtime.mesh_eval` and find cases which should account for the edit-mesh,
for example `stats_object` checks this.
  • Multi-Thread EditMesh to Mesh Conversion
This can use 3 threads, vertices/edges/faces.
Splitting this up further could be done, I'd need to check if this would cause problems copying custom-data.

Minimize Data Send to the GPU

One part of this project is to minimize data sent to the GPU after each mesh edit.

  • Selection:
When changing selection,
only the selection state arrays need to be refreshed.
  • Deformation:
When moving geometry, only vertex locations need be updated,
along with derived data:
Face centers, normals and possibly UV tangents.
  • Custom Data Layers:
When editing a UV layer, the updates could be limited to that layer
and it's (UV tangents when present).
The same goes for Vertex colors and Weight Paint colors.

This could be achieved by tagging a mesh as requiring data to be updated.

Optimize Edit-mesh to GPU Conversion

Benchmark current code, identify any bottlenecks to improve the performance.

//As far as I know, nobody has checked on edit-mesh conversion performance,
since for 2.80 release we were mainly concerned with it working correctly.//

Stage 2, Further Optimizations


This is mainly to note possible improvements.

This is only a rough outline, we can re-evaluate this once stage one is done.

Partial Geometry Updates

Currently when moving a single vertex, all normals are recalculated and the entire mesh is updated.

This would avoid two expensive operations:

  • Recalculating all normals.
  • Sending all vertex coordinates and normals the the GPU.

We could support tagging geometry to update, while this would only work for deformations,
this could give a significant speedup in the common case of transforming geometry.

Although there are complications with having to update connected normals, custom-normals and UV-tangents
making this a less straightforward task.

BMesh Support in the Modifier Stack

Avoid unnecessary BMesh conversions by allowing modifiers to pass BMesh data between modifiers.

Multi-Object Edit-Mode

Currently there aren't many optimizations relating to multi-object edit-mode.

  • Every undo step includes all editable objects.
This can be optimized only to include tagged objects.

Multi-Threaded Conversion

There are some difficulties with OpenGL and threading,
so the gains here might be limited, or better left until we move to Vulkan which handles this better.

The gains for edit-mesh aren't large unless the users is editing many meshes at once.

Listing this for completeness.

Stage 1, Minimize Unnecessary Work **** This should bring Blender's performance back to what we had in 2.7x. The first step for this planning will be to perform benchmarks to get an idea how much time these operations are taking, so we can estimate how much of a speed improvement we can expect to see for each proposed change. This can help us prioritize changes. Skip EditMesh to Mesh Conversion -------------------------------- Blender 2.7x supported edit-mesh without the creation of an "evaluation mesh". For Blender 2.8x development it was convenient to always create this mesh however this adds significant overhead, especially when making interactive mesh edits. Exactly how to do this needs some design discussion with other module owners, since it impacts the: * Depsgraph. * Modifier stack. * Render engine API. * Python API & file IO. Exact details for this may change. * **Support Delayed Mesh Creation:** ``` Initially this may mean locking the object upon request for an evaluation mesh, for common editing operations there would be no need to create this data. ``` ``` For cases where we know the evaluation mesh is needed, the depsgraph could create this. ``` ``` The end result should be that locking is avoided in common cases. Ideally we could avoid it entirely, however there may end up being some operations that require mesh data that we can't predict ahead of time. ``` * **Modifier Stack Support for EditMesh:** ``` Support deformations without converting to a "Mesh". ``` * **Support edit-mesh for tools & UI code:** Currently which assume an evaluation mesh is present. Listing this here since it's going to take time to go over all uses of ``` `Object.runtime.mesh_eval` and find cases which should account for the edit-mesh, for example `stats_object` checks this. ``` * Multi-Thread EditMesh to Mesh Conversion ``` This can use 3 threads, vertices/edges/faces. ``` ``` Splitting this up further could be done, I'd need to check if this would cause problems copying custom-data. ``` Minimize Data Send to the GPU ----------------------------- One part of this project is to minimize data sent to the GPU after each mesh edit. * **Selection:** ``` When changing selection, only the selection state arrays need to be refreshed. ``` * **Deformation:** ``` When moving geometry, only vertex locations need be updated, along with derived data: Face centers, normals and possibly UV tangents. ``` * **Custom Data Layers:** ``` When editing a UV layer, the updates could be limited to that layer and it's (UV tangents when present). The same goes for Vertex colors and Weight Paint colors. ``` This could be achieved by tagging a mesh as requiring data to be updated. Optimize Edit-mesh to GPU Conversion ------------------------------------ Benchmark current code, identify any bottlenecks to improve the performance. //As far as I know, nobody has checked on edit-mesh conversion performance, since for 2.80 release we were mainly concerned with it working correctly.// Stage 2, Further Optimizations **** This is mainly to note possible improvements. This is only a rough outline, we can re-evaluate this once stage one is done. Partial Geometry Updates ------------------------ Currently when moving a single vertex, all normals are recalculated and the entire mesh is updated. This would avoid two expensive operations: * Recalculating all normals. * Sending all vertex coordinates and normals the the GPU. We could support tagging geometry to update, while this would only work for deformations, this could give a significant speedup in the common case of transforming geometry. Although there are complications with having to update connected normals, custom-normals and UV-tangents making this a less straightforward task. BMesh Support in the Modifier Stack ----------------------------------- Avoid unnecessary BMesh conversions by allowing modifiers to pass BMesh data between modifiers. Multi-Object Edit-Mode ---------------------- Currently there aren't many optimizations relating to multi-object edit-mode. * Every undo step includes all editable objects. ``` This can be optimized only to include tagged objects. ``` Multi-Threaded Conversion ------------------------- There are some difficulties with OpenGL and threading, so the gains here might be limited, or better left until we move to Vulkan which handles this better. The gains for edit-mesh aren't large unless the users is editing many meshes at once. Listing this for completeness.
Campbell Barton self-assigned this 2020-02-25 00:38:36 +01:00
Author
Owner

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Author
Owner

Added subscriber: @ideasman42

Added subscriber: @ideasman42

Added subscriber: @1D_Inc

Added subscriber: @1D_Inc

A question.
Will it be possible to develop a special cheapest heavy mesh viewport display mode, that contains no AA, no multisampling, edges shading and other features to increase performance?
We woul like to use such a mode.

A question. Will it be possible to develop a special cheapest heavy mesh viewport display mode, that contains no AA, no multisampling, edges shading and other features to increase performance? We woul like to use such a mode.

Added subscriber: @YAFU

Added subscriber: @YAFU

I'm afraid that the main bottleneck in edit mode is CPU related and not related to the GPU or viewport features. In my tests select the worst quality in viewport and a very small size of viewport/blender window does not make changes in fps while you move vertices in dense mesh.
Edit:
I mean, I'm not sure that what you ( Paul Kotelevets ) proposes changes the situation much.

I'm afraid that the main bottleneck in edit mode is CPU related and not related to the GPU or viewport features. In my tests select the worst quality in viewport and a very small size of viewport/blender window does not make changes in fps while you move vertices in dense mesh. Edit: I mean, I'm not sure that what you ( Paul Kotelevets ) proposes changes the situation much.

In #74186#879761, @YAFU wrote:
I mean, I'm not sure that what you ( Paul Kotelevets ) proposes changes the situation much.

I suppose it depends on the implementation as well.

> In #74186#879761, @YAFU wrote: > I mean, I'm not sure that what you ( Paul Kotelevets ) proposes changes the situation much. I suppose it depends on the implementation as well.
Author
Owner

@1D_Inc, noted, although I think we should first look into making the default shader faster - if this is even a bottleneck.

@1D_Inc, noted, although I think we should first look into making the default shader faster - if this is even a bottleneck.

Added subscriber: @kioku

Added subscriber: @kioku

Added subscriber: @ManuelAlbert

Added subscriber: @ManuelAlbert

Added subscriber: @Blendork

Added subscriber: @Blendork

Added subscriber: @ostry

Added subscriber: @ostry

Added subscriber: @brecht

Added subscriber: @brecht

This proposal seems broadly fine to me.

I also expect that EditMesh to Mesh Conversion can be multi-threaded? Depends how much it shows up in the profiles if it's worth to do this, but from what I remember this is largely single-threaded while there are some loops that might be trivially converted to run on multiple threads if there is a high number of verts/faces.

Also, our current multi-threaded normal computation algorithm does not scale well with many threads. The use of atomics for accumulation is too slow. A better algorithm is not trivial, but may be worth investigating if this shows up significantly in the profiles.

Support Delayed Mesh Creation: Initially this may mean locking the object upon request for an evaluation mesh, for common editing operations there would be no need to create this data.

I'm not sure what locking means here exactly? I would imagine the mesh to be created from the editmesh on demand, probably with a double-checked mutex lock, but there would no need for any thread to hold that lock once the mesh has been created?

This proposal seems broadly fine to me. I also expect that EditMesh to Mesh Conversion can be multi-threaded? Depends how much it shows up in the profiles if it's worth to do this, but from what I remember this is largely single-threaded while there are some loops that might be trivially converted to run on multiple threads if there is a high number of verts/faces. Also, our current multi-threaded normal computation algorithm does not scale well with many threads. The use of atomics for accumulation is too slow. A better algorithm is not trivial, but may be worth investigating if this shows up significantly in the profiles. > Support Delayed Mesh Creation: Initially this may mean locking the object upon request for an evaluation mesh, for common editing operations there would be no need to create this data. I'm not sure what locking means here exactly? I would imagine the mesh to be created from the editmesh on demand, probably with a double-checked mutex lock, but there would no need for any thread to hold that lock once the mesh has been created?

Added subscriber: @SamGreen

Added subscriber: @SamGreen
Author
Owner

No problem with mutli-threading EditMesh -> Mesh conversion. It's fairly localized code.

Although from memory, this ends up only being useful with quite high poly meshes.

As for locking, it depends if we want to keep the shared Object.runtime.mesh_eval, if this is lazily initialized - instead of always filled in, we'll have to lock it to avoid multiple users initializing it at once.

Or, an alternative could be to create the mesh from the bmesh as needed, then free it (leaving Object.runtime.mesh_eval NULL), the problem with this is it could end up being impractical for usage where the beginning/end isn't as clearly defined.

No problem with mutli-threading EditMesh -> Mesh conversion. It's fairly localized code. Although from memory, this ends up only being useful with quite high poly meshes. As for locking, it depends if we want to keep the shared `Object.runtime.mesh_eval`, if this is lazily initialized - instead of always filled in, we'll have to lock it to avoid multiple users initializing it at once. Or, an alternative could be to create the mesh from the bmesh as needed, then free it (leaving `Object.runtime.mesh_eval` NULL), the problem with this is it could end up being impractical for usage where the beginning/end isn't as clearly defined.

I think lazily initialized is fine. It's difficult to predict how many times this will be used, so if we free it everytime that might happen a lot and become a performance problem in itself. And to perform the lazy initialization you do indeed need a (probably double-checked) lock.

I think lazily initialized is fine. It's difficult to predict how many times this will be used, so if we free it everytime that might happen a lot and become a performance problem in itself. And to perform the lazy initialization you do indeed need a (probably double-checked) lock.

Added subscriber: @VladimirTurcan

Added subscriber: @VladimirTurcan

Removed subscriber: @VladimirTurcan

Removed subscriber: @VladimirTurcan

Added subscriber: @VladimirTurcan

Added subscriber: @VladimirTurcan

Added subscriber: @ckohl_art

Added subscriber: @ckohl_art

Added subscriber: @wakin

Added subscriber: @wakin

Added subscriber: @Astiero

Added subscriber: @Astiero

In #74186#879788, @ideasman42 wrote:
@1D_Inc, noted, although I think we should first look into making the default shader faster - if this is even a bottleneck.

Ok, just wanted to know the opinion of the developer. Thank you for the answer.

> In #74186#879788, @ideasman42 wrote: > @1D_Inc, noted, although I think we should first look into making the default shader faster - if this is even a bottleneck. Ok, just wanted to know the opinion of the developer. Thank you for the answer.

Added subscriber: @0o00o0oo

Added subscriber: @0o00o0oo

Added subscriber: @JacobMerrill-1

Added subscriber: @JacobMerrill-1

for the future optimizations- sculpting and painting very high poly meshes

using 1 mesh for physics and for graphics is a bad design when we cross a certain model complexity.

we need to take the mesh and break it up like voxel remesh does - but break a mesh into islands - each island(physics patch) vertex 'ownes' a gfx vertex - and can own up to 3 other physics patch vertex.

we can sculpt on the physics patches and have them update the draw mesh vertex - and rebuild the very small physics patch bvhtree .

  1. getting hit position on big meshes becomes faster
  2. rebulding small bvhtree that change is much faster than rebuilding the whole tree.
    • room is left for adaptive subdivision too.
for the future optimizations- sculpting and painting very high poly meshes using 1 mesh for physics and for graphics is a bad design when we cross a certain model complexity. we need to take the mesh and break it up like voxel remesh does - but break a mesh into islands - each island(physics patch) vertex 'ownes' a gfx vertex - and can own up to 3 other physics patch vertex. we can sculpt on the physics patches and have them update the draw mesh vertex - and rebuild the very small physics patch bvhtree . 1. getting hit position on big meshes becomes faster 2. rebulding small bvhtree that change is much faster than rebuilding the whole tree. 3. - room is left for adaptive subdivision too.

Added subscriber: @ReguzaEi

Added subscriber: @ReguzaEi

Added subscriber: @mattli911

Added subscriber: @mattli911

Added subscriber: @MeshVoid

Added subscriber: @MeshVoid

Added subscriber: @lictex_1

Added subscriber: @lictex_1
Philipp Oeser removed the
Interest
Modeling
label 2023-02-09 15:29:19 +01:00
Author
Owner

Closing, while some of these suggestions have not been implemented (only storing undo data for tagged meshes for e.g.), quite a few have and I don't think it helps to keep this issue open.

Closing, while some of these suggestions have not been implemented (only storing undo data for tagged meshes for e.g.), quite a few have and I don't think it helps to keep this issue open.
Blender Bot added
Status
Archived
and removed
Status
Confirmed
labels 2024-01-15 03:34:15 +01:00
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
19 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#74186
No description provided.