Latent Keyframe Interpolation 🛂🅐🅒🅝¶
Documentation¶
- Class name:
LatentKeyframeTiming
- Category:
Adv-ControlNet 🛂🅐🅒🅝/keyframes
- Output node:
False
This node is responsible for creating and managing latent keyframes within a generative model's control network. It allows for the dynamic adjustment and sequencing of keyframes based on specified timing and strength parameters, facilitating the controlled transformation or animation of generated content.
Input types¶
Required¶
batch_index_from
- Specifies the starting index of the batch for keyframe creation, marking the beginning of the sequence where adjustments are applied.
- Comfy dtype:
INT
- Python dtype:
int
batch_index_to_excl
- Defines the exclusive end index of the batch for keyframe creation, indicating the point just beyond the last batch index where adjustments cease.
- Comfy dtype:
INT
- Python dtype:
int
strength_from
- Sets the initial strength or intensity level for the starting keyframe, influencing the beginning of the transformation or animation effect.
- Comfy dtype:
FLOAT
- Python dtype:
float
strength_to
- Determines the final strength or intensity level for the ending keyframe, shaping the culmination of the transformation or animation effect.
- Comfy dtype:
FLOAT
- Python dtype:
float
interpolation
- Chooses the method of interpolation between keyframe strengths, affecting the transition smoothness and dynamics between the start and end points.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
str
Optional¶
prev_latent_kf
- An optional parameter for including a previously defined latent keyframe or keyframe group, enabling the extension or modification of existing sequences.
- Comfy dtype:
LATENT_KEYFRAME
- Python dtype:
LatentKeyframeGroup
print_keyframes
- A flag to enable or disable the printing of keyframe details, aiding in debugging or visualization of the keyframe sequence.
- Comfy dtype:
BOOLEAN
- Python dtype:
bool
Output types¶
LATENT_KF
- Comfy dtype:
LATENT_KEYFRAME
- Outputs a modified or newly created latent keyframe group, incorporating the specified adjustments and interpolations to the keyframes.
- Python dtype:
LatentKeyframeGroup
- Comfy dtype:
Usage tips¶
- Infra type:
CPU
- Common nodes: unknown
Source code¶
class LatentKeyframeInterpolationNode:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"batch_index_from": ("INT", {"default": 0, "min": BIGMIN, "max": BIGMAX, "step": 1}),
"batch_index_to_excl": ("INT", {"default": 0, "min": BIGMIN, "max": BIGMAX, "step": 1}),
"strength_from": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
"strength_to": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.001}, ),
"interpolation": ([SI.LINEAR, SI.EASE_IN, SI.EASE_OUT, SI.EASE_IN_OUT], ),
},
"optional": {
"prev_latent_kf": ("LATENT_KEYFRAME", ),
"print_keyframes": ("BOOLEAN", {"default": False})
}
}
RETURN_NAMES = ("LATENT_KF", )
RETURN_TYPES = ("LATENT_KEYFRAME", )
FUNCTION = "load_keyframe"
CATEGORY = "Adv-ControlNet 🛂🅐🅒🅝/keyframes"
def load_keyframe(self,
batch_index_from: int,
strength_from: float,
batch_index_to_excl: int,
strength_to: float,
interpolation: str,
prev_latent_kf: LatentKeyframeGroup=None,
prev_latent_keyframe: LatentKeyframeGroup=None, # old name
print_keyframes=False):
if (batch_index_from > batch_index_to_excl):
raise ValueError("batch_index_from must be less than or equal to batch_index_to.")
if (batch_index_from < 0 and batch_index_to_excl >= 0):
raise ValueError("batch_index_from and batch_index_to must be either both positive or both negative.")
prev_latent_keyframe = prev_latent_keyframe if prev_latent_keyframe else prev_latent_kf
if not prev_latent_keyframe:
prev_latent_keyframe = LatentKeyframeGroup()
else:
prev_latent_keyframe = prev_latent_keyframe.clone()
curr_latent_keyframe = LatentKeyframeGroup()
steps = batch_index_to_excl - batch_index_from
diff = strength_to - strength_from
if interpolation == SI.LINEAR:
weights = np.linspace(strength_from, strength_to, steps)
elif interpolation == SI.EASE_IN:
index = np.linspace(0, 1, steps)
weights = diff * np.power(index, 2) + strength_from
elif interpolation == SI.EASE_OUT:
index = np.linspace(0, 1, steps)
weights = diff * (1 - np.power(1 - index, 2)) + strength_from
elif interpolation == SI.EASE_IN_OUT:
index = np.linspace(0, 1, steps)
weights = diff * ((1 - np.cos(index * np.pi)) / 2) + strength_from
for i in range(steps):
keyframe = LatentKeyframe(batch_index_from + i, float(weights[i]))
curr_latent_keyframe.add(keyframe)
if print_keyframes:
for keyframe in curr_latent_keyframe.keyframes:
logger.info(f"keyframe {keyframe.batch_index}:{keyframe.strength}")
# replace values with prev_latent_keyframes
for latent_keyframe in prev_latent_keyframe.keyframes:
curr_latent_keyframe.add(latent_keyframe)
return (curr_latent_keyframe,)