95 lines
4.9 KiB
Markdown
95 lines
4.9 KiB
Markdown
# Documentation
|
|
- Class name: LatentKeyframeInterpolationNode
|
|
- Category: Adv-ControlNet 🛂🅐🅒🅝/keyframes
|
|
- Output node: False
|
|
- Repo Ref: https://github.com/Kosinkadink/ComfyUI-Advanced-ControlNet.git
|
|
|
|
LatentKeyframeInterpolationNode 旨在在潜在空间中对关键帧进行插值,允许在生成过程中进行平滑过渡。它通过根据指定的强度和插值方法(可以是线性或各种缓动函数)计算中间关键帧来实现这一点。该节点在增强潜在表示生成的流畅性和控制方面发挥着关键作用。
|
|
|
|
# Input types
|
|
## Required
|
|
- batch_index_from
|
|
- 插值开始的批次索引,定义了关键帧序列中的初始位置。这对于确定过渡的起始点至关重要。
|
|
- Comfy dtype: INT
|
|
- Python dtype: int
|
|
- strength_from
|
|
- 起始关键帧处的强度值,它影响插值过程中初始状态的强度。
|
|
- Comfy dtype: FLOAT
|
|
- Python dtype: float
|
|
- batch_index_to_excl
|
|
- 计算插值的批次索引,不包括索引本身,定义序列的结束位置。
|
|
- Comfy dtype: INT
|
|
- Python dtype: int
|
|
- strength_to
|
|
- 结束关键帧处的强度值,确定插值后最终状态的强度。
|
|
- Comfy dtype: FLOAT
|
|
- Python dtype: float
|
|
- interpolation
|
|
- 在关键帧之间使用的插值类型,可以是线性的或者是一个缓动函数,以实现更自然的过渡。
|
|
- Comfy dtype: COMBO[LINEAR, EASE_IN, EASE_OUT, EASE_IN_OUT]
|
|
- Python dtype: str
|
|
## Optional
|
|
- prev_latent_kf
|
|
- 一个可选的先前的潜在关键帧组,它为插值提供上下文,允许更有信息量的生成过程。
|
|
- Comfy dtype: LATENT_KEYFRAME
|
|
- Python dtype: LatentKeyframeGroup
|
|
- print_keyframes
|
|
- 一个布尔标志,当设置为 true 时,将打印生成的关键帧的详细信息,用于调试目的。
|
|
- Comfy dtype: BOOLEAN
|
|
- Python dtype: bool
|
|
|
|
# Output types
|
|
- LATENT_KF
|
|
- 生成的插值潜在关键帧组,代表初始和最终状态之间的过渡。
|
|
- Comfy dtype: LATENT_KEYFRAME
|
|
- Python dtype: LatentKeyframeGroup
|
|
|
|
# Usage tips
|
|
- Infra type: CPU
|
|
|
|
# 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, 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}')
|
|
for latent_keyframe in prev_latent_keyframe.keyframes:
|
|
curr_latent_keyframe.add(latent_keyframe)
|
|
return (curr_latent_keyframe,)
|
|
``` |