[Studio Beta] Introducing Skinning and FACS data support for EditableMesh Objects

Get ready to take your character and mesh animations to the next level! We’re thrilled to announce a powerful set of new APIs for EditableMesh that give you unprecedented control over Skinning, Bones, and Facial Action Coding System (FACS) data.

These additions will empower you to procedurally create, modify, and animate complex meshes with greater fidelity and dynamism right within Roblox.

When working with an animated 3D mesh like a character, you first need to rig it to give the mesh structure. This is done by adding “bones” to the mesh to define where and how the mesh can articulate. Think of these bones like the pieces of a wooden puppet. Next, you would skin the mesh by assigning individual vertices in a mesh to one or more bones so that those vertices would move if you moved the bones. During skinning, you also assign weights to each bone that influences a vertex since you might want one bone to influence a vertex more than another. Once you are done rigging and skinning a mesh, you can then drive the bones with an animation system which would in turn move the vertices of the mesh scaled by the individual weights that were previously assigned. This is akin to moving the strings that control the puppet.

When working with Roblox, you would traditionally do the Rigging and Skinning steps in an external tool like Blender, embed the data into the mesh and then import it into Roblox. You would then use Bone instances or Motor6Ds to address the individual bones within your mesh by name and then hook them up to the animation system or a script to drive the mesh.

With EditableMesh, you now have direct access to modify this embedded bone and skinning data right within your experiences at runtime!

Enabling the Studio Beta

In Studio, go to File > Beta features and enable the EditableMesh Skinning and FACS beta.


:bone: Full Control Over Bones!

You can now manipulate the skeleton of your EditableMesh instances with a comprehensive suite of bone-related functions. This allows you to dynamically add, remove, and query bone information, and modify their properties like names, hierarchy, transforms, and whether it is a virtual bone (virtual bones are typically used with FaceControls).

New EditableMesh Bone APIs include:

  • Creation & Removal:
    • EditableMesh:AddBone(): Adds a new bone with specified properties (name, parent, CFrame, virtual status).
    • EditableMesh:RemoveBone(): Removes a bone by its ID.
  • Querying Bone Data:
    • EditableMesh:GetBones(): Lists all bone IDs in the mesh.
    • EditableMesh:GetBoneByName(): Finds a bone ID using its name.
    • EditableMesh:GetBoneName(): Retrieves a bone’s name.
    • EditableMesh:GetBoneParent(): Gets a bone’s parent ID.
    • EditableMesh:GetBoneCFrame(): Returns a bone’s initial CFrame (bind pose).
    • EditableMesh:GetBoneIsVirtual(): Checks if a bone is virtual.
  • Modifying Bones:
    • EditableMesh:SetBoneName(): Updates a bone’s name.
    • EditableMesh:SetBoneParent(): Changes a bone’s parent.
    • EditableMesh:SetBoneCFrame(): Modifies a bone’s initial CFrame.
    • EditableMesh:SetBoneIsVirtual(): Sets a bone’s virtual status.

It’s important to distinguish these EditableMesh bones from Bone instances:

Mesh bones are data embedded within the mesh itself. They define the underlying skeletal structure, bind pose, and FACS data for the mesh and EditableMesh now gives you access to query and modify them.

Bone instances, on the other hand, are typically parented to a Model or MeshPart, and can be used by the animation system or by scripts to drive the bones embedded within meshes.

While Bone instances are live objects in the hierarchy that drive animations, EditableMesh bones are the blueprint within the mesh data that dictates how it can be deformed and animated when applied to a MeshPart (often in conjunction with systems like FaceControls for facial animation). Internal bones and Bone instances are bound to each other by their unique names. For example: The MeshPart.Neck instance will drive the runtime transformation of the EditableMesh:GetBoneByName("Neck") internal bone.


:muscle: Advanced Skinning Manipulation!

Skinning is crucial for realistic mesh deformation, and now you have direct access to vertex-bone associations and their weights. This means you can define or alter how vertices are influenced by bones.

New Skinning APIs include:

  • EditableMesh:GetVertexBones(): Returns bone IDs associated with a vertex for skinning.
  • EditableMesh:GetVertexBoneWeights(): Returns the blend weights for those bones.
  • EditableMesh:SetVertexBones(): Assigns bones to a vertex for skinning.
  • EditableMesh:SetVertexBoneWeights(): Sets the blend weights for those assigned bones. (Remember to call SetVertexBones before SetVertexBoneWeights!)

