Camera Focal Length Deformer

Playing with an idea that could help when modelling heads/characters: deforming objects by the change in a cameras focal length.

When sculpting/modelling a character head, I often find that that the model “feels” better when viewed through a longer or shorter lens, so I wanted to attempt to turn that idea into a viable modelling workflow.
This is a custom C++ deformer that will deform input objects by the change in a camera’s focal length.

Each object’s points are scaled as they are deformed to ensure that the object stays the same size in frame, mimicking the “dolly zoom” effect.

It’s not quite as useful as I had hoped, since most of the deformation occurs along the camera’s Z axis due to focal length compression.
However, things get a bit more interesting when you adjust the point scaling in each axis separately.
This allows the user to distort the objects more in X and Y than Z, giving you that feeling of a wider head with a compressed face, or vice-versa.
 
Focus distance, which adjusts the pivot point for scaling, and a falloff control, which adjusts the deformation strength based on each point’s depth relative to the camera, have been implemented for additional control.
 
Another potential use for something like this is to improve the manual camera line up workflow, where you feel the model needs to be adjusted to fit a known image’s focal length.
The reference starting focal length is cached, with an option to re-cache, allowing the camera to be adjusted to apply distortion from any viewing angle.
 
Mostly, this is a tool made just for fun and the learning process, running on the GPU for real time feedback with high res meshes.

Lip Intersection + Lip Sticky Nodes

A problem I’ve wanted to tackle for a while, lip meet intersections. This is my first take on a possible solution.

A custom C++ deformer written to dynamically resolve intersections between the upper and lower lips by pushing and flattening the contact area.
This Lip Intersection deformer will first solve the intersection, and then do a post-push on the areas around the meet line for a softer roll into the meet line.
Width and strength of this post-pushing is all controllable independently from the intersection solve. (I’ve pumped it a bit for the demo)

In this demo I’ve also layered on a custom C++ Lip Sticky deformer. As lip sticky is another effect that benefits a lot visually from a clean lip meet line.

All deformers running the on GPU to make them somewhat puppet friendly.

Lip meet intersections can be a subtle problem, and an even more subtle result when fixed, but in my experience, I’ve found that the intersection between closed lips can contribute to unnatural looking lips at render time for close-up shots.
This is especially true when the lips transition from closed to parted and a clear intersection can be seen as the upper lip slides out of the lower.

Ideally, the compression between lips should not be baked into the neutral, as the full roundness of the lips need to be in place whenever the lips are parted.
This means that the only solution is to solve the intersections dynamically, either in CFX, or in this case, the rig.

This setup has its limits, and works when the lips are not overly intersected. Going far beyond the neutral intersection can cause things to look odd. But things are generally stable with 50/60% of the lips intersected.

Cornea Push Node

A custom C++ Maya deformer to handle cornea displacement along the lid line and surrounding mesh.
Running on the GPU to make it puppet friendly.

The deformer does both cornea displacement and automatic snapping of the eyelid to the input eyeball geometry.
The radius, strength and shape of the displacement can be adjusted via attributes and a shape ramp for a decent amount of control over the final look.
The eyelid snapping influence can be adjusted by weights.

I my experience, I’ve found that a setup like this allows artists to simplify their eye look shape workflow by allowing them to focus solely on the eye opening shape in general and the flesh movement around it. 
I find this helps a lot with iteration speed and eye shape network management.

For best results, the eyelids would be modelled without any cornea displacement baked in, allowing for it all to be done 100% dynamically by the deformer.
However, as that is often not possible in production (due to renders and presentations being done before any rig is in place), the deformer will store offsets against the current shape, allowing for that baked displacement to be removed during deformation.

Workflow Tools

A long running set of tools I’ve been building up over the years to aid my personal workflow in Facial Modelling and Modelling in general. Constantly evolving as I add and adjust tools.

The core of the this specific UI and tool set is to be a crude plugin system that allows me to quickly implement new tools, with built-in automatic UI (for when custom UIs are not required).

Recently rewritten to be cleaner, faster and ready for PySide 6/Python 3 etc.

The toolset also comes with a set of custom C++ nodes and deformers.

Weight Builder Node

A custom C++ node to build and populate a weights array based on the input mesh’s shape.
I found the need for something like this for a while, useful when plugged directly into deformer weights attributes.

Current modes:

  • Mesh Convexity
  • Mesh Concavity
  • Mesh Smoothness
  • Mesh Roughness
  • Mesh Tension
  • Mesh Compression
  • Axis X
  • Axis Y
  • Axis Z
  • Noise
    • More noise modes/features to be implemented
    • FastNoiseLite.h used for noise algorithms

Weight range clamping, multiplying and blurring built in.

Shape Splitter

I’ve been working on a Shape Splitting tool on/off over the years.
With a major re-write for a recent project.

That latest iteration has been re-worked to have the following core features:

  • Unlimited Split Directions
    • Allowing users to add as many custom splits as required for the character
    • A Split Direction defines how a shape is divided into two resulting shapes
    • Example:
      • Split Lips Upper and Lower Splits a shape into an Upper Lip and Lower Lip version
      • Split Left/Right Splits a shape down the middle of the face into Left and Right versions
    • Split Directions are controlled through JSON configuration files and per-vertex painted weight data
  • Unlimited Splits Per Shape
    • While most shapes typically require basic Left/Right or Lip Upper/Lower splits, or both, the tool supports any number of additional splits as required
    • Example, taking a full brow shape and producing not only a L/R brow raiser, but also an Inner and Outer browRaisesr that are in-turn split L/R
  • Middle line pulling
    • Automatically pulls shapes across the midline after splitting to reduce the “dead zone” often felt along the centre line.
  • Realtime Split Preview
    • Ability to preview the resulting split names before committing to the split process
  • Config Driven
    • Shapes List, Split Directions, Pull Directions all driven via JSON config files allowing for different configs per show
  • Shape Group
    • Basic group of the input shapes list with import/export
  • Split States
    • Ability to disable/enable shapes for splitting after selection for faster iterations

The core splitting logic is independent of the UI and can be easily implemented as a post-process for use on a farm or at rig build time.

Split times depend on mesh resolution, but the tool has been written to only work on the smallest amount of data required to reduce memory and speed up split times.