Tutorial 06

Facial Rigging.

 download material files

General info:

  • This tutorials simply explore a facial rig using curve as deformer to simulate muscle like”. Using a double hierarchy it will allowed the animator to animate
    simple preset emotion created using SDK. It will also have the possibility to move himself the facial to shape a desired expression.
  • In order of helping yourself around, please source jd_facialScript102.py. They are simple scripts to help you along with the facial rigging process.
    They will work no problem as long as you naming convention follow mine. “I didn’t have time yet to make them bullet proof.”
  • If you close Maya and continue to work on your setup, please source again.

Step 01 Create a facial camera.

  1. Create a new camera call camFacial
    • Position the camera in front of the character head
    • Group the camFacial to a new group call camFacialCons.
    • Parent constrain camFacialCons to the head_ctrl.
    • Lock all TRS for camFacialCons.
    • Parent the camFacialCons to the ctrl_grp node.
  2. Select camFacial and active the limit information in the transformation tab.
    • Limit all rX, rY, rZ to the current position
    • Find proper setting to limit the translation ot the camera movement around the face region.

Step 02 Duplicate the head_geo and create a link to the rig using blendShape.

Now we are creating a head_geometry copy, so we will be able to setup all our facial feature on it and easily pass those information back to the full rig by activating a blendshape.

  1. Duplicate the head_geo and rename it head_geo_facialSetup_base. Be sure the geometry like the eyeBrow_geo are also duplicate with the face geometry.
    • Translate up the head above 5 to 15 unit in Y.
    • Group head_geo_facialSetup_base and rename this new Group facialRig_grp. Be sure this new group are not children of any others node.
  2. Create a new locator call lf_eyeBall_locPosition. This locator will be place at the same location of the eyeball_geo. To do so….
    • Temporally constrain without offset the lf_eyeBall_locPosition to the eye geometry position
    • Now that we get the locator position of the eye delete the constrain as we simply use this method to obtain the exact eye position.
  3. Create a BlendShape between both head_geo
    • Select head_geo_facialSetup_base
    • Select head_geo
    • Then create a blendShape node call facialRig_link.
    • On facialRig_link set the head_geo_facialSetup_base blendShape weight to 1.
  4. Parent and clean all new element by parenting them to facialRig_grp

Step 03 EyeLid setup.

Using joint and proper LRA we will setup both the upper and lower eyeLid for our character

  1. Create a single joint call headRig_jnt and position it in the center of head_geo_facialSetup_base.
  2. Create and position, two new joint call lf_upperEyeLid_jnt and lf_upperEyeLidEnd_jnt. Draw from the lf_eyeBall_locPosition terminating in the upper eyeLid topology position. (Refer to below Picture)
  3. Create and position, two new joint call lf_lowerEyeLid_jnt and lf_lowerEyeLidEnd_jnt. Draw from the lf_eyeBall_locPosition terminating in the lower eyeLid topology position. (Refer to below Picture)
  4. Create a single new joint call lf_eyeLid_jnt. Same position as the lf_eyeBall_locPosition. Change the radius to bigger so you can differen
    • parent lf_upperEyeLid_jnt and lf_lowerEyeLid_jnt to lf_eyeLid_jnt.
    • Set the proper LRA to all created joint
    • parent lf_eyeLid_jnt to headRig_jnt.
  5. Mirror lf_eyeLid_jnt setup to the right side of the character.
  6. SmoothBind together the headRig_jnt and the head_geo_facialSetup_base.
    • On head_geo skinCluster. Turn on use component, so the original face will be deform also using cv influence.
    • On head_geo_facialSetup_base skinCluster. Turn on use component, so the original face will be deform also using cv influence.
  7. Now simply block out the paintWeight value “Can be refine later”

Watch for the rotation and placement of the joint lf_upperEyeLid_jnt lf_lowerEyeLid_jnt…..

Step 04 EyeBrow setup.

