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

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.

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

Today I’ve faced a rather difficult problem to solve. Creating model in Blender, animating it with armature and exporting the animation to 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 traveling up and down.

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 to the world in correct place.
    two_cubes
  4. Join these cubes meshes – 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 its bones

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

  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, select the first bone and duplicate(Shift+D) and grab the new bone so the result would look like so:
    two_cubes_two_bones

Having those let’s go on to parenting.

The key to understand skeletal animation and skinning in Blender is the following rule:

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 the bone responsible form moving them.

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 at export time. In case with Blender the parenting must occur to see the changes when moving the bones and actually creating the animation but THREE.js ignores that information.

Now we’re at the point where we can do one of two things: we can parent the boxes mesh 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 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 demands all the vertices of a skinned mesh to be assigned to vertex groups 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 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 and you can make a mistake while assigning. In this case you will need to take care of more things

In this tutorial I will show you both methods because they can be both usefull.

Naming bones and vertex groups

This is very important rule, and you should stay with it if you don’t want to get really frustrated. The matter has to do with a specific bug either on THREE.js exporter or inside the framework script. This bug doesn’t takes into account that the name of a vertex group or a bone may start with a number. So clearly:

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

The recomended naming convention is to use only letters and underscores, but numbers are also allowed but not in the first place. So:

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

Parenting with “Armature deform with automatic weights”

  1. Unselect everything in the 3d space. The select the boxes(RMB) and “add select” the armature (Shift+RMB)
    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 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 you should see:
    two_cubes_parented_v_groups
    I
    n the vertex groups panel now are two groups: Bone and Bone.001, they were created automatically when we were parenting the cubes mesh to the armature bones..
  2. To check if the vertices belong to correct groups: first unselect any selected vertices with “A” on the keyboard.
  3. Then click one of the group and press “select” in the “vertex groups” subpanel. You should see the vertices of a box selected. Rotate around and check if all vertices of a cube 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).

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 the vertex group. I won’t cover this in step by step tutorial. I think you will figure it out (or already are able to do so) after explaining how to manually create vertex groups related to the bones and assign vertices to these groups.

Manual creation of vertex groups

The other way, which may be simpler in this case with two cubes in one mesh is to manually create the vertex groups and assign vertices to them.

This method would be especially usefull when rigging non organic, technical shapes, where the vertices are easy to select. The usefull way to select them is “select linked’ tool to select vertices linked to each other.

Suppose we are at the point where the two bones in our example are not yet parented or related in any other way to the two cubes – single object.

  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. Depending on the bone yoy’ve selected you should see it’s name in the lower left corner of the screen:
    bone_name
    There you can see the name of the armature you are currently editing and the name of the selected bone. Remember the names. 
  2. Enter the “object data” panel in the “properties” window. You should see “vertex groups” panel with no groups.
    vertex_groups_empty
  3. We need to create the groups with the same names as the names of bones rigging their vertices. Press the “+” button. You should see a new group appeared. 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 assign vertices to the groups. We have to select the vertices to be rigged by a particular bone, select the group of the bone in the vertex groups panel and click “assign” button.
    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 there is no in-Blender relationship between those. THREE.js would deal with it by using vertex groups names and bones names but in Blender this isn’t enough.

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

  1. Select the cubes in object mode, go to “object” menu in “properties” panel. In relations subpanel you should see “relations” subpanel:
    relations_subpanel
  2. Click on the parent box and select the armature object, then click the dropdown 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 that is related  to the model has to have at least one keyframe

Wihout this you should expect incorrect results when running animation in 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 at the earliest keyframe found in the file and end in the last found, which may be on a different bone.

Knowing that we can start creating animation:

  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”). Select “LocRotScale”.
    insert_keyframe
  3. Move to frame 50 on the timeline with the bone seleced. Move the bone up and insert a keyframe.
  4. Go to frame 100, move bone back to original position and insert a 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 in frame 1 and insert a keyframe

To see most similar animation in Blender to what will be happening in THREE.js you can move to frame 100, move the mouse cursor over the timeline window and press “E”. This will set the end of animation to frame 100.

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

To see what we are talking about here is a version rendered in Blender:

animation

Scaling and unparenting and checking animations.

Before actually exporting you have to do some more things.

Keep in mind that..

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

In my experience 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 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.

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

This is very important because if you will not do so the model will be offset in THREE.js 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 currently edited Blender file, which can be an old animation, currently unused. Threre 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 in this example. 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 dropdown for available actions, click on it and check if there are unused action datablocks, which has a 0 number to the left In this example there are four unused action datablocks.
    action_datablocks

If there are any unused action datablocks you have to manually delete them. This is done by reloading the current file. To do so:

  1. First save the file
  2. Go to File menu, click Open recent and open the file you are already editing.

The unused datablocks should disappear.

There is also another situation: when you created many actions for example by keyframing two or more different objects. You need to select those object and in DopeSheet action editor – unlink them by pressing the “X” button next to the available actions dropdown. Then reload the file as above.

Reseting 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 the mesh and the armature. To do so select the mesh 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

  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 window should look like following:
    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 to 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.

About these ads

24 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