Latent Keyframe Interpolation 🛂🅐🅒🅝¶
Documentation¶
- Class name:
LatentKeyframeTiming
- Category:
Adv-ControlNet 🛂🅐🅒🅝/keyframes
- Output node:
False
This node is designed to manage the timing and sequencing of latent keyframes within a generative model's control network. It focuses on interpolating and scheduling keyframes based on specified timing parameters, ensuring smooth transitions and accurate timing for the generation process.
Input types¶
Required¶
batch_index_from
- Specifies the starting index for the batch of keyframes to be processed, serving as the initial point for timing and sequencing operations.
- Comfy dtype:
INT
- Python dtype:
int
batch_index_to_excl
- Defines the exclusive end index for the batch of keyframes, marking the boundary for the sequence of keyframes to be interpolated or scheduled.
- Comfy dtype:
INT
- Python dtype:
int
strength_from
- Indicates the starting strength value for the interpolation of keyframes, setting the initial intensity or effect level.
- Comfy dtype:
FLOAT
- Python dtype:
float
strength_to
- Specifies the ending strength value for the interpolation, determining the final intensity or effect level for the sequence of keyframes.
- Comfy dtype:
FLOAT
- Python dtype:
float
interpolation
- Defines the method of interpolation to be used for transitioning between keyframes, such as linear or ease-in/out, to ensure smooth changes in strength or effects.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
str
Optional¶
prev_latent_kf
- Optional parameter for providing a previous set of latent keyframes to be considered or integrated into the current timing and sequencing operation.
- Comfy dtype:
LATENT_KEYFRAME
- Python dtype:
LatentKeyframeGroup
print_keyframes
- A flag to enable logging of keyframe details for debugging or informational purposes.
- Comfy dtype:
BOOLEAN
- Python dtype:
bool
autosize
- unknown
- Comfy dtype:
ACNAUTOSIZE
- Python dtype:
unknown
Output types¶
LATENT_KF
- Comfy dtype:
LATENT_KEYFRAME
- The output is a modified or newly created set of latent keyframes, reflecting the applied timing and sequencing operations.
- 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._LIST, ),
},
"optional": {
"prev_latent_kf": ("LATENT_KEYFRAME", ),
"print_keyframes": ("BOOLEAN", {"default": False}),
"autosize": ("ACNAUTOSIZE", {"padding": 90}),
}
}
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"LatentKeyframe {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,)