Using curve as influence over a smooth bind. This is the general concept behind the eyeBrow creation.

  1.  Create two curve from the center of the face call lf_eyeBrow_crv and rt_eyeBrow_crv.
  2. Select both curve and create a none relative cluster call centerEyeBrow_clstr.
    • Select both curve all cv components
    • Go to the component Editor to edit the influence. Remember Those setting will be different for your own character.
    • Group centerEyeBrow_clstr to itself to become centerEyeBrow_clstr_grp
    • Parent centerEyeBrow_clstr to head_rig_jnt.
  3. Select the lf_eyeBrow_crvand create 3 cluster with the relative mode check on.
    • Rename each cluster as below
      • lf_eyeBrow_inside_clstr
      • lf_eyeBrow_middle_clstr
      • lf_eyeBrow_outside_clstr
    • Group together all new created cluster. Rename it lf_eyeBrow_clstr_grp
    • CenterPivot the new created group lf_eyeBrow_clstr_grp.
    • Parent lf_eyeBrow_clstr_grp to lf_eyeBrow_crv node.
    • Edit Membership of all new created cluster so the cluster can manibulate all lf_eyeBrow_crv cv’s.
    • Select all cv’s for lf_eyeBrow_crv……
      Go to the component Editor to edit the influence.Remember Those setting will be different for your own character, but here an examples.  
  4. Replace the pivot for each cluster………………………… “COULD BE FINE TUNE LATER BEFORE OR DURING THE SDK CREATION PROCESS”
  5. Add lf_eyeBrow_crv as influence to the head_geo_facialSetup_base
    • Parent lf_eyeBrow_crvBase to lf_eyeBrow_crv.
  6. Repeat all previous step for the rt_eyeBrow setup.

Step 05 lips setup

  1. Create two curve for the upper and lower lips deformation, call lowerLips_crv and upperLips_crv.
    • Select both curve and add influence to the head_geo_facialSetup_base. “Lock weight to 0 if you won’t affect previous paintWeight.”
    • Paintweight the lips value.
  2. Select both curve and create none-relative cluster call: Be sure all this cluster are also manipulating they’re neighboring cv’s.
    • lf_corner_lips_clstr
    • rt_corner_lips_clstr
    • lower_lips_rt_clstr
    • lower_lips_mid_clstr
    • lower_lips_lf_clstr
    • upper_lips_lf_clstr
    • upper_lips_mid_clstr
    • upper_lips_rt_clstr
  3. Select all cv’s for lowerLips_crv and upperLips_crv……
    Go to the component Editor to edit the influence.RememberThose setting will be different for your own character, but here an examples.
  4. Place the pivot of each cluster to a more appropriate position. so the Rotation and Scaling of each cluster will be more meaningful.
  5. Group together all cluster
    • centerPivot this new group
    • rename this new group lips_clstr_grp..
  6. Group together lips_clstr_grp, upperLips_crv, lowerLips_crv, upperLips_crvBase, lowerLips_crvBase.
    1. rename this new group lips_setup_grp.
    2. parent lips_setup_grp to facialRig_grp node.

Step 06 cheek and nose setup

  1. Create one curve for the cheek muscle call lf_cheek_crvInclude the nose in the setup as it closely connected.
    • Select lf_cheek_crv and add influence to the head_geo_facialSetup_base. “Lock weight to 0 if you won’t affect previous paintWeight.”
    • Paintweight the new added _crv.
  2. Select lf_cheek_crv and create none-relative cluster call: Be sure all this cluster are also manipulating they’re neighboring cv’s.
    • lf_nostril_clstr
    • lf_upperCheek_clstr
    • lf_middleCheek_clstr
    • lf_lowerCheek_clstr
  3. Move Cluster pivot for a better interaction in TRS with the skin.
  4.  Select all cv’s for lf_cheek_crv……
    Go to the component Editor to edit the influence.RememberThose setting will be different for your own character, but here an examples.
  5. Group together all cluster
    • centerPivot this new group
    • rename this new group lf_cheek_clstr_grp..
  6. Group together lf_cheek_clstr_grp, lf_cheek_crv, lf_cheek_crvBase.
    • rename this new group lf_cheek_setup_grp.
    • parent lf_cheek_setup_grp to facialRig_grp node.
  7. Repeat STEP06 for the right side.

Step 07 Create a fake mouth to make the ctrl follow the jaw deformation.

