Creating skeletal animation in Blender and exporting it to three.js.

Updates (most recent on top):

UPDATE: I’ve corrected some spelling and language specific problems. Now, this tutorial should be easier to read and understand (at least that’s what I hope for). 

UPDATE 2: Currently THREE.js exports multiple actions using blender exporter, so this tutorial in not suitable for exporters for THREE.js versions r62 and higher. It should work well with versions r56 up to r61

UPDATE: Originally this tutorial was written for THREE.js r56 and Blender 2.65 but lately I’ve tested it with THREE.js r60 and Blender 2.68a and it worked (actually it also worked with THREE.js versin “r61dev.”. whatever it means), so I believe that it works for the versions in between also.

Today I’ve solved a rather puzzling problem: creating model in Blender, animating it with armature and exporting the animation for THREE.js (r56) JSON format.

I was working on for 2 days now and it was really a harsh job to be done, especially that THREE.js is still in alpha version and a lot of features are not stable and fully reliable. So now I’m gonna explain how to perform the mentioned task.

For this I’m using Blender 2.65, and exporter for this version found in THREE.js package (https://github.com/mrdoob/three.js/).

In this tutorial I assume that you know JavaScript at intermediate level and are familiar with Blender basics.

The animation will be made of 2 cubes moving up and down in an alternating motion.

The Blender part

Creating objects and armature

  1. Start Blender, delete the default cube.
  2. Add two cubes and place them side by side.
    two_cubes
  3. Select one of the cubes, and press Shift+S and select “cursor to selected” This will let us add an armature in correct place later on.
    two_cubes
  4. Join these cubes into one object: select them both and press Ctrl+J.
    two_cubes_joined

Before continuing, you should know that:

There could be only one armature responsible for rigging the objects and many objects controlled by it’s bones

This is because if you add another armature and animate it’s bones you will end up with more than one action in Blender, and THREE.js exporter exports only one (the first) it founds in Blender file. So:

  1. Add an armature bone: press Shift+A in the 3d view and select Armature->Single bone.
    Now in the wireframe view (press Z to switch between display modes) you should see the bone “in” the cube.
    two_cubes_joined_w_armature
  2. Now we have to create the bones setup. Go to edit mode with the armature selected. While there – select the first bone and duplicate it(Shift+D) and grab it to the left so the result will look like following:
    two_cubes_two_bones

Having those let’s go on to parenting:

The key to understand skeletal animation and skinning in Blender is to follow the a single:

The vertices that are to be moved by a bone have to be assigned to a vertex group which name is the same as the name of bone responsible for moving these vertices.

So for example: if you have vertices that you want to control by a bone named “somebone”, you have to create a vertex group called “somebone” and assign vertices to that group.

This is the only requirement for THREE.js – to know which vertices are belonging to which bone, when exporting to JSON format, no other information is required – the skinned mesh doesn’t require to be parented to the armature in Blender at export time. In case with Blender the parenting must occur for us to see the changes when moving the bones while working on the animation, but THREE.js, working in the browser – ignores that information.

Now we’re at the point where we can do one of two things: we can parent the boxes to the armature with automatic computing of the vertex weights or we can create vertex groups manually and assign vertices to them by hand.

In practice the decision is highly depending on what is going to be rigged: if you have some simple or technical meshes do it manually, if you have a highly complicated organic mesh – you will want to do it automatically.

But.. the first method is a little more risky because the automatic creation of vertex groups and computation of their weights may be inaccurate and..

 THREE.js requires that all the vertices of a skinned mesh have assigned vertex groups to them and all vertex groups to be named after the corresponding bone.

In case of automatic parenting the vertex groups are created and weights calculated. The problem may be that, during the process,  some vertices will not be assigned to vertex groups. So in this case  it’ll be likely that you’ll need to correct the results manually if some of the vertices are out.

The second method – of manually assigning vertices to vertex groups may be tedious in some cases, though you may find it more predictable.

In this tutorial I will show you both methods (which on the side of things – you should already know, being familiar with Blender).

Naming bones and vertex groups

So before going straight into it, we need to name the bones and vertex groups adequately.

But… there is a little quirk. The matter of it has to do with a specific bug I’ve encountered.  This bug makes it impossible to export an animation which is using vertex groups with names that have a number at the beginning. So clearly, since we will need to name bones and vertex groups the same:

The names of bones and vertex groups can’t start with a number

So, taking into consideration that we may use letters, underscores and numbers(not as first character):

  • this is incorrect: “1st_floor”
  • this is correct: “first_floor”
  • and this is also correct: “floor_1st”

SIDE NOTE: On the technical side of things this may not really be a bug if the names are then used in JS as an argument to eval function (and if so they can’t start with a number).

So after another obstacle removed (trust me it was like hour of time lost trying to figure out that the names are wrong) we can actually do something – name our bones. Well, actually we will leave their names as they are: “Bone” and “Bone.001”. About the vertex groups – I will show you in the following sections.

Parenting with “Armature deform with automatic weights”

When parenting using automatic weight calculation – naming of the vertex groups is actually left to the parenting mechanism. Continuing the example:

  1. Unselect everything in the 3d view (A). Then select the boxes object(RMB) and add the armature to selection (Shift+RMB) (it’s important to follow the order in which objects are selected: Boxes first, armature second).
    cubes_and_armature_selected
  2. Now press Ctrl+P and select “Armature deform with automatic weights”
    automatic_weights_parenting

At this point you could start making animation – moving the bones and keying.

But before doing so you should check if every vertex is attached to a vertex group. This will most probably save a lot of problems further (as I mentioned before).

  1. To do so you need to select the cubes, go to the edit mode and switch to “OBJECT DATA” view in “PROPERTIES” panel. This is what I’m talking about:
    two_cubes_parented_v_groups
    I
    n the vertex groups panel now are two groups: Bone and Bone.001, they were created automatically – as I told you, when we were parenting the cubes mesh to the armature bones..
  2. To check if the vertices belong to correct groups: first un-select any selected vertices with (A).
  3. Then click one of the groups and press “select” in the “vertex groups” subpanel. You should see the vertices of a box selected. Check if all vertices of a cube are selected by rotating the view around.
    The following image shows how will the viewport look like when the vertices from the “Bone” vertex group are selected:
    two_cubes_one_selected
  4. Repeat the process for the other group (steps 2 and 3 above – deselect vertices and select the other vertex group, check if all vertices selected).

If all vertices in the object made of two cubes belong to one of the vertex groups you can start animating the bones in pose mode. If not you will have to assign the spare vertices to a vertex group. I won’t cover this in step by step tutorial. I think you will be able to easily figure this out after I explain how to manually create vertex groups and assign vertices to them.

Manual creation of vertex groups

The other way, which may be simpler in this case – with two cubes as a single mesh – is to manually create the vertex groups and assign vertices to them (or speaking in other words – put vertices into vertex groups).

This method would be especially useful when rigging non organic, technical shapes, where the vertices are easy to select and the parts of mesh are clearly distinguishable. The easy way to select parts of mesh that are not connected by an edge is to use “select linked” tool. It will do just that – select vertices that are linked together by an edge.

So suppose we are at the point where the two bones in our example are at the state, they were before the previous section of the tutorial – we have the two bones and the single object made of two cubes; no more: no vertex groups, and the bones aren’t in any parent-child relationship with the boxes. In this case we have to manually create the vertex groups, name them and assign vertices to them:

  1. First check the names of the bones of the armature. Go to the object mode, select the armature by clicking at one of the armature’s bone and go to edit mode again and select the bone the name you want to know. What you will see is the name of the armature and the bone you’ve selected – in the bottom-left corner of 3d view (remember these names):
    bone_name
  2. Now enter the “OBJECT DATA” panel in the “PROPERTIES” window. You should see “VERTEX GROUPS” panel empty – with no groups.
    vertex_groups_empty
  3. We need to create the groups with the same names as the names of bones. Press the “+” button. You should see a new group appear. Select the group and enter a new name for it and press “enter” to confirm the new name:
    naming_groupnamed_v_groups
  4. Now we need to put vertices into these groups. For each bone there is in the armature – we have to select the vertices that we want to be rigged by that bone and assign these vertices to a vertex group with the same name as that bone, vertex groups which we created in previous steps. Here is what it will look like for the “Bone.001”:
    assign_vertices
  5. Repeat process for the “Bone” vertex group.

Parenting the cubes to armature with “Armature” relation

If you’ve choosen the manual way you will see now that moving the bones in pose mode doesn’t makes the cubes move, so we can’t do the animation. The reason is that Blender is blind to these changes – they are only used by the THREE.js exporter. For our working purposes we need to actually see the effects of rigging in Blender.

Thus we have to parent the cubes object to the armature with “armature” relation:

  1. Select the cubes in object mode, go to “OBJECT” menu in “PROPERTIES” panel. In there you should see “relations” subpanel:
    relations_subpanel
  2. Click on the “Parent” entry and select the armature object, then click the drop-down below it and select “Armature”. The result should look like so:
    armature_relation

If, after parenting, the cubes are not in place with bones, go to object mode, select the object with cubes and align it to the bones.

Now we can start animating the bones.

Animation

The animation here means that we will be keyframing the bones in pose mode. At the beginning one key information:

Every bone has to have at least one keyframe associated with it’s transform properties.

Without this you will end up with incorrect results when running animation in the browser with THREE.js.

The other thing you should be aware of is that:

The animation will start at frame where first keyframe was found and end at the frame where last keyframe was found.

This means that you can have bones with one keyframe but the animation will span wider if you have other bone with two keyframes far away from each other. The keyframes are searched globally,  which means that the animation will span from the earliest keyframe found to the last found – those may be set on a different bone.

Now we’re good to go:

  1. Select the armature and go to pose mode
  2. Select the first bone, move to frame 1 on the timeline . Place the cursor in 3d view and insert a keyframe (“I” – big “i”). Select “LocRotScale”.
    insert_keyframe
  3. Move to frame 50 on the timeline with the bone seleced. Move the bone up (you will notice the cube following it) and insert a keyframe.
  4. Go to frame 100, move bone back to original position and insert another keyframe.
  5. Deal with the second bone. Go back to frame 1 select second bone, move it up and insert a keyframe.
  6. Go to frame 50 move the bone down and insert a keyframe
  7. Go to frame 100 move the bone to the same position as it is in frame 1 and insert a keyframe

To see the animation in Blender you can set the end frame to frame 100: move the mouse cursor over the Timeline window to frame 100, click LMB and press “E” (keep in mind, that we’re talking about the animation in Blender: THREE.js will still respect only the positions of bone’s keyframes within the timeline for the animation, not the Blender’s start and end markers).

Now playing the animation (Alt+A) you should see cubes moving up and down.

To see what we are talking about – here is the animation rendered in Blender:

animation

Scaling and unparenting and checking animations.

Before actually exporting you have to do few more things.

Keep in mind that..

You won’t be able to scale anything after exporting is done.

That is – I had a problem when trying to change scale in JSON file. The pivot points were simply in wrong place, so scaling models in THREE.js will probably also break the rigging.

And the key matter:

The rigged object must be at its rest pose when exporting

Which may mean that you will have to do one of the following:

Unparent the skinned(rigged) object from the armature “Armature” parent

and if you were working with rigging using “Armature” modifier

Remove the armature modifier from the rigged object

If you’ve done so, playing the animation (with Alt+A ) will show only the bones moving and the mesh as unchanged, but still – will export correctly.

The rest pose of course may be at some frame, and if you know that frame, you will have to export your model at that frame.

This is very important because if you will not do so the model will be offset inside the browser in a matter that’s relative to it’s “rest pose”.

Another important step is to:

Check if the animation you are exporting is the one you want.

Blender keeps track of many animations – called “actions”. In case of THREE.js – only one animation can be exported to .js (JSON) file. This actually means that the only animation present in the .blend file has to be the one you want, otherwise the THREE.js exporter may confuse things badly.

There is no way of having more than one action(animation) in THREE.js exported from Blender at the current time of writing (THREE.js release r56)

To make it happen you need to delete unwanted actions from the Blender internal datablock structure.  In a fresh files, where there was only one animation done there’s no such a need.

If you are curious – the real problem is that THREE.js exporter doesn’t export all animations or the current one, but only the first animation found in Blender file, which can be an old animation, currently unused. There may be a way to make the animation we want first, but for the sake of simplicity lets go and delete the animations we don’t need.

To explain this I’ve made some “fake” empty actions. So, to check if there any spare “acitons”:

  1. With the armature selected, go to “DopeSheet” window:
    dope_sheet
  2. Select action editor:
    action_editor
  3. In the header: you should see a drop-down for available actions, click on it and check if there are any unused action datablocks, which have a “0” number on their left side. In this example there are four unused action datablocks:
    action_datablocks

What you have to do is to manually delete them. This is done by reloading the current file:

  1. Save the file (CTRL+S)
  2. Go to File menu, click Open Recent and open the file (which, actually, you are already editing).

The unused datablocks should disappear.

There is also another case: when you’ve created many actions for example by keyframing two or more different objects. You need to select those objects in 3d view(or outliner or elsewhere), and in DopeSheet action editor – unlink them by pressing the “X” button that is present next to the available actions drop-down. Then reload the file as I’ve explained.

Resetting position, rotation and scale

The last thing and probably the most important for the happy ending is to reset location, rotation and scale of the mesh and the armature. This step is not required if the mentioned are at their defaults. This must apply for both: the mesh and the armature. To do so select the object with your mesh, go to object mode and press CTRL+A, then select “location”. Repeat this for “rotation” and “scale”. Do the same for armature. Now you’re (by chance of 99%) done.

Exporting

This is simple:

  1. Go to object mode and select everything (“A” on keyboard)
  2. Go to the File menu, select Export -> THREE.js
  3. In the exporting window select the name of the file and it’s path.
  4. The THREE.js export settings panel should look like following, if it doesn’t correct the settings so they match:
    exporting_setup
  5. Keep in mind that the following options must be enabled: “skinning”, “bones” and “skeletal animation”.
  6. Export the JSON file.

Summary of Blender part:

The checklist:

  1. The object(s) has every vertex assigned to at least one vertex group
  2. Each vertex group has a name corresponding to the name of bone that controls it
  3. The correct animation is exported
  4. Every single bone must have a keyframe
  5. The animation starts at first keyframe found and ends at last keyframe
  6. The model is in its “rest pose”
  7. No spare animations “actions” are registered in Blender so that only one is the one that will be exported
  8. The location, rotation and scale of mesh and armature are reset

Known limitations:

  • Only one action can be exported.

Advantages over morph animations:

  • Low file sizes

Blender example file to download (based) on this tutorial:

Blender file ready to export for three.js

The exported file for three.js:

Json file ready to load in three.js

Three.js

To display the model animation there are some things needed to be done. First we need correct setup for the scene, along this we need to load model by:

var loader = new THREE.JSONLoader(); 
loader.load("animation.js", createSkinnedMesh)

Create a SkinnedMesh instance based on geometry and materials loaded from the JSON file and enable skinning on its MeshFaceMaterial materials collection:

function createSkinnedMesh(geometry, materials) 
  { 
  skinnedMesh = new THREE.SkinnedMesh(geometry, 
      new THREE.MeshFaceMaterial(materials)); 
  enableSkinning(skinnedMesh); init(); 
}
function enableSkinning(skinnedMesh) { 
   var materials = skinnedMesh.material.materials; 
   for (var i = 0,length = materials.length; i < length; i++) { 
       var mat = materials[i]; mat.skinning = true; 
   } 
}

At the end we need to add the SkinnedMesh to the scene, push animation data of its geometry to the THREE.AnimationHandler and finally create Animation instance and play it with play() method.

scene.add(skinnedMesh);
THREE.AnimationHandler.add(skinnedMesh.geometry.animation);
animation = new THREE.Animation(skinnedMesh, 
     "ArmatureAction", 
     THREE.AnimationHandler.CATMULLROM)
animation.play();

Somewhere in the application we need to run the application animation loop so the last thing to do is to update the animation in it:

animation.update(deltaTimeMS); // deltaTimeMS - delta time in milisecond                                  since last update loop execution

The complete example file:

The html file with animation explains more. It is populated with comments relating the animation stuff, you can download it here:

THREE.js scene with skeleton animated model.

The complete package

(ZIP with Blender model, JSON model, and Example scene):

Tutorial package.

Summary and notes:

This tutorial covered the basics concepts of rigging for THREE.js it deals with one object parented to one armature. Also it doesn’t covers the skin weights topic.

26 thoughts on “Creating skeletal animation in Blender and exporting it to three.js.

  1. Thanks for this tutorial, it will really help me :)

    Have you an idea in THREE.js how to move a bone programmatically (without using animations). I’m trying to create a human model which will aim to the mouse direction but I can’t figure out how to move his arm bone and update the mesh.

    • Well I can’t give You a straightforward answer but first thing I would do is to search the structure of a Mesh object, find the bone which I need to alter and then move it. Although that may be not the case, because there could be more things to do after just changing that bone position – simply can’t tell if it will move appropriate vertices. :)

      • There must something to do afterwards, but I tested a lot of things after changing the bone properties (rotation, position, matrix) and I can’t figure out what to do (settings the rotationAutoUpdate and matrixWorldNeedsUpdate is not working)

        Thanks for your help anyway :)

  2. Thanks for the article, I just was learning rigging for three.js and wrote my own article about that stuff.
    One thing I’ve mentioned: if you rotate the armature from its initial, vertical, position, the whole geometry will be streched. To avoid this, you need to align the first bone using its tail position.

      • It’s r60. And it’s not about just rotating, but positioning too. Seems like any alignment except using tail/head position will break the animation.

        Also, rotating the mesh in three.js will cause bones axis inverting.

      • I’m not too sure what you mean but all I know is that if the armature or the model are rotated/scaled/moved at all in object mode, everything screws up. Things get really stretchy and deformed. As long as you do your transforming on the geometry itself in edit mode, things seem to work out. That, together with https://gist.github.com/kontan/4484676 has allowed me to finally have animated models with multiple actions.

  3. Actually I was targeting this question to @Roman Liutikov :) nice to know that there is a multiple actions exporter for THREE.js though. I think that the mesh object and armature should have applied rotation, location and scale before exporting. It’s done using CTRL+A. I updated this article today to mention this. I think it should solve any issue related to rotated armatures and meshes.

    • Looks like it works, nice! But it’s still more practical for me to align the armature manually, I mean the first bone, when starting skinning. This will avoid mesh aligning after parenting. I can predict somebody doing a heavy skinning, then applying parenting and things moved somewhere, so it will be kind of hard to align a mesh with such an armature.

      Also I’ve noticed that there is always a support bone need to be left in order to make animation work properly (except simple skinning like in your example). I’ve tried to avoid this with locking the bone location, or just manually change its rotation, but nothing helped, animation breaks.

      As for a new export script, how should I load multiple animation? I guess creating another instances of Animation with names of the anims from Blender.

      • About the “support bone” – I don’t know what You actually mean, but if You mean that every bone has to be connected to other bone so that their head and tail position matches – and form a chain as a result – then You’re wrong. The skinning is precise to the point. If bones are parented and they are away from each other – thing’s work as usual. THREE.js correctly implements the parented but not connected bones.
        About Your predictions, or actually – imaginations – parenting objects in Blender rigging setup for THREE.js export could have very bad implications:
        First – as far as object can have only one parent – parenting it to something else than armature with armature modifier or armature relation during rigging would make it impossible to see changes during rigging process.
        Secondly – using parenting between meshes after removing parenting with armature (what is possible) is a very stupid way to do things – one would have to re-parent all the objects every time he wants to switch between viewing the animation and rotating the whole scene.
        And most important is that it doesn’t make any sense to use parenting between other objects than armature/mesh because moving intermediary parents would give no result – because the bones are responsible for movement, and actually it would break the animation because now – the original vertices would be offset from the mesh.

        In order to transform (translate/scale/rotate) the whole rigged scene – every object in the scene (including armature) has to be transformed along a single point of pivot. This is done simply by selecting everything in 3d view, selecting the desired pivot point (any except “individual centers”) and performing the actual rotation.
        Though there is simpler way of doing this which will probably work – using the armature as a parent and rotating only the armature while the armature is parented to the object using armature relation and exporting everything at the frame 0.

        So please think, not guess, as this was always more reliable way of doing things, and also won’t confuse others – including myself.

        About the export script with multiple animations – I don’t know, You should ask the author or read the source thoroughly.

      • Thanks, I’m not a 3D guy actually, good to know things.
        I was talking about usual parenting, which is need to be done once. Also, I mean “support bone” is a first, unused bone, of the armature.

      • I don’t know what You mean by saying “usual parenting” – if You mean that You want to rig something that You have organized before, using parenting – fact is that You will have to un-parent everything first so You can parent all the objects to one armature. This also means that You will have to apply the rotation/location/scale of every parent object in the scene before removing all the parenting.

        About the support bone – I’ve found this not to be true also. I don’t know Your case but I’ve just made a little more than trivial skinning. The files for this example can be downloaded here: https://dl.dropboxusercontent.com/u/40322040/no_support_bone.zip

  4. Thanks for the tutorial ! I tried to follow he steps you said . and every thing looks good in blender , But when I export the 3js file , i can only see 1 bone in the file when open it in text editor . I have check the settings at the export window , they all look good to me . Any clue what I might be doing wrong ? Any help would be hugely appreciated . Thanks in advance :)

  5. Hi, really thanks for the tutorial ! it’s great! I have a problem. I followed all steps, but my code in Three.js returns “TypeError: data is undefined” (in THREE.AnimationHandler). I tried to fix it myself with different ways working on Blender and Three .js but the Skinned Mesh is invisible or visible without animation. Have you got some ideas about this problem?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s