Contributors: Jellejurre, JustSleightly

# Advanced Blend Tree Techniques

## Introduction

Blend Trees are powerful tools that cover a variety of use cases, from optimizing simple animator layers, to simulating complex logic equations.

For an introduction to Blend Trees, check out Combining Layers Using Direct Blend Trees to optimize simple animator layers and save animator performance.

This article covers more advanced applications of Blend Trees, including:

- Logic Gates
- Float Remapping*
- Math Operators*
- Framerate Detection*
- Float Smoothing*

*Many applications are an extension of the Animated Animator Parameters (AAP) article, so it’s recommended to have read its contents.

When using Direct Blend Trees, don’t forget to make their states Write Defaults enabled, and mark their states with (WD ON) in the name.

Example images in this article use MACS for visualization.

- Numbers on the left of animations/Blend Trees show their Threshold in a 1D/2D Blend Tree
- Names on the left of animations/Blend Trees show their Direct Blend Parameter
- If an animation is named [Parameter][Number] it animates that AAP to that number. Output1 for example animated the Output AAP to 1

For example, on the right you will see a Direct (`[DIR]`

) Blend Tree that animates a Standard 1D (`[S1D]`

) Blend Tree with a weight parameter of `One`

. That Blend Tree has two children, one animation clip `Output-100`

at threshold `-100`

, and another animation clip `Output100`

at threshold `100`

.

Direct and 1D Blend Trees are the only types that follow simple mathematical rules, while the other types have advanced algorithms not meant for logic but for animation, and are at best an approximation.

An example of the visualizations used in this article. This layer would save the Output AAP according to the 1D Blend Tree technique.

## Logic Gates

You can use Blend Trees to simulate the logic of logic gates (like AND, OR, NOT, XOR, etc.).

These can be used to animate properties based on multiple input parameters, such as toggling a GameObject off when toggling another GameObject on, or animating a blendshape only when two other toggles are enabled.

The following examples assume 1 = True and 0 = False.

### AND Gate

*Output true, only if A* **and***B are both true*

This example demonstrates an AND Gate using parameters `InputA`

and `InputB`

.

Here, the only way the `Output`

animation plays is if both inputs are 1 (true).

Example template can be downloaded from Logic: AND Gate.

An example of an AND gate.

This table represents all of the possible outcomes:

❌ = False

✅ = True

Input 1 | Input 2 | Output |
---|---|---|

❌ | ❌ | ❌ (`Output 0` ) |

✅ | ❌ | ❌ (`Output 0` ) |

❌ | ✅ | ❌ (`Output 0` ) |

✅ | ✅ | ✅ (`Output 1` ) |

### OR Gate

*Output true, if either A* **or***B are true*

This example demonstrates an OR Gate using parameters `InputA`

and `InputB`

.

Here, the `Output`

animation can play if either input is 1 (true).

Example template can be downloaded from Logic: OR Gate.

An example of an OR gate.

This table represents all of the possible outcomes:

❌ = False

✅ = True

Input 1 | Input 2 | Output |
---|---|---|

❌ | ❌ | ❌ (`Output 0` ) |

✅ | ❌ | ✅ (`Output 1` ) |

❌ | ✅ | ✅ (`Output 1` ) |

✅ | ✅ | ✅ (`Output 1` ) |

### NOT Gate

*Output the opposite of the input*

This example demonstrates a NOT Gate using parameter `Input`

.

Here, the `Output 1`

animation plays if `Input`

is 0 (false).

Example template can be downloaded from Logic: NOT Gate.

An example of a NOT gate.

This table represents all of the possible outcomes:

❌ = False

✅ = True

Input | Output |
---|---|

❌ | ✅ (`Output 1` ) |

✅ | ❌ (`Output 0` ) |

### Arbitrary 2-Bit Gates

In reality, you can make any 2-bit (or even n-bit) gate by animating every possibility.

This example demonstrates animating every output possibility, where you can replace each output clip with anything you want.

For example, an XOR gate would replace the:

`Replace with 0,0 value`

node for an`Output 0`

animation`Replace with 0,1 value`

node for an`Output 1`

animation`Replace with 1,0 value`

node for an`Output 1`

animation`Replace with 1,1 value`

node for an`Output 0`

animation

Example template can be downloaded from Logic: Arbitrary Gate.

An example of a 2-bit gate.

## Remapping A Value

You can use the “1D Blend Tree” method explained in the Animated Animator Parameters (AAP) article to remap a value.

This is done by changing what gets animated at what time. If you want to remap the range `0`

- `1`

to the range `10`

- `100`

, you would make the Thresholds `0`

and `1`

, and the animations `Output 10`

and `Output 100`

.

An example where the range `-100`

to `100`

is remapped to `100`

to `-100`

is shown to the right. This is similar to a NOT Logic Gate that inverts/negates the output.

Example template can be downloaded from Remap Float.

An example of negating a float with an AAP. If the Source value is 100, the Target-100 animation will play with full weight, setting the Target AAP to -100.

## Math Operators

Using Animated Animator Parameters (AAP), you can do the four basic mathematical operations (though with some caveats); Addition (`+`

) , Subtraction (`-`

), Multiplication (`*`

), and Division (`/`

).

### Addition

Addition can be accomplished by animating an AAP twice in the same Direct Blend Tree, causing the effects to stack.

In the first example, we will use the 1D Blend Tree method to animate the output value.

This can include negative values as inputs too, but is lower on precision and only works within a set range.

An example of adding two values by animating the Output AAP in two 1D Blend Trees in a Direct Blend Tree.

In the second example, we will use the Direct Blend Child animation method to animate the output value.