As we have 8 cluster to control the upper and lower Lip. We will now create a in-between geometry to allow the ctrl to follow the jaw influence.

  1.  Create a polygone cylinder with 8 subdivisions axis.
    • Delete all the top and bottom poly.
    • Move to the mouth location and shape it to roughly to fit the mouth shape of the face_geo.
    • Freeze Transformation and delete history
    • rename this object fakeMouth_geo.
  2. smoothBind the fakeMouth_geo to be deform by bindJnt_head_jnt and bindJnt_jaw_jnt.
    • Do simple paint weight so the bottom and the top get 100% influenced by what they should be attract too. Then 50/50% for the corner.
  3. Using the rivet scripts, create all rivet as above. Using the command line, select 2 edges at the time and execute rivet.
    •  Rename as below:
      • lf_corner_lips_rivet
      • rt_corner_lips_rivet
      • upper_lips_lf_rivet
      • upper_lips_mid_rivet
      • upper_lips_rt_rivet
      • lower_lips_lf_rivet
      • lower_lips_mid_rivet
      • lower_lips_rt_rivet
  4. Using the jaw_ctrl rotate the jaw and observe the deformation for both object.”fakeMouth_geo, head_geo
    • Adjust the paintWeight if needed.
  5. Clean our setup
    • parent all rivet locator under a new group call lips_rivet_grp.
    • group together fakeMouth_geo and lips_rivet_grp
    • rename this new group fakeMouth_setup_grp.
    • parent fakeMouth_setup_grp to facialRig_grp.
    • Now in the Shape tab. For each rivet object. Un-check the visibility in the object display sub tab visibility.


Step 08 link all previous setup to controller

In order to control all the previous controller we would create a triple hierarchy to control all of this cluster and more. By the same time allowing us more level of control over the deformation.
WARNING: Step 08 to 09 should be execute in a single flow. Don’t close Maya. The scripts will not work with your actual setup when you reopen you Maya scene…. I fix the scripts soon to avoid such inconvenient.

  1.  Create the icon and parent them as shown below
    1. a line icon call _drv
    2. a plus icon call _ctrl
    3. Parent them as below under a new group call ctrl_zeroGrp.
    4. Each object and group should have a centerPivot
  2. Select all previous created cluster. “Pay attention to the order that you select them… Select them by Facial part“.
    In a PYTHON command line, execute jd_snapper(). This will duplicate the previous hierarchy of controller and position them to the cluster position.
    Be sure you naming convention fit the one above.
  3. Now simply select all new created controller ctrl_zeroGrp. Scale, move and rotate them to be in a accurate position in front of the main rig, head_geo.  The newly created controller must be in front of the face_geo include proper center pivot.
  4. Freeze transformation and delete history for all selected *ctrl_zeroGrp.
  5. Group them all under a new group call facial_all_ctrl.
  6. Now in a PYTHON scripts editor, execute jd_facialExpressionGenerator(). This will generate a text printed in the user history section of the scripts editor. Copy and paste the text in a secure location. Or simply paste it in a new expression call facial_expr. “Expression Editors”.
  7. You may want to disabled the expression using the block comments: /* all inside expression */
  8. parentConstrain and scaleConstrain facial_all_ctrl to the head_ctrl.
  9. parentConstrain appropriate ctrl_grp to their rivet  driver object.
    • lf_corner_lips_ctrl_grp to lf_corner_lips_rivet
    • rt_corner_lips_ctrl_grp to rt_corner_lips_rivet
    • upper_lips_lf_ctrl_grp to upper_lips_lf_rivet
    • upper_lips_mid_ctrl_grp to upper_lips_mid_rivet
    • upper_lips_rt_ctrl_grp to upper_lips_rt_rivet
    • lower_lips_lf_ctrl_grp to lower_lips_lf_rivet
    • lower_lips_mid_ctrl_grp to lower_lips_mid_rivet
    • lower_lips_rt_ctrl_grp to lower_lips_rt_rivet
  10. Lock TRS value for all previous *_ctrl_grp.


