Is there some method to add blendshape in editor?

Hi, developers,

Do you know if there's some method to add blendshape by script?

For now, I find that the only routine to add blendshape is to use external softwares and let the unity model importer to make blendshape when imported.

I really hope there's some API (or hidden API) to let us, for example, add a deformed Mesh as new blendshape.

1 Like

Hi TMPxyz,

We are working on the API at the moment, it's not yet finish so it won't be part of 5.0 for sure.

Thanks for the reply, :)

I'll see if I can find some workaround then.

@TMPxyz what's the complication you're experiencing with the established process used for blend shapes, beyond having to rely on a 3D modeling package to perform the morphs/blend shapes?

Hi, theANMATOR2b,

Nope, I don’t mean that I have trouble with current blendshape workflow, :slight_smile:

I’m just trying to make a plugin to add blendshape in unity editor, and I took a short investigation and found no API to add blendshape in editor script. So I’m considering to take a workaround for now.

1 Like

You can't really add a blend-shape in a Unity script. But you can alter existing blend-shapes through a Unity script. At the moment, it's just a given that you create blend-shapes in whatever 3D program you are using, and then use them inside of Unity.

Hi, RichardKain,

Do you mean that we can use scripts to alter the blend-shape set in modeling software? I didn’t find related APIs but SetBlenderShapeWeight().
Could you shed some more light on that? Thanks :slight_smile:

No, I merely meant that the value of an individual blend-shape can be accessed and altered in Unity through the Skinned Mesh Renderer component. For creating blend shapes themselves, you would have to create and alter the blend shape in a program such as Blender, 3D Studio Max, Maya, etc…

While I can understand the desire to alter a model through script, most blend-shape applications are faster and easier to edit in an external 3D program. There are often thousands of vertices that would need to be shifted around for even a basic blend shape. (depending on the complexity of the model) There are also no generalized approaches to applying such transformations through a script. Any such script would have to be customized for every model, as the polygon density and distribution of any model will vary wildly from any other model.

Once you have your blend-shape created in an external 3D program, the values for those shapes are readily available through scripting in Unity. Just don’t expect to be using scripts to alter the model itself.

Thanks for the detailed explanation.

If you create a blend-shape in an external 3D program, it will show up naturally when the model gets imported into Unity. I did this with my own models and Blender. When Unity imported the .blend file, it would automatically detect any blend-shapes that I had added to the model.

Those blend shapes are visible as a list in the Skinned Mesh Renderer component. (the default rendering component for any imported model that has an armature or blend shapes) Each of the blend-shapes in that list has a value from 0.0 to 100.0. Adjusting that slider will "animate" the blend-shape from it's least effect to it's greatest effect. For this reason, it is a good idea to exaggerate your blend-shapes a little bit when you are creating them in your 3D program.

These 0 - 100 values can be easily accessed and manipulated through scripting by accessing the Skinned Mesh Renderer component. Using this method, it is possible to adjust these values in a more dynamic fashion, and allow the animation of your blend-shapes to react to different events happening in the game. (instead of just having static, pre-defined animations) One common and extremely useful blend-shape fueled effect is to adjust your character's "breathing." By creating a blend shape of your character's chest and stomach expanding outward, you can make your character appear to be breathing by adjusting the slider for that blend-shape. If your character is running around a lot, you can increase the level to which that slider is extended, as well as the speed at which it changes, to make it seem like your character is breathing heavier or faster.

2 Likes

Can we have a preview version of the API, similar to WebGL, with warning that the API is subjected to change, just to get it out there so the developers on the asset store can have fun with it?

Right now I have to write my own vertex morphing scripts in LateUpdate that took the vertices array out of the mesh, accumulate the morph in a cache-line unsavvy way, then put them back into the mesh, that's a huge chuck of memory between mono and the native code.

I was thinking of writing a fbx exporter to export the runtime generated mesh and blendshape to a temp fbx then ask unity to import it back in, but that only work in editor, not the runtime, so I am stucked.

Hi sunnyDavid,

It not yet ready to be shipped, but I can give you a preview of the scripting API.
We did extend the mesh class to add blend shape support like this. And of course this all available at Runtime too.

public struct BlendShapeFrame
{
    public Vector3[] vertices;
    public Vector3[] normals;
    public Vector3[] tangents;

    private float m_Weight;

    public float weight { get { return m_Weight; } set { m_Weight = value; } }
}

public struct BlendShape
{
    protected string m_Name;

    public BlendShapeFrame[] frames;

    public string name { get { return m_Name; } set { m_Name = value; } }
}

public class Mesh
{
    public BlendShape[] blendShapes;
}
1 Like

That would be great! Oh, does each BlendShapeFrame contains the full list of vertices? you know sometimes only a small portion of the mesh need to be morphed.

And are the normals and tangents optional? Some stylized shaders doesn't need all of them.

Yes you need to define the full list of vertices

yes they are optionnal

Ok great! Can't wait for it to be released!!!

My only suggestion is that maybe the API allow us to get and set each BlendShape one by one, instead of a huge array of BlendShapes. In that case we can reuse the same vertices array. If I want to set 50 BlendShapes, instead of allocating 50 X 10,000 verts X Vector3 of memory, I can just reuse the same vertices array 50 times.


From the Unity 5.0 feature page if you missed it here.

Correct me if I misunderstand the data structures here.

It looks that ONE blendshape is consists of multiple BlendshapeFrame, is it like the multiple Keyframes in an AnimationCurve?

But I cannot see there's time / inTangent / outTangent attribute in the BlendshapeFrame structure, so how do you define the time and curve for them?
Or maybe you had just omitted these attributes to make it look simpler?

You can specify the blend weight for each BlendShapeFrame to get more control over how the blending occur.
So for each blend shape you can define intermediate BlendShapeFrame, it like adding extra keyframe to shape your animation curve.

Oh, I think I might get what you mean.

So we still use the AnimationCurve to tweak a float value ranging between [0, Count_of_BlendShapeFrame], which controls the interpolation between two BlendshapeFrames.

And the time and tangents are defined on the KeyFrame of AnimationCurve.

That's a great idea. I'll looking forward to the new APIs. :)

1 Like

There is no animation curve involved in the process.

You define a set a blend shape[smile, sad, angry] and for each shape you can define as many BlendshapeFrame as you want. For most case you will have only one BlendShapeFrame

But let say that for shape smile you don’t like the way Unity interpolate your shape at 50% because some vertex become too visible so you can add an intermediate BlendShapeFrame at 50%. Between 0-50% Unity will blend the default shape with BlendShapeFrame.weight = 50, and between 50%-100% Unity will blend blendshapeframe 50% and 100% together.

If there is only one blendshapeframe the weight is assume to be 100%

I hope it’s clearer

2 Likes