Search Unity

Is there some method to add blendshape in editor?

Discussion in 'Animation' started by TMPxyz, Feb 14, 2015.

  1. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I would have expected that Mesh.vertices would give you the deformed mesh.
    exactly like the second example in the documentation
    http://docs.unity3d.com/ScriptReference/Mesh.html

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ExampleClass : MonoBehaviour {
    6.     void Update() {
    7.         Mesh mesh = GetComponent<MeshFilter>().mesh;
    8.         Vector3[] vertices = mesh.vertices;
    9.         Vector3[] normals = mesh.normals;
    10.         int i = 0;
    11.         while (i < vertices.Length) {
    12.             vertices[i] += normals[i] * Mathf.Sin(Time.time);
    13.             i++;
    14.         }
    15.         mesh.vertices = vertices;
    16.     }
    17. }
     
  2. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    I thought the same thing, but the results of this test indicate the Mesh.verticies are not being updated by blend shape changes. This test grabs a snapshot of the Mesh.verticies before a blend shape change and another snapshot after, then loops through both looking for differences, but finds none. Is this a bug?

    Code (CSharp):
    1.         if (test2)
    2.         {
    3.             test2 = false;
    4.  
    5.             int diffs = 0;
    6.             // Grab verticies before blendshape
    7.             preShapeVerts = mesh.vertices;
    8.             // Set blendshape
    9.             smr.SetBlendShapeWeight(7, 100f);
    10.             // Grab verticies after blendshape
    11.             postShapeVerts = mesh.vertices;
    12.  
    13.             for (int i = 0; i < preShapeVerts.Length; i++)
    14.             {
    15.                 if (preShapeVerts[i].x != postShapeVerts[i].x
    16.                     || preShapeVerts[i].y != postShapeVerts[i].y
    17.                     || preShapeVerts[i].z != postShapeVerts[i].z)
    18.                 {
    19.                     diffs++;
    20.                 }
    21.             }
    22.  
    23.             Debug.Log("Differences: " + diffs);
    24.         }
     
  3. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    I also tried this in a coroutine with some delays between the initial vertex sample, blend shape activation, and the second vertex sample just in case the mesh changes don't occur until the next frame. You can certainly change vertex positions and apply those changes to the Mesh, but the blend shapes don't seem to have any effect on the Mesh.vertcies vectors.
     
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
  5. AVOlight

    AVOlight

    Joined:
    Apr 15, 2014
    Posts:
    427
    Thank you @Mecanim-Dev for the information

    do you know if there are plans for BufferPtrs to blend shape frame data
    i see that the 5.5 alpha mentions
    • Mesh.GetNativeIndexBufferPtr
    • Mesh.GetNativeVertexBufferPtr
     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    I don't know, maybe a graphic devs would know the answer

    @Aras ?
     
  7. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    Is it possible to save new BlendShapes added with AddBlendShapeFrame to the mesh so they persist an editor restart? In my testing I lose the added shapes after an editor restart. I was thinking maybe the mesh needed to be serialized similar to the way the editor must be set dirty so that ScriptableObject data is persisted, but that doesn't seem to work.

    Thanks,
    Michael
     
  8. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    I was hoping saving assets through the AssetDatabase namespace was going to do it, but alas, still no luck. If anyone has any idea on how to commit added BlendShapes so that they persist an editor restart I would appreciate any guidance. I'm running out of things to try.

    Thanks,
    Michael
     
  9. CrazyRocksStudios

    CrazyRocksStudios

    Joined:
    Sep 29, 2015
    Posts:
    15
    Hi guys !

    We have a huge problem with retrieving deltaVertices from a blend shape frame !!

    1. We have a mesh with a blend shape exported from 3ds MAX ( it moves character face muscles )
    2. When we move the blend shape weight in editor - it works correctly as expected. ( from 0 to 100 )
    3. Then when I try to get this blend shape frame deltaVertices using:

    Code (CSharp):
    1. Vector3[] deltaVertices = new Vector3[newMeshVertexCount];
    2.                 meshToMerge.GetBlendShapeFrameVertices(shapeID,0,deltaVertices, null, null);
    3.                 for(int h=0; h<newMeshVertexCount; h++)
    4.                     Debug.Log("delta vertex no "+h+" = "+deltaVertices[h].ToString());
    => The whole vertex array is filled with zero vectors


    ----
    Additional information:

    When I add my own blend shape from code - GetBlendShapeFrameVertices() successfully retrieves deltaVertices.

    Please help !
     
    Last edited: Oct 27, 2016
  10. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Was Mesh.blendShapes completely removed in Unity 2017?
    What's the new way to create blendshapes at runtime?
    I have a skinned mesh combiner script which I would like to add support for mesh with blend shapes but I cannot find a way to do so.
     
  11. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
  12. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    No the initial design never made it into the final product because it was generating to many allocation, so we change the API a little bit to avoid GC

    You need to use the following function to add a blend shape
    https://docs.unity3d.com/ScriptReference/Mesh.AddBlendShapeFrame.html
     
  13. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Thanks a lot. Always thought that was just to edit existing blendshapes to add intermediate frames, should have read the description better.
     
  14. m-obeid

    m-obeid

    Joined:
    Aug 7, 2012
    Posts:
    9
    I'm using this method successfully to add a pre-made blendshape from one mesh to another, I perform that in the Start() function so when I run in editor the desired blendshapes are added to the target mesh, but the specified weights don't take effect on that run since the mesh didn't originally have them. So after I stop the run, the mesh preserves the added Blendshapes, and on the next run the weights do take effect and I can manipulate them in real-time.

    My issue, however, is similar to what @Crazy-Minnow-Studio describes. Whenever I restart the editor, close and reopen Unity, or build the project, the mesh doesn't preserve the added blendshape. How can I ensure that the added Blendshape is a permanent component of the target mesh so that it would have it when I build the scene? I tried turning it into a Prefab after adding the blendshape but no luck.

    Any help is appreciated.
     
  15. m-obeid

    m-obeid

    Joined:
    Aug 7, 2012
    Posts:
    9

    Any luck with committing added Blendshape so that they are a permanent component of the target mesh? I lose my added blendshapes every time I restart the scene and it doesn't preserve it on Build.

    -much appreciated
     
  16. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    I don't believe there is a way to commit added BlendShapes to a target FBX in a way that Unity won't re-import and overwrite the changes after an editor restart. You either need to track what's been added and re-apply the additions after an editor restart (this is how one of the popular character systems works), or duplicate the mesh to an asset file and perform the changes there instead of the FBX. This is how we do it in our MorphMixer asset.

    Michael
     
  17. grobonom

    grobonom

    Joined:
    Jun 23, 2018
    Posts:
    335
    hey guyz !

    i just fell in it today !
    Blendshapes are wat i was missing.... for randomly customizing toons at runtime.

    My first question is:
    - do blendshapes burden the graphic/engine execution ? and impacts on performance when shapes factors are not changed during runtime ?

    My second question is:
    - as it obviously allocates more memory than a skinnedmesh with no blendshape, is there a way to 'bake' random blendshapes factors at startup to a skinnedmesh that will still be deformed by a rig ?
     
  18. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    First question - yes, it do. But it calculated on GPU side, so it works fast. Seems like there is some optimization for "sleeping" blendshapes. Take a look on this webgl demos - each animated mesh has a tens of blendshapes, but only several has weight greater than zero, it works lighting fast.

    Second question - yes, you can bake skinned mesh on bind pose then restore skin-data.
     
    TrickyHandz likes this.
  19. grobonom

    grobonom

    Joined:
    Jun 23, 2018
    Posts:
    335
    wonderfull !

    thanks a lot @polyflow3d :)

    and happy unityint !
     
  20. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    The Mesh.AddBlendShapeFrame API seems to be bugged in Unity 2018/2019. Using Mesh.AddBlendShapeFrame, you can successfully add as many functional blendshapes as you want to a mesh asset, until you move one of the existing blendshape sliders. Any new blendshapes added, after any slider value is adjusted, are broken and have no effect on the mesh vertices. I've worked around the issue, and already submitted a bug report, but I wanted to see if anyone else has run into this issue.
     
    polyflow3d likes this.
  21. Crazy-Minnow-Studio

    Crazy-Minnow-Studio

    Joined:
    Mar 22, 2014
    Posts:
    1,399
    After submitting a bug report, and a project that allowed easy recreation of the issue, Unity has confirmed that they were able to reproduce this issue and have submitted it for review.
     
    polyflow3d likes this.
  22. DavidPeicho

    DavidPeicho

    Joined:
    Nov 18, 2019
    Posts:
    14
    Is there any API to remove a blendshape? It seems that it's only possible to add some
     
  23. TrickyHandz

    TrickyHandz

    Joined:
    Jul 23, 2010
    Posts:
    196
    @DavidPeicho the only way to do this right now would be to store all the blendshape information from the SkinMeshRenderer in a separate collection, clear all the blendshapes from the SkinnedMeshRenderer, remove the unwanted BlendShape from the collection, and then add the remaining BlendShapes back on to the SkinnedMeshRenderer. It would require some custom editor scripting to do this, but it is possible. I hope that makes sense.
     
  24. DavidPeicho

    DavidPeicho

    Joined:
    Nov 18, 2019
    Posts:
    14
    Thanks @TrickyHandz. It makes sense, but sounds highly inefficient. I perform the morphing at runtime, with morphing info coming from a server, so I wouldn't use an editor script but rather just a "normal" script. I guess I have no other way than simply deleting everything...
     
  25. liudgervr

    liudgervr

    Joined:
    May 5, 2021
    Posts:
    3
    Another question. When using this Mesh.AddBlendShapeFrame. My resulting mesh (asset) on disk is quite big. Am I missing something? It all works, but the file size is instead of a few mb's it is 135 mb's. It doesn't make sense. Is it storing all the data? Or only the delta's?