Step 09 Adding attribute on custom controller

  1. Create facial geometry to overlay the original face and represent some of the main facial muscle.
    • Create 7 icon “geometry” as below.
    • Group them under a new group call facial_muscle_ctrl_grp.
    • Name and center pivot all of them
      • lf_eyeBrow_ctrl_facial
      • lf_eye_ctrl_facial
      • lf_cheek_ctrl_facial
      • rt_eyeBrow_ctrl_facial
      • rt_eye_ctrl_facial
      • rt_cheek_ctrl_facial
      • upperLips_ctrl_facial
      • lowerLips_ctrl_facial
    • For each and every piece. Set the RenderStats all off.
    • Create a new shader call facial_muscle_shrd. Set the shader to a red and transparent color.
    • parent facial_muscle_ctrl_grp to ctrl_grp
    • Be sure you TURN OFF Inherits Transform for facial_muscle_ctrl_grp.
  2. Create a wrap deformer between the muscle and the face_geo.
    • Select facial_muscle_ctrl_grp, then select face_geo
    • Create the wrap as Exclusive Bind
  3. In a PYTHON command Line execute. jd_facial_102_addAttr()
    • This scripts will add a set of predefined attributes.
    • Feel Fee to add your own if needed.

Step 10 Add new blendShape for the lips

In order to get others behaviour for our lips mouvement we will duplicate head_geo_facialSetup_base and create a blend shape inbetween head_geo_facialSetup_basean the new facial shape.

  1. Select head_geo_facialSetup_base and duplicate it twice.
    • Move and rename both geometry
      • head_geo_facialSetup_lipsScale
      • head_geo_facialSetup_lipsRoll
      • parent both geometry to facialRig_grp.
  2. On head_geo_facialSetup_lipsScale, create a new cluster call lips_scale_clstr
    • Paint the weight as picture below
    • If not place correctly move the center pivot of lips_scale_clstr in the middle of the mouth
    • Group on himself lips_scale_clstr to become lips_scale_clstr_grp.
    • Parent lips_scale_clstr_grp to facialRig_grp.
  3. On head_geo_facialSetup_lipsRoll, create two new cluster call upperLips_roll_clstr and lowerLips_roll_clstr
    1. Paint the weight as picture below
    2. Place correctly the center pivot of upperLips_roll_clstr and lowerLips_roll_clstr both pivot should be place inside the lips “Lips skin and Gum JUNCTION”.
    3. Group on together upperLips_roll_clstr and lowerLips_roll_clstr to become lips_roll_clstr_grp.
    4. Parent lips_roll_clstr_grp to facialRig_grp.
  4. Create a blendShape to head_geo_facialSetup_base.
    • Select head_geo_facialSetup_lipsScalehead_geo_facialSetup_lipsRoll and head_geo_facialSetup_base
    • Create a blendShape without inbetween “default setup”. Call this new blendShape lips_blshp.
    • Now Activate the new created blendShape lips_blshp.

Step 11 SDK your ways to create the user preset shapes.

  1. Now simply SDK around and create preset expression for your animator to easily animated the face.
    • Simply remember to set driven key on _drv object and let the _ctrl for the animator to custom the facial as what he wish.
    • At that moment you will also want to fine tune and finish your paintWeight on head_geo_facialSetup_base and others clustered head_geo.
    • Always keep your SDK curve in linear tangent. Is is because you will animated the ease in and out manually.
    • Examples: See the list of assosication for SDK

Step 12 wrap up

Simply Wrap up out facial setup

  1. Parent facialRig_grp to noDeformation.
  2. Color code your controller if needed.
    • Using jd_loopColorCode.mel change the color out your facial controller to match your body controller.
  3. Set all geometry to a layer and set this layer as reference so no one can select the renderable geometry easily.
    • You can also do the same but this time using each and every object drawingOveride and set to the reference mode.
  4. Be sure your rig have no double transformation.
  5. Convert all SDK graph editor curve to linear.
  6. Create anew display layer call facial_ctrl. Add all facial related control into it.
  7. Lock and hide jaw_ctrl.rotate
  8. See your rigging checklist to ensure consistency.

Leave a Reply

Your email address will not be published. Required fields are marked *