In-between blendshapes

Good morning:

We’ve just need to create a “functional” measure tape and wanted to do it the classic way, made of a plane with a non-linear bend deformer, in order for it to curve on itself like a snail.

The case is that GLTF doesn’t export deformers, so we need to llok for another way. We tried with “in-between” blendshape, so it curves again but found out that GLTF doesn’t suppor that “progressive” blendshapes at all, just jumps from first shape to the end one with no in-betweens

Do you have any information about that kind of blendshapes or how to address this model?

Thanks for your time.

maybe @bghgary can help here? or @sebavan ?

@bghgary is definitely the king on this topic :slight_smile:

I’m not sure what you mean by this. Do you have an example? Here is a very basic morph target (blend shape) example from the glTF sample models repo loaded in the Babylon.js Sandbox: Babylon.js - AnimatedMorphCube.gltf (babylonjs.com).

Hi there @bghgary:

I’m translating your comments to the resident 3D artist guy in the company, and will let you know.

Thanks for your time.

1 Like

Hi, I’m the 3D guy LOL
Having watched the youtube video about morph targets, I confirm they are the same as blendshapes in MAYA.
But with one exception there. While glTF morph targets just support going from point A to B, so they blend between source mesh to destination, MAYA’s blendshapes CAN blend between multiple targets in the same weight. So, when you are at weight 0, you see the source mesh. At weight 0.5, you see the second mesh, and at weight 1.0 you see the destination mesh. So “in-between” blendshapes (that’s how they are called) are great to face circular movements, like eyelids do (eyelids should move in a circular way because the eyeball below is spherical).
Does all this make sense?

I don’t know much about this. Maybe @PatrickRyan has seen this before?

@joie, sorry for the delay in my response. As far as I know, glTF does not support one parameter morphing between multiple shape states. The way I would normally pass from one shape through another to the end shape is by cross fading the influences like this example.

Here I’ve started with a cube, morph to a sphere before ending on the hemisphere and then back out again. The cube => sphere and cube => hemisphere morphs are two different influences, but if you cross fade the animations, you will appear to move through a different shape to reach the end shape. This is what I mean by the cross fade:

This is how the influences change in order to produce cube => sphere => hemisphere => sphere => cube morph:

  • sphere influence moves to 1.0, hemisphere influence remains at 0.0
  • sphere influence moves to 0.0 at the same rate at hemisphere influence moves to 1.0
  • hemisphere influence moves to 0.0 at the same rate as sphere influence moves to 1.0
  • sphere influence moves to 0.0 while hemisphere influence remains at 0.0

I realize that needing to handle two influence values instead of one makes for a more complicated animation process. However, I would suggest creating a control rig that you can map a single value to lerp the values of the multiple influence values. I haven’t made a rig like this for glTF, but you should be able to either export or bake the correct data into the glTF so that your animations retain your authored motion but also fit within the glTF spec.

I hope this helps, but please feel free to ping me with more questions.

I wonder if this should be an exporter issue. Maybe it’s possible to automatically separate these morph targets on export. cc @Guillaume_Pelletier

1 Like

Hello,
The exporter is suppose to deal with multiple target for a weight.
the final weight associated with the target is calculated using
weight * envelope
where envelope is a global scale factor that is applied to all of the weight values in the deformer (Maya API).
So at this point we may end up with multiple morph target with correct (blended) weight.
What i do not know is how the animation is handle these parameters, and how it’s translated to GLTF.
Having a sample will definitively help.

Hi there,
Thank you for the explanation. I saw something like that in the video about infinite morph targets (which looks promising until you realize you can’t do that with the exporter, that guy does it via coding).
Your example is perfect for something very simple, but in our case, we would need hundreds of morph targets.
Let me put this in context.
We need to create a rubber transmission band (which is NOT a closed loop).
So, I made that transmission band with the curve wrap deformer and it worked great.
you can see it here:

