Bendy bones and shape keys cause vertices to pop #53700

Closed
opened 2018-01-05 22:16:46 +01:00 by Rafael Navega · 22 comments

Hi. I'm posting this to know if this is a known limitation.

bbone_shapekey_deformation0.gif

Blender Version
2.79

Short description of error
When you change the value of a shape key for a mesh that is deformed by an armature that has normal bones as well as bendy-bones, the mesh vertices will pop.

Exact steps for others to reproduce the error
Create a mesh and add an Armature modifier to it, with an armature object that has some normal bones as well as one or more bendy-bones (more than 1 subdivision). Use auto-weights or manual weight painting. Add and use a shape key on this mesh to see this behaviour.
This happens whether you're in animation playback mode or not.

I originally posted this as a Right-Click Select entry:
https://blender.community/c/rightclickselect/t0bbbc/b-bones-don-t-work-with-shape-keys

Hi. I'm posting this to know if this is a known limitation. ![bbone_shapekey_deformation0.gif](https://archive.blender.org/developer/F1711077/bbone_shapekey_deformation0.gif) **Blender Version** 2.79 **Short description of error** When you change the value of a shape key for a mesh that is deformed by an armature that has normal bones as well as bendy-bones, the mesh vertices will pop. **Exact steps for others to reproduce the error** Create a mesh and add an Armature modifier to it, with an armature object that has some normal bones as well as one or more bendy-bones (more than 1 subdivision). Use auto-weights or manual weight painting. Add and use a shape key on this mesh to see this behaviour. This happens whether you're in animation playback mode or not. I originally posted this as a Right-Click Select entry: https://blender.community/c/rightclickselect/t0bbbc/b-bones-don-t-work-with-shape-keys
Author

Added subscriber: @RNavega

Added subscriber: @RNavega

Added subscriber: @zeauro

Added subscriber: @zeauro

Currently, Bendy Bones are not replacing bones chains. Unless you have several subdivisions, you have one weight group or one enveloppe with one head and one tail per bone.
So, closed vertices may be influenced by following segments pointing to different angles at maximum intensity.
Distortion is obvious without the shapekey. The shapekey is just emphasizing gap made by skinning.

B-bones are useful to twist a part of initial mesh or to rig a curved part of the mesh . Their use for center of a sphere is irrelevant.
The shapekey was created before the skinning for a basis with closed vertices.
After that skinning creates the gap ; the shapekey becames irrelevant, too.
But there is no reason to observe a problem for a corrective shapekey made in sculpt mode.

If you use less B-bone segments than pairs of edge loops ; you will still have a noticeable problem because curvature of bone will only correspond to curvature of mesh at rest pose.
Unless you are only doing a twisting, segments cuts will still be obvious and emphasized by a pose that is creating bigger gaps between segments.
So, you have to use B-bones with a mesh part that is not dense and a subdivision surface modifier after the armature.
Or if the mesh part is detailed, you have to compensate the problem with a corrective smooth modifier.

But an automatic smoothing of weight between segments is rather a feature request or a todo than a bug.
At least, it is an already known issue.
https://youtu.be/-R1VQ1M8dM0?t=19m52s

Currently, Bendy Bones are not replacing bones chains. Unless you have several subdivisions, you have one weight group or one enveloppe with one head and one tail per bone. So, closed vertices may be influenced by following segments pointing to different angles at maximum intensity. Distortion is obvious without the shapekey. The shapekey is just emphasizing gap made by skinning. B-bones are useful to twist a part of initial mesh or to rig a curved part of the mesh . Their use for center of a sphere is irrelevant. The shapekey was created before the skinning for a basis with closed vertices. After that skinning creates the gap ; the shapekey becames irrelevant, too. But there is no reason to observe a problem for a corrective shapekey made in sculpt mode. If you use less B-bone segments than pairs of edge loops ; you will still have a noticeable problem because curvature of bone will only correspond to curvature of mesh at rest pose. Unless you are only doing a twisting, segments cuts will still be obvious and emphasized by a pose that is creating bigger gaps between segments. So, you have to use B-bones with a mesh part that is not dense and a subdivision surface modifier after the armature. Or if the mesh part is detailed, you have to compensate the problem with a corrective smooth modifier. But an automatic smoothing of weight between segments is rather a feature request or a todo than a bug. At least, it is an already known issue. https://youtu.be/-R1VQ1M8dM0?t=19m52s
Author

@zeauro Thank you for your observations. You're right, a sphere is not the best kind of mesh to show what I mean.
I'll try with a cylinder. So the same context as in those steps to reproduce the event from the report, but with a cylinder and some keyframes.

Shown only the armature modifier:
bbone_shapekey_anim1.gif

Shown only the shapekey animation:
bbone_shapekey_anim2.gif