This can only take positive values as inputs and relies on the Output being weighted to 0 by default, but has higher precision and works for any positive number.

Example templates can be downloaded from Math: Addition.

An example of adding two values by animating the Output AAP in two animation children in a Direct Blend Tree.

### Subtraction

Subtraction is similar to Addition but while negating the second parameter.

The first example uses the 1D Blend Tree method.

An example of subtracting two values by animating the Output AAP in two 1D Blend Trees in a Direct Blend Tree. Note how the bottom blend tree animated -100 at 100 and vice versa.

The second example uses the Direct Blend Tree Child method.

Example templates can be downloaded from Math: Subtraction.

An example of subtracting two values by animating the Output AAP in two animation children in a Direct Blend Tree.

### Multiplication

Multiplication is done by nesting Blend Trees as children of the DBT, as the child of a child Blend Tree gets played by the weight of both Blend Trees multiplied.

Both methods can only take in positive values due to the math only working when the lower value is 0, and the Direct child only works when the default value is 0.

The first example uses the 1D Blend Tree method.

An example of multiplying two values by animating the value through two 1D Blend Trees. Note that both inputs here go up to 10, and the last animation, Output 100, animates those two values multiplied together.

The second example uses the Direct Blend Tree Child method.

Example templates can be downloaded from Math: Multiplication.

An example of multiplying two values by animating the value through two Direct Blend Trees.

### Division

Division is done by using the Normalize Blend Values option, which takes the Blend Parameters of a Direct Blend Tree, and divides them (and therefore the outputs) by the sum of all Blend Parameters, meaning the final used Blend Parameters are normalized (add up to 1).

Note that this only happens if the total sum of Blend Parameters is greater than 1. We can abuse this by animating a dummy animation (that animates nothing) with our input parameter, while animating the Output with a weight of 1.

For example, if the value of `Input`

is `2`

, then:

`Dummy`

gets animated with weight`2`

and`Output1`

- This means the total weight is
`1`

+`2`

=`3`

- So then because this is greater than 1, all weights get divided by
`3`

- So
`Dummy`

gets animated with weight`2/3`

and`Output`

gets animated with weight`1/3`

, giving us our output value of`1/3`

Example template can be downloaded from Math: Division.

An example of division. Note that this doesn’t divide by Input, but by (1 + Input).

## Frame Time Detection

Blend Trees get run once every frame. So at different framerates, the effects that happen over time (like float smoothing) will happen at different rates. To counteract this, you can read out the frame time (time that has passed since last frame), and multiply your effects by this number, so that over the course of a second, the full effect happens once.

To do this, we keep track of an ever increasing Time parameter, and the value it had last frame, and subtract these to get the frame time.

This setup requires two layers. One layer playing a time animation, and one layer processing that into the frame time.

Example template can be downloaded from Frame Time Measurement.

The layout of Frame Time detection layers.

The Time Animation would be set up with two key frames, one at 0 and one at a frame far away, This example uses 20000 seconds (120000 frames). In this animation, the Time AAP would be animated between 0 and 20000, with Both Tangents set to Linear. This animation would have Loop Time on and be playing on the top layer.

An example Time animation.

Then, the next layer is a Direct Blend Tree which performs two operations.

First it sets `FrameTime`

= `Time`

- `LastTime`

(see ). Lastly, it sets `LastTime`

to `Time`

so it can be used next frame.

Now the `FrameTime`

is set to the difference between the time at the current and previous frame, a.k.a. the frame time. This can be used in your other Blend Trees.

An example Frame Time measurement layer.

## Smoothing

Blend Trees can also be used to let a float smoothly change from one value to another. There are currently two ways to do this: Exponentially and Linearly.

### Exponential Smoothing

In Exponential Smoothing, the difference between the current value and the target gets exponentially smaller every frame. It uses three 1D Blend Trees.

We use an 1D Blend Tree to blend between setting `Smoothed Value`

to itself and setting it to the actual `Value`

.

If you have a Blend Tree where you set a value A at threshold 0 and value B at threshold 1, the math is as follows for a 1d Blend Tree with parameter f:

$Blend(f) = \begin{cases} A & \quad f \leq 0 \\ A * (1 - f) + B * f & \quad 0 \leq f \leq 1 \\ B & \quad f \geq 1 \end{cases}$So this means that since our `S``moothAmount`

is always between 0 and 1, our value would be:

$SmoothedValue = Value * (1-SmoothAmount) + SmoothedValue * SmoothAmount$

So the higher `SmoothAmount`

is, the more it will use the old value instead of the new one, so it’s gonna “lag behind” more. Feel free to try this yourself to get a feel for what this value does.

Example templates can be downloaded from Smoothing (Exponential), Smoothed Float (Full) and Smoothed Float (Half).

### Linear Smoothing

In Linear Smoothing, the amount that gets added or subtracted is the same every frame, so over the frames it’s linear.

The top two 1D Blend Trees set Delta (Difference) = Value - Smoothed Value

The bottom two 1D Blend Trees set

$SmoothedValue = SmoothedValue + Clamp(-StepSize, StepSize, Delta)$

To clarify, the Linear Blend Blend Tree does the following:

- If Delta < -0.1, we subtract Step Size from the Smoothed Value.
- If -0.1 < Delta < 0.1, we blend Delta between itself and the Step Size
- If Delta > 0.1, we add Step Size too the Smoothed value.

Therefore we always take a step of `StepSize`

in the direction of the Value, and thus get Linear Smoothing.

Example template can be downloaded from Smoothing (Linear).

An example of an Linear Smoothing Blend Tree.

By adding a Frame Time Detection layer and multiplying `StepSize`

by the frame time before using it, this can be frame time independent.