So, as you know, glTF doesn’t suppor the curve wrap deformer, obviously.
So I needed another approach and I made new version with simple joint chain with iksplinewhich works great again, but it needs LOTS of joints, almost 250 of them.
The glTF exporter process takes forever and It doesn’t export after two hours.
Another approach is to convert that skinning to one in-between blendshape with hundreds of weights, that’s not a problem in MAYA.
Obviously that doesn’t work for glTF because there is a limit in the number of morph targets an object can store.
So we´re running out of ideas.

we are considering using a kind of animated displacement map, but it’s not a straight forward solution.

@joie, thank you for the explanation of what you are trying to achieve, this context helps us understand the real issue you face. The limiting factor in all of this is that you are trying to bake all of the animation into the glTF format. If that is the goal, then I am expecting that you want to be able to use this asset in any environment that supports glTF which would limit custom extensions or even ratified extensions since there is no guarantee that any implementation of glTF includes all extensions.

Due to that limitation, I would likely use an approach that leans more heavily on game art. This would be separating your belt into sections that can be grouped together and using bones only where needed. This is a little hard to describe, so I put together the diagram below.

The circle represents the cylinder your belt is wrapped around and the dotted and solid lines represent your belt. The red dotted line represents the section of your belt that is skinned to a chain of joints. The blue straight lines represent the area of the belt that remains straight between bends. These blue sections would all be skinned to a single joint.

Assuming your animation starts at A, the motion of the red section of the curve will wrap around the cylinder in the direction of the red arrow to B. The blue section of straight mesh will move in the same direction of the straight blue arrows to B. Once these reach the position of B, the animation will loop back to A. You need to have linear key tangents in this motion so that the snap back at the loop will not be perceived by the user. You do have an advantage in your case since the belt is a repeating pattern of shapes, so as long as the start and end positions align to the pattern, it will be invisible to the user. This will dramatically cut down on the number of joints you need.

You will want to split the mesh to make sure that you have double vertices at the breaks between the red and blue sections for skinning purposes. It won’t be welded in the glTF, but breaks in UV seams aren’t welded either, so it won’t matter. You can then combine all of the submeshes that make up the belt into one mesh for skinning to reduce the number of draw calls, but don’t combine vertices so you can isolate the skin weights.

If you need to have something like a pattern in the texture of the belt (like type on the outside surface) you can do something like an animated UV on the texture that matches the speed of the belt. In this way, it won’t seem that the belt is only animating a small amount before snapping back.

This will also result in a much smaller file as you won’t need to store a bunch of morph target data in the glTF either. I hope this helps spark some ideas for you.

1 Like

Also, I think @bghgary and @Guillaume_Pelletier would be interested in possibly looking at the file that wouldn’t export. I don’t know if there is a limit to the number of bones in a skeletal hierarchy in glTF but the fact that it sits for hours and doesn’t export tells me there may be an issue in the exporter.

1 Like

Hi there @PatrickRyan
I’d like to thank you for the so in depth explanation. We want to test if we can make the displacement map trick first, since your solution is quite involving.
Here you can download the test scene with the geometry and the IK Spline joint hierarchy that moves it. It would be super great if you could be able to export it to glTF: WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free
Thanks!

1 Like

@bghgary and @Guillaume_Pelletier to also take a look at the file if possible. I will dig in as well.

2 Likes

I manage to get a functional gltf, by optimizing (a lot) the code. still very long with animation export, where I haven’t been.
However, the exported animation is not correct and some minor GLTF issues are still left.
Keep you posted
test.zip (441.1 KB)

3 Likes

Yep, as you say, the output glTF is not correct. How long did it take for you to export that?
I don’t know where the problem is, it looks like the joints get an increasing rotation and translation offset somehow, which is not in the source MAYA file.
Any ideas?

No idea yet, i have to dig in further.
About the time, it did take too much (about 30mn) which is NOT acceptable, it might be about less than a minute (the skin export now is about 5s), but i did not optimize the animation export yet. Once done, this will give me the opportunity to explore the offset issue.

3 Likes

Hi there @Guillaume_Pelletier
Do you have any update on the issue?
Thanks!