And finally with both combined (armature modifier and shapekey animation):
bbone_shapekey_anim3.gif

The problem is how the swelling part of the mesh pops in place.
So this would appear in a render, for example, if you were using shape keys for correction or just for morphing (like a skinny character that becomes big and muscular).
Increasing the b-bone subdivisions and using a Corrective Smooth modifier seems to make this behaviour less noticeable (the pops get more subtle).

@zeauro Thank you for your observations. You're right, a sphere is not the best kind of mesh to show what I mean. I'll try with a cylinder. So the same context as in those steps to reproduce the event from the report, but with a cylinder and some keyframes. Shown only the armature modifier: ![bbone_shapekey_anim1.gif](https://archive.blender.org/developer/F1718477/bbone_shapekey_anim1.gif) Shown only the shapekey animation: ![bbone_shapekey_anim2.gif](https://archive.blender.org/developer/F1718488/bbone_shapekey_anim2.gif) And finally with both combined (armature modifier and shapekey animation): ![bbone_shapekey_anim3.gif](https://archive.blender.org/developer/F1718497/bbone_shapekey_anim3.gif) The problem is how the swelling part of the mesh pops in place. So this would appear in a render, for example, if you were using shape keys for correction or just for morphing (like a skinny character that becomes big and muscular). Increasing the b-bone subdivisions and using a Corrective Smooth modifier seems to make this behaviour less noticeable (the pops get more subtle).
Member

Added subscribers: @JoshuaLeung, @lichtwerk

Added subscribers: @JoshuaLeung, @lichtwerk
Joshua Leung was assigned by Philipp Oeser 2018-01-09 19:59:05 +01:00
Member

It indeed seems like a known limitation, but maybe @JoshuaLeung can share his wisdom? move to TODO?

It indeed seems like a known limitation, but maybe @JoshuaLeung can share his wisdom? move to TODO?

Added subscriber: @Sergey

Added subscriber: @Sergey

@JoshuaLeung , any updates here?

@JoshuaLeung , any updates here?
Author

I think it has to do with this logic here:
https://github.com/dfelinto/blender/blob/master/source/blender/blenkernel/intern/armature.c#L778-L783

Deformed (shape-keyed) vertices are assigned to b-bone segments based on their position relative to the rest-pose b-bone, so if the deformed vertices change position (like when you change a shape key strength), they become assigned to different segments (which may have a very different transform, causing the popping effect).
That's what i take from it, but I can't look into it further.

I think it has to do with this logic here: https://github.com/dfelinto/blender/blob/master/source/blender/blenkernel/intern/armature.c#L778-L783 Deformed (shape-keyed) vertices are assigned to b-bone segments based on their position relative to the rest-pose b-bone, so if the deformed vertices change position (like when you change a shape key strength), they become assigned to different segments (which may have a very different transform, causing the popping effect). That's what i take from it, but I can't look into it further.
Author

Hi. After researching some more.

This is a problem of interpolation (or lack of it).

The code is correct in taking the vertices after they are deformed (from shape keys or from modifiers earlier in the stack) and mapping them to b-bone segments.
But this code here considers a vertex as being deformed by a single b-bone segment at a time:

/* now calculate which of the b_bones are deforming this */
segment = bone->length / ((float)bone->segments);
a = (int)(y / segment);

Knowing this, we can make a scene with the worst case scenario, a two-segment b-bone with a sharp curve:

blenderBendyBoneInterpolation01.gif
Bendy Bone Interpolation 01.blend

(The stuff on the right side is just a duplicate, where the b-bone segments are scaled so you can tell them apart. This scene can be used as a template for testing solutions to this.)

@JoshuaLeung had mentioned this in an article in the past:

(...) any questions regarding the quality of B-Bone deforms, or how those work are not covered here.

For details about those, go consult the armature modifier for further details about how it uses the B-Bone info gained from b_bone_spline_setup(). My guess is that it calculates delta matrices for each segment, and then interpolates between these to deform points that are affected by such bones. Smoother deforms may be possible if we added an extra smoothing step in there somewhere, instead of just using the result.

I think the solution is localised to the b_bone_deform function in armature.c.
Like, the fractional part...

(y/segment) - (int)(y/segment)

...could be used to interpolate the deformation being done on the vertex, such as SLERPing the rotations of the segments that the vertex is closest to along the Y-axis of the b-bone local space, like it's being done now to map it.
Since a b-bone tries to fit a bezier curve, the ideal deformation that this interpolation should cause on a mesh with shape keys \ deform modifiers earlier in the stack would probably be like the Curve modifier, which does something similar.
Anyway, I think it's a to-do. Good luck!

Hi. After researching some more. This is a problem of interpolation (or lack of it). The code is correct in taking the vertices *after* they are deformed (from shape keys or from modifiers earlier in the stack) and mapping them to b-bone segments. But this code here considers a vertex as being deformed by a single b-bone segment at a time: ``` /* now calculate which of the b_bones are deforming this */ segment = bone->length / ((float)bone->segments); a = (int)(y / segment); ``` Knowing this, we can make a scene with the worst case scenario, a two-segment b-bone with a sharp curve: ![blenderBendyBoneInterpolation01.gif](https://archive.blender.org/developer/F2583160/blenderBendyBoneInterpolation01.gif) [Bendy Bone Interpolation 01.blend](https://archive.blender.org/developer/F2583162/Bendy_Bone_Interpolation_01.blend) (The stuff on the right side is just a duplicate, where the b-bone segments are scaled so you can tell them apart. This scene can be used as a template for testing solutions to this.) @JoshuaLeung had mentioned this [in an article](https://code.blender.org/2016/05/an-in-depth-look-at-how-b-bones-work-including-details-of-the-new-bendy-bones/) in the past: > (...) any questions regarding the quality of B-Bone deforms, or how those work are not covered here. > > For details about those, go consult the armature modifier for further details about how it uses the B-Bone info gained from b_bone_spline_setup(). My guess is that it calculates delta matrices for each segment, and then interpolates between these to deform points that are affected by such bones. Smoother deforms may be possible if we added an extra smoothing step in there somewhere, instead of just using the result. I think the solution is localised to the **b_bone_deform** function in **armature.c**. Like, the fractional part... ``` (y/segment) - (int)(y/segment) ``` ...could be used to interpolate the deformation being done on the vertex, such as SLERPing the rotations of the segments that the vertex is closest to along the Y-axis of the b-bone local space, like it's being done now to map it. Since a b-bone tries to fit a bezier curve, the ideal deformation that this interpolation should cause on a mesh with shape keys \ deform modifiers earlier in the stack would probably be like the [Curve modifier](https://docs.blender.org/manual/en/dev/modeling/modifiers/deform/curve.html), which does something similar. Anyway, I think it's a to-do. Good luck!

Added subscriber: @Sam200

Added subscriber: @Sam200

Hi everyone, I'm not a Blender developer but I took some time to implement interpolation between bendy bone segments. If I'm doing something wrong posting here, tell me, because I'm new to all this.

This shows bendy bones with interpolation:
{F6908197, size=full}

And this shows how it works currently in master branch:
{F6908200, size=full}

It's a minor change in a single source file limited to a single static function (with 2 small static functions added to improve clarity).

Here's the git diff (edit: Improved code readability and formatting):
interpolated bendy bones diff.txt

Hi everyone, I'm not a Blender developer but I took some time to implement interpolation between bendy bone segments. If I'm doing something wrong posting here, tell me, because I'm new to all this. This shows bendy bones with interpolation: {[F6908197](https://archive.blender.org/developer/F6908197/interpolated_bendy_bones.gif), size=full} And this shows how it works currently in master branch: {[F6908200](https://archive.blender.org/developer/F6908200/current_bendy_bones.gif), size=full} It's a minor change in a single source file limited to a single static function (with 2 small static functions added to improve clarity). Here's the git diff (edit: Improved code readability and formatting): [interpolated bendy bones diff.txt](https://archive.blender.org/developer/F6908339/interpolated_bendy_bones_diff.txt)
Author

Omg that's brilliant @Sam200! It's clearly an improvement.
You should submit that in here if you haven't already: https://developer.blender.org/differential/diff/create/

Omg that's brilliant @Sam200! It's clearly an improvement. You should submit that in here if you haven't already: https://developer.blender.org/differential/diff/create/
Joshua Leung was unassigned by Rafael Navega 2019-04-03 10:31:42 +02:00
Sam was assigned by Rafael Navega 2019-04-03 10:31:42 +02:00
Author

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'

Submitted patch here

Submitted patch [here ](https://developer.blender.org/D4635)

This issue was referenced by 51c8a6f491

This issue was referenced by 51c8a6f491d3b21a6c91af6267f58d4f0add58af

Added subscriber: @angavrilov

Added subscriber: @angavrilov

Changed status from 'Resolved' to: 'Open'

Changed status from 'Resolved' to: 'Open'

Bugs shouldn't be closed until the patch is actually committed, it's misleading.

Bugs shouldn't be closed until the patch is actually committed, it's misleading.
Author

@angavrilov how did you associate the patch with this task? I can't find it in Actions.

@angavrilov how did you associate the patch with this task? I can't find it in Actions.

Added subscriber: @capnm

Added subscriber: @capnm
Sam was unassigned by Alexander Gavrilov 2019-04-13 15:19:13 +02:00
Alexander Gavrilov self-assigned this 2019-04-13 15:19:13 +02:00

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
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
8 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#53700
No description provided.