Changing AnimationAction's blendmode to 'AdditiveAnimationBlendMode' leads to incorrect results

Change AnimationAction’s blendmode to ‘AdditiveAnimationBlendMode’ leads to incorrect results.

Main Code:

if (blendMode !== clip.blendMode) {
    clip.blendMode = blendMode;
 }

const additiveAction = this.mixer.clipAction(clip, this.animRoot);
additiveAction.setEffectiveWeight(1.0)

idleAction.play();
additiveAction.play();

Incorrect Result:skeleton nodes are overscaled

Conversely, use AnimationUtils.makeClipAdditive will get the correct result.
Main Code:

if (blendMode !== clip.blendMode) {
    if (blendMode === AdditiveAnimationBlendMode) {
        AnimationUtils.makeClipAdditive(clip);
    } else {
        clip.blendMode = blendMode;
    }
}
const additiveAction = this.mixer.clipAction(clip, this.animRoot);
additiveAction.setEffectiveWeight(1.0)

idleAction.play();
additiveAction.play();

Correct Result:

Does anyone have an idea?

Using AnimationUtils.makeClipAdditive() is mandatory if you define AdditiveAnimationBlendMode. As mentioned in the inline docs, the method makes each track’s values relative to the values at the reference frame which is a prerequisite for additive blending.

2 Likes

/cc

Got it, thank you very much.

what’s the purpose of calling makeClipAdditive() without reference clip? What to make the clip additive to?

It’s about processing the keyframe tracks of the clip. Like mentioned above, the call makes each keyframe track’s values relative to the values at the reference frame. It’s best if you study to source code of the method to see what’s going on.

“the call makes each keyframe track’s values relative to the values at the reference frame.” – since the reference frame is itself, how does that work? Sorry I’m still in confusion after a quick scan of the method code. Thanks for your patience.

The reference frame is 0 by default but you can pass a different value as the second parameter of makeClipAdditive(). Based on this frame the function determines a keyframe and its values that represents the reference. This reference is subtracted from all other values in the keyframe track.

Sorry I have been slow here. There was only one argument passed to makeAdditive in the above code. Where did the reference come from?

Ha, were you saying that it used the first frame as the reference and made the following frames relative to it?

It is not always the first keyframe. The function determines this based on the passed in reference frame and the keyframe tracks’s time values.