These APIs open up possibilities for in-experience character customization, and much more!


:blush: Expressive Facial Animations with FACS APIs!

We’re also introducing a suite of functions to manage Facial Action Coding System (FACS) poses, giving you fine-grained control over facial expressions on animatable heads!

Understanding FACS Poses:

Animatable heads use FACS to define expressions. Each base facial pose is tied to a FacsActionUnit. For each action unit, virtual bones can have a specific CFrame transforming them from their bind pose to that action unit’s pose. Posing the virtual bones to match the corresponding action units gives the animation system all the data it needs to animate heads on Roblox.

Sometimes, blending base poses can lead to undesirable results. That’s where corrective poses come in! A corrective pose (defined by 2 or 3 Enum.FacsActionUnit values) allows you to specify a more pleasing result for specific combinations of base poses.

For more details on FACS, check out the FACS poses reference and corrective pose documentation.

New FACS APIs include:

  • Querying FACS Data:
    • EditableMesh:GetFacsPoses(): Lists all FacsActionUnits with defined poses.
    • EditableMesh:GetFacsPose(): Gets bone IDs and CFrames for a specific FACS action unit.
    • EditableMesh:GetFacsCorrectivePoses(): Lists all active corrective poses.
    • EditableMesh:GetFacsCorrectivePose(): Gets bone IDs and CFrames for a specific corrective pose.
  • Setting FACS Data:
    • EditableMesh:SetFacsPose(): Sets the pose (bone IDs and CFrames) for a FACS action unit.
    • EditableMesh:SetFacsBonePose(): Sets the CFrame for an individual bone within a FACS action unit.
    • EditableMesh:SetFacsCorrectivePose(): Sets the pose for a FACS corrective pose.

These FACS APIs will be invaluable for creators working on dynamic facial expressions, custom character heads, and advanced animation tooling.

:hammer_and_wrench: Example Place Files

To help you get started, we’ve prepared a couple of example places:

Example 1: Simple Skinned Logo Animation

Logo_Recolor

Editable_Skinning_Logo_Recolor.rbxl (80.0 KB)

This example demonstrates how to take an existing skinned mesh (a Roblox logo cube) and use the new bone APIs to apply simple procedural animation, making it wiggle and deform at runtime. It’s a great starting point to understand bone manipulation.

Simply download and open up the attached RBXL file in Studio and hit play to see the logo dance.

Take a look at the Workspace > logo > AnimateLogo script to see how the new APIs are being used to set up and animate the logo. You will also notice that the script contains a bit of code to recolor the faces of the mesh just to prove that it is still an EditableMesh

Example 2: R15 Avatar skinning and FACS Demo


R15-EditableMeshSkinningFACSv2.rbxl (408.5 KB)

Starting with 15 separate, unskinned MeshParts, this demo shows how to programmatically generate a full bone hierarchy, apply skinning data to all vertices, and set up basic FACS poses for facial animation. The resulting avatar is structured to meet the technical requirements for UGC validation, providing a powerful example of procedural avatar assembly.

Note: This demo sometimes uses a pre-skinned/rigged avatar hidden in ReplicatedStorage to copy over positions or raw skinning weights but you are free to build your own weight painting UI or rigging UI to create everything from scratch!

Once you download and open the RBXL file in Studio, hit play and then use the buttons on the left to go through each step of the process in order:

  1. Orbit Camera: Sets the camera so it orbits around the new “avatar”
  2. Place attachments: Creates new Attachment instances with the correct naming conventions to define the R15 rig
  3. Show / Hide skeleton: Shows/Hides optional example UX to modify the locations of the Rig attachments
  4. Build R15 Rig: Adds the requisite R15 instances to the model (e.g. Humanoid) and calls Humanoid:BuildRigFromAttachments to convert the Rig attachments to appropriate Motor6Ds. Note: At this point, you could play R15 animations on the avatar but the joints would look odd since they do not contain skinning data.
  5. Set Bones: Uses the skeleton UI to create the correct bone hierarchies inside each of the 15 EditableMesh objects.
  6. Show/Hide Bones: Visualizes the actual bone structures created within the EditableMesh objects
  7. Skin Inv Distance: Uses a naive inverse distance algorithm to set skinning weights for each vertex based on its distance to the closest bones. (Note: This will not give great results and is meant to be illustrative)
  8. Avatar Inv Distance: Slightly improved inverse distance algorithm that only uses adjacent bones in the skeleton hierarchy to influence vertices. (Again, non-ideal weights but better than the previous algorithm)
  9. Authored Skinning: Transfers skinning weights from a pre-authored avatar vertex-by-vertex to the new avatar
  10. Show/Hide Skinning weights: Uses standard colors to visualize skinning weights for each vertex. Each color corresponds to a specific R15 bone to make it easier to compare results
  11. Animate Avatar: Plays a running animation on the avatar
  12. Apply FACS Poses: Transfers pre-authored FACS poses from an existing avatar over to the new avatar
  13. Animate Face: Cycles through a number of facial expressions to showcase the FACS pose data
  14. Switch to Avatar: Uses ApplyMesh to transfer all 15 meshes to your own avatar so you can run around and test out the results
  15. Run UGC Validation: Runs all the UGC validation steps to verify that the avatar could be successfully published using the PromptCreateAvatarAsync API

Each of the TextButton instances in the GUI have simple corresponding child scripts that you can use to follow along. Look under StarterGUI > ScreenGui > ScrollingFrame to find all the TextButtons

The scripts under each of the buttons call out to specific functions all housed within ReplicatedStorage > RigControl.

:construction: Known Issues

  • Loading certain meshes with skinning data into an EditableMesh may briefly slow down the engine, as it can temporarily block the main thread. This will be addressed before the full release.
  • When publishing and reloading meshes that include FACS data, there is a possibility of small skinning precision errors being introduced each time the data is saved and loaded. The level of detail should be sufficient for most uses. If you need to save and reload the same mesh many times, be aware that these minor changes could accumulate over time.
  • If all the vertex weights for a given EditableMesh vertex are zero, the vertex is placed at the origin

:rocket: What’s Next?

The launch of these Skinning, Bones, and FACS APIs is a significant step, but we’re not stopping here! Our team is dedicated to continuously improving the EditableMesh feature set and the broader tools for mesh manipulation on Roblox.

  • We are actively investigating solutions for key EditableMesh usability impediments, including Replication support, Permissions, Memory budget limits, and ID Verification requirements. While we don’t have a firm timeline to share at the moment, keep an eye out over the next few months for updates.
  • We have a few quality of life API / workflow improvements, bug fixes and performance improvements to EditableMesh that will be ready in a few weeks. Keep an eye out for a separate Dev Forum post when these are available.
  • Once we are confident that the API surface for these Skinning / FACS APIs are final, we will push to let you publish experiences with these new APIs as soon as possible.
  • We are actively working on EditableImage support for SurfaceAppearance as well as a host of WrapDeformer fixes. Keep an eye out for updates on those over the coming months as well.

We’re incredibly excited to see the innovative experiences you’ll build with these new EditableMesh capabilities. Dive in, experiment with the examples, and don’t forget to share your amazing creations and feedback with us! We are specifically looking for feedback on the API surface, naming, and common workflows.

Happy skinning and FACSing,

@L3Norm, @monsterjunjun, @ContextLost, @Penpen0u0, @lweoalawelu, @cyrian_sun, @c0de517e, @syntezoid, @portenio, @FGmm_r2 and @gelkros on behalf of the Geometry team.

157 Likes

This topic was automatically opened after 10 minutes.

Still waiting for it to be usable in a normal place to people that aren’t id verified. This does seem quite useful though for custom custom characters.

(When will remove vertex come back?)

30 Likes

Hoping the precision issues get resolved :pray:
I run into them frequently

These are some great APIs!

3 Likes

This is great! …but one thing I feel is missing.

Bulk APIs. I would absolutely love a EditableMesh:SetBoneCFrameBulk(), and EditableMesh:SetUVBulk(). This isn’t even just for performance - it’s to make parallelization & integration with algorithms such as FFTs and Gerstner waves easier. However, the added performance is definitely great.

This is amazing though, and I’m really really happy about it. Bone CFrames makes normal data calculation fast & easy to integrate with existing bone ocean systems.

8 Likes

Will ID verification requirements also be investigated and possibly changed/removed for EditableImages, audio upload limits, Cube 3D, UGC uploading, and whatever other features that don’t strictly relate or revolve around requiring someone’s identity and age?

8 Likes

We’re aware of the frustration around this, and it’s something we’re working on:

We got rid of RemoveVertex because of some unresolved questions about how it should behave.

RemoveFace will always delete the face you give it. But how should RemoveVertex behave if the vertex is in use by some faces? We didn’t want the faces to be left in an invalid state, referencing a deleted vertex. Should all the faces also be deleted? Or should RemoveVertex only remove the vertex if it’s not in use?

We decided to only allow removing a vertex if it’s not in use. Since we also have :RemoveUnused, we weren’t sure if there’s a good use case for a separate remove vertex method

9 Likes

THIS IS HUGE

I’ve been waiting months for this, so great to see it came out before I was expecting it to
Will there be live closed beta applications so I can use it in real games?

3 Likes

Really great for future animated heads!!! Good work

4 Likes

Oh my goodness, this is incredible! This is such an exciting update!

3 Likes

What about the ID verification frustrations for UGC/marketplace uploading, audio limits, EditableImages, Cube 3D and whichever other features don’t actively require it? Will those also be investigated?

Now yes, I understand E-Commerce, restricted content and stuff of that sort requiring it, that’s not the problem
The problem is that too many features, like the ones I mentioned are gatekept behind this requirement, and I hope that this can be addressed

8 Likes


Is he Dwayne Johnson?

13 Likes

Very cool tech! Do you foresee us having the ability to use shape keys as well in the future? Being able to change the shape of meshes at runtime predictably AND the collision box would be huge.

4 Likes

This feature is very nice!

I’ve been experimenting with the new Beta features (even pre-release via fast flags), and I absolutely love the possibilities. One thing I keep running into, though, is performance pain when I try to drive per-vertex deformations (e.g. a real-time shape-key system) on skinned meshes.

This comes down to a few reasons that I found out by reverse engineering Roblox Studios C++ code using IDA.

The Problem:

Every time I modify any vertices on a skinned EditableMesh while it’s animating, the engine treats it as a full “bind-pose” change! That triggers a FastCluster rebuild, a full re-upload of the mesh, and a complete skinning pass every single frame! This drops me on a RYZEN 7 7800x3d from 240fps, to 60fps! On mobile platforms this effect is even worse and can sometimes get you sub 10fps!

The result:

frame-times spike dramatically and it becomes completely unusable for real-time morphs. Which brings me to a possible feature request.

Feature Request:

Would it be possible to expose an “editable‐delta” mode a way to register per-vertex offsets on top of the existing bind-pose, without ever mutating the bind-pose itself?

Basically internally, this could hook into the CPU-skinning or GPU-skinning pass as an additive step

  • Keep the original bind-pose Vertex Buffer static.
  • Store only the delta arrays in a lightweight buffer.
  • At skin-time, apply pos = bindPosePos + delta * weight → then skin

Because the current implementation lacks this, this basically makes ANY sort of shapekey type system impossible to have any kind of reasonable performance.

Here is a video example of it running, the head is a separate meshpart that is turned into a editable mesh, Instead of using wrap deformers. I am using the actual head and multiple sets of editable meshes that each define a shapekey pose. the animation itself contains data for what each shapekey value is at each keyframe. These are then set and its all blended together, the actual lua side of things are fast since I’m using parallel lua, at most this takes like 2ms.

I would really appreciate if a engineer can give me a response on this, because this problem really restrict such a system from existing. Shapekeys have been requested for years, but never added. Now that we somewhat can do them, the performance isn’t great which makes this unfeasible to use in live games.

29 Likes

When are we getting shape keys on normal meshes?

5 Likes

I’d do you one better, let shapekeys handle the dynamic head! That way I can skip the torture chamber that is weight painting and bone rigging. Save me from my suffering, please…

5 Likes

I wish Permissions were accepted towards the ROBLOX-made avatars, it would be cool (since Roblox gave away those avatars, or atleast the free ones), or even the public Meshes in the Toolbox. (since you purposefully published the mesh, meaning that the person using can do whatever he wants with it).

Permissions at this moment are just way too strict, I feel like.

4 Likes

Extremely exciting stuff, however we desperately need native shape key support.

2 Likes

this is cool, but let us move verts in bulk. moving them 1 by 1 is too slow

4 Likes

@FGmm_r2 see this comment !!!

4 Likes