diff --git a/SteerableMotion.py b/SteerableMotion.py
index 2fd3e03..c697d36 100644
--- a/SteerableMotion.py
+++ b/SteerableMotion.py
@@ -17,7 +17,9 @@ from .imports.AdvancedControlNet.weight_nodes import ScaledSoftUniversalWeightsI
from .imports.AdvancedControlNet.nodes_sparsectrl import SparseIndexMethodNodeImport
from .imports.AdvancedControlNet.nodes import ControlNetLoaderAdvancedImport, AdvancedControlNetApplyImport,TimestepKeyframeNodeImport
-
+from color_matcher import ColorMatcher
+
+
class BatchCreativeInterpolationNode:
@classmethod
@@ -39,8 +41,8 @@ class BatchCreativeInterpolationNode:
"linear_frame_distribution_value": ("INT", {"default": 16, "min": 4, "max": 64, "step": 1}),
"dynamic_frame_distribution_values": ("STRING", {"multiline": True, "default": "0,10,26,40"}),
"type_of_key_frame_influence": (["linear", "dynamic"],),
- "linear_key_frame_influence_value": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.1}),
- "dynamic_key_frame_influence_values": ("STRING", {"multiline": True, "default": "1.0,1.0,1.0,0.5"}),
+ "linear_key_frame_influence_value": ("STRING", {"multiline": False, "default": "(1.0,1.0)"}),
+ "dynamic_key_frame_influence_values": ("STRING", {"multiline": True, "default": "(1.0,1.0),(1.0,1.5)(1.0,0.5)"}),
"type_of_strength_distribution": (["linear", "dynamic"],),
"linear_strength_value": ("STRING", {"multiline": False, "default": "(0.3,0.4)"}),
"dynamic_strength_values": ("STRING", {"multiline": True, "default": "(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0)"}),
@@ -49,62 +51,28 @@ class BatchCreativeInterpolationNode:
"relative_cn_strength": ("FLOAT", {"default": 0.1, "min": 0.0, "max": 10.0, "step": 0.01}),
"relative_ipadapter_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"ipadapter_noise": ("FLOAT", {"default": 0.3, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "ipadapter_start_at": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "ipadapter_end_at": ("FLOAT", {"default": 0.75, "min": 0.0, "max": 1.0, "step": 0.01}),
},
"optional": {
}
}
- RETURN_TYPES = ("IMAGE","CONDITIONING","CONDITIONING","MODEL","SPARSE_METHOD","INT")
+ RETURN_TYPES = ("IMAGE","CONDITIONING","CONDITIONING","MODEL","SPARSE_METHOD","INT", "COLOR_MATCH_FRAMES")
# "comparison_diagram, positive, negative, model, sparse_indexes, last_key_frame_position"
- RETURN_NAMES = ("GRAPH","POSITIVE","NEGATIVE","MODEL","KEYFRAME_POSITIONS","BATCH_SIZE")
+ RETURN_NAMES = ("GRAPH","POSITIVE","NEGATIVE","MODEL","KEYFRAME_POSITIONS","BATCH_SIZE", "COLOR_MATCH_FRAMES")
FUNCTION = "combined_function"
- CATEGORY = "Steerable-Motion/Interpolation"
+ CATEGORY = "Steerable-Motion"
def combined_function(self,positive,negative,images,model,ipadapter,clip_vision,control_net_name,
type_of_frame_distribution,linear_frame_distribution_value, dynamic_frame_distribution_values,
type_of_key_frame_influence,linear_key_frame_influence_value,
dynamic_key_frame_influence_values,type_of_strength_distribution,
linear_strength_value,dynamic_strength_values, soft_scaled_cn_weights_multiplier,
- buffer, relative_cn_strength,relative_ipadapter_strength,ipadapter_noise):
+ buffer, relative_cn_strength,relative_ipadapter_strength,ipadapter_noise,
+ ipadapter_start_at,ipadapter_end_at):
- def calculate_dynamic_influence_ranges(keyframe_positions, key_frame_influence_values, allow_extension=True):
- if len(keyframe_positions) < 2 or len(keyframe_positions) != len(key_frame_influence_values):
- return []
-
- influence_ranges = []
- for i, position in enumerate(keyframe_positions):
- influence_factor = key_frame_influence_values[i]
-
- if i == 0:
- # Special handling for the first keyframe (half the distance to the second keyframe)
- range_size = influence_factor * (keyframe_positions[1] - keyframe_positions[0]) / 2
- start_influence = position # Start from the first keyframe position
- end_influence = position + range_size
- elif i == len(keyframe_positions) - 1:
- # Special handling for the last keyframe (half the distance from the penultimate keyframe)
- range_size = influence_factor * (keyframe_positions[-1] - keyframe_positions[-2]) / 2
- start_influence = position - range_size
- end_influence = position # End at the last keyframe position
- else:
- # Regular calculation for other keyframes
- range_size = influence_factor * (keyframe_positions[-1] - keyframe_positions[0]) / (len(keyframe_positions) - 1) / 2
- start_influence = position - range_size
- end_influence = position + range_size
-
- if not allow_extension:
- start_influence = max(start_influence, keyframe_positions[i - 1] if i > 0 else 0)
- end_influence = min(end_influence, keyframe_positions[i + 1] if i < len(keyframe_positions) - 1 else keyframe_positions[-1])
-
- influence_ranges.append((round(start_influence), round(end_influence)))
-
- return influence_ranges
-
- def add_starting_buffer(influence_ranges, buffer=4):
- shifted_ranges = [(0, buffer)]
- for start, end in influence_ranges:
- shifted_ranges.append((start + buffer, end + buffer))
- return shifted_ranges
def get_keyframe_positions(type_of_frame_distribution, dynamic_frame_distribution_values, images, linear_frame_distribution_value):
if type_of_frame_distribution == "dynamic":
@@ -117,24 +85,6 @@ class BatchCreativeInterpolationNode:
else:
# Calculate the number of keyframes based on the total duration and linear_frames_per_keyframe
return [i * linear_frame_distribution_value for i in range(len(images))]
-
- def extract_keyframe_values(type_of_key_frame_influence, dynamic_key_frame_influence_values, keyframe_positions, linear_key_frame_influence_value):
- if type_of_key_frame_influence == "dynamic":
- # Check if the input is a string or a list
- if isinstance(dynamic_key_frame_influence_values, str):
- # Parse the dynamic key frame influence values without sorting
- dynamic_values = [float(influence.strip()) for influence in dynamic_key_frame_influence_values.split(',')]
- elif isinstance(dynamic_key_frame_influence_values, list):
- dynamic_values = dynamic_key_frame_influence_values
- else:
- raise ValueError("Invalid type for dynamic_key_frame_influence_values. Must be string or list.")
-
- # Trim the dynamic_values to match the length of keyframe_positions
- return dynamic_values[:len(keyframe_positions)]
-
- else:
- # Create a list with the linear_key_frame_influence_value for each keyframe
- return [linear_key_frame_influence_value for _ in keyframe_positions]
def create_mask_batch(last_key_frame_position, weights, frames):
# Hardcoded dimensions
@@ -158,7 +108,6 @@ class BatchCreativeInterpolationNode:
return masks_tensor
-
def plot_weight_comparison(cn_frame_numbers, cn_weights, ipadapter_frame_numbers, ipadapter_weights, buffer):
plt.figure(figsize=(12, 8))
@@ -201,24 +150,66 @@ class BatchCreativeInterpolationNode:
img_tensor = img_tensor.unsqueeze(0)
img_tensor = img_tensor.permute([0, 2, 3, 1])
- return img_tensor,
-
+ return img_tensor,
- def extract_start_and_endpoint_values(type_of_key_frame_influence, dynamic_key_frame_influence_values, keyframe_positions, linear_key_frame_influence_value):
+ def extract_strength_values(type_of_key_frame_influence, dynamic_key_frame_influence_values, keyframe_positions, linear_key_frame_influence_value):
+ print("START AND ENDPOINT VALUES")
+ print(f"type_of_key_frame_influence {type_of_key_frame_influence}")
+ print(f"dynamic_key_frame_influence_values {dynamic_key_frame_influence_values}")
+ print(f"keyframe_positions {keyframe_positions}")
+ print(f"linear_key_frame_influence_value {linear_key_frame_influence_value}")
if type_of_key_frame_influence == "dynamic":
- # If dynamic_key_frame_influence_values is a list of characters representing tuples, process it
- if isinstance(dynamic_key_frame_influence_values[0], str) and dynamic_key_frame_influence_values[0] == "(":
- # Join the characters to form a single string and evaluate to convert into a list of tuples
+ # Process the dynamic_key_frame_influence_values depending on its format
+ if isinstance(dynamic_key_frame_influence_values, str):
+ dynamic_values = eval(dynamic_key_frame_influence_values)
+ else:
+ dynamic_values = dynamic_key_frame_influence_values
+
+ # Iterate through the dynamic values and convert tuples with two values to three values
+ dynamic_values_corrected = []
+ for value in dynamic_values:
+ if len(value) == 2:
+ value = (value[0], value[1], value[0])
+ dynamic_values_corrected.append(value)
+
+ return dynamic_values_corrected
+ else:
+ # Process for linear or other types
+ if len(linear_key_frame_influence_value) == 2:
+ linear_key_frame_influence_value = (linear_key_frame_influence_value[0], linear_key_frame_influence_value[1], linear_key_frame_influence_value[0])
+ return [linear_key_frame_influence_value for _ in range(len(keyframe_positions) - 1)]
+
+
+ def extract_influence_values(type_of_key_frame_influence, dynamic_key_frame_influence_values, keyframe_positions, linear_key_frame_influence_value):
+ # Check and convert linear_key_frame_influence_value if it's a float or string float
+ # if it's a string that starts with a parenthesis, convert it to a tuple
+ if isinstance(linear_key_frame_influence_value, str) and linear_key_frame_influence_value[0] == "(":
+ linear_key_frame_influence_value = eval(linear_key_frame_influence_value)
+
+
+ if not isinstance(linear_key_frame_influence_value, tuple):
+ if isinstance(linear_key_frame_influence_value, (float, str)):
+ try:
+ value = float(linear_key_frame_influence_value)
+ linear_key_frame_influence_value = (value, value)
+ except ValueError:
+ raise ValueError("linear_key_frame_influence_value must be a float or a string representing a float")
+
+ number_of_outputs = len(keyframe_positions) - 1
+
+ if type_of_key_frame_influence == "dynamic":
+ # Convert list of individual float values into tuples
+ if all(isinstance(x, float) for x in dynamic_key_frame_influence_values):
+ dynamic_values = [(value, value) for value in dynamic_key_frame_influence_values]
+ elif isinstance(dynamic_key_frame_influence_values[0], str) and dynamic_key_frame_influence_values[0] == "(":
string_representation = ''.join(dynamic_key_frame_influence_values)
dynamic_values = eval(f'[{string_representation}]')
else:
- # If it's already a list of tuples or a single tuple, use it directly
dynamic_values = dynamic_key_frame_influence_values if isinstance(dynamic_key_frame_influence_values, list) else [dynamic_key_frame_influence_values]
- return dynamic_values
+ return dynamic_values[:number_of_outputs]
else:
- # Return a list of tuples with the linear_key_frame_influence_value as a tuple repeated for each position
- return [linear_key_frame_influence_value for _ in keyframe_positions]
-
+ return [linear_key_frame_influence_value for _ in range(number_of_outputs)]
+
def calculate_weights(batch_index_from, batch_index_to, strength_from, strength_to, interpolation,revert_direction_at_midpoint, last_key_frame_position,i, number_of_items,buffer):
# Initialize variables based on the position of the keyframe
@@ -294,56 +285,160 @@ class BatchCreativeInterpolationNode:
return list(filtered_frame_numbers), list(filtered_weights)
- keyframe_positions = get_keyframe_positions(type_of_frame_distribution, dynamic_frame_distribution_values, images, linear_frame_distribution_value)
- cn_strength_values = extract_start_and_endpoint_values(type_of_strength_distribution, dynamic_strength_values, keyframe_positions, linear_strength_value)
- cn_strength_values = [literal_eval(val) if isinstance(val, str) else val for val in cn_strength_values]
-
- shifted_keyframes_position = [position + buffer - 1 for position in keyframe_positions]
- shifted_keyframe_positions_string = ','.join(str(pos) for pos in shifted_keyframes_position)
- print(f"shifted_keyframe_positions_string: {shifted_keyframe_positions_string}")
+ def calculate_influence_frame_number(key_frame_position, next_key_frame_position, distance):
+ # Calculate the absolute distance between key frames
+ key_frame_distance = abs(next_key_frame_position - key_frame_position)
+ # Apply the distance multiplier
+ extended_distance = key_frame_distance * distance
+
+ # Determine the direction of influence based on the positions of the key frames
+ if key_frame_position < next_key_frame_position:
+ # Normal case: influence extends forward
+ influence_frame_number = key_frame_position + extended_distance
+ else:
+ # Reverse case: influence extends backward
+ influence_frame_number = key_frame_position - extended_distance
+
+ # Return the result rounded to the nearest integer
+ return round(influence_frame_number)
+
+ # GET KEYFRAME POSITIONS
+ keyframe_positions = get_keyframe_positions(type_of_frame_distribution, dynamic_frame_distribution_values, images, linear_frame_distribution_value)
+
+ shifted_keyframes_position = [position + buffer - 2 for position in keyframe_positions]
+ shifted_keyframe_positions_string = ','.join(str(pos) for pos in shifted_keyframes_position)
+
+ print(f"SparseCtrl impacts on frames {shifted_keyframe_positions_string}: ", shifted_keyframe_positions_string)
sparseindexmethod = SparseIndexMethodNodeImport()
sparse_indexes, = sparseindexmethod.get_method(shifted_keyframe_positions_string)
- key_frame_influence_values = extract_keyframe_values(type_of_key_frame_influence, dynamic_key_frame_influence_values, keyframe_positions, linear_key_frame_influence_value)
- influence_ranges = calculate_dynamic_influence_ranges(keyframe_positions, key_frame_influence_values)
+ # ADD BUFFER TO KEYFRAME POSITIONS
- influence_ranges = add_starting_buffer(influence_ranges, buffer)
- last_key_frame_position = (keyframe_positions[-1]) + buffer
+ if buffer > 0:
+ keyframe_positions = [position + buffer - 1 for position in keyframe_positions]
+ keyframe_positions.insert(0, 0)
+
+ # GET STRENGTH VALUES
+ strength_values = extract_strength_values(type_of_strength_distribution, dynamic_strength_values, keyframe_positions, linear_strength_value)
+ strength_values = [literal_eval(val) if isinstance(val, str) else val for val in strength_values]
+ print(f"strength_values: {strength_values}")
+ # GET SPARSE INDEXES
+ # GET KEYFRAME INFLUENCE VALUES
+ key_frame_influence_values = extract_influence_values(type_of_key_frame_influence, dynamic_key_frame_influence_values, keyframe_positions, linear_key_frame_influence_value)
+ key_frame_influence_values = [literal_eval(val) if isinstance(val, str) else val for val in key_frame_influence_values]
+ print(f"key_frame_influence_values: {key_frame_influence_values}")
+
+ last_key_frame_position = (keyframe_positions[-1] + 1)
all_cn_frame_numbers = []
all_cn_weights = []
all_ipa_weights = []
all_ipa_frame_numbers = []
+
+ for i in range(len(keyframe_positions)):
- for i, (batch_index_from, batch_index_to_excl) in enumerate(influence_ranges):
-
- # Default values
- revert_direction_at_midpoint = False
+ keyframe_position = keyframe_positions[i]
interpolation = "ease-in-out"
- strength_from = strength_to = 1.0
-
- if i == 0:
+ # strength_from = strength_to = 1.0
+
+
+ if i == 0: # buffer
+
if buffer > 0: # First image with buffer
image = images[0]
- strength_from = strength_to = cn_strength_values[0][1] if len(cn_strength_values) > 0 else (1.0, 1.0)
- # interpolation = "ease-in-out"
+ strength_from = strength_to = strength_values[0][1]
else:
continue # Skip first image without buffer
- elif i == 1: # First image
- image = images[0]
- strength_to, strength_from = cn_strength_values[0] if len(cn_strength_values) > 0 else (0.0, 1.0)
+ batch_index_from = 0
+ batch_index_to_excl = buffer
+ print("*********************************")
+ print(f"BUFFER - frame {i}")
+ print(f"keyframe_position {keyframe_position} goes from {batch_index_from} to {batch_index_to_excl}, from {strength_from} to {strength_to}")
+ weights, frame_numbers = calculate_weights(batch_index_from, batch_index_to_excl, strength_from, strength_to, interpolation, False, last_key_frame_position, i, len(keyframe_positions), buffer)
+
+ elif i == 1: # first image
+
+ # GET IMAGE AND KEYFRAME INFLUENCE VALUES
+ image = images[0]
+ key_frame_influence_from, key_frame_influence_to = key_frame_influence_values[0]
+ start_strength, mid_strength, end_strength = strength_values[0]
+
+ keyframe_position = keyframe_positions[i]
+ next_key_frame_position = keyframe_positions[i+1]
+
+ batch_index_from = keyframe_position
+ batch_index_to_excl = calculate_influence_frame_number(keyframe_position, next_key_frame_position, key_frame_influence_to)
+ print("*********************************")
+ print(f"FIRST IMAGE - frame {i}")
+ print(f"keyframe_position {keyframe_position} goes from {batch_index_from} to {batch_index_to_excl}, from {mid_strength} to {end_strength}")
+ weights, frame_numbers = calculate_weights(batch_index_from, batch_index_to_excl, mid_strength, end_strength, interpolation, False, last_key_frame_position, i, len(keyframe_positions), buffer)
# interpolation = "ease-in"
- elif i == len(images): # Last image
+
+ elif i == len(images): # last image
+
+ # GET IMAGE AND KEYFRAME INFLUENCE VALUES
image = images[i-1]
- strength_from, strength_to = cn_strength_values[i-1] if i-1 < len(cn_strength_values) else (0.0, 1.0)
+ key_frame_influence_from,key_frame_influence_to = key_frame_influence_values[i-1]
+ start_strength, mid_strength, end_strength = strength_values[i-1]
+ # strength_from, strength_to = cn_strength_values[i-1]
+
+ keyframe_position = keyframe_positions[i]
+ previous_key_frame_position = keyframe_positions[i-1]
+
+ batch_index_from = calculate_influence_frame_number(keyframe_position, previous_key_frame_position, key_frame_influence_from)
+ batch_index_to_excl = keyframe_position
+ print("*********************************")
+ print(f"LAST IMAGE - frame {i}")
+ print(f"keyframe_position {keyframe_position} goes from {batch_index_from} to {batch_index_to_excl}, from {start_strength} to {mid_strength}")
+ weights, frame_numbers = calculate_weights(batch_index_from, batch_index_to_excl, start_strength, mid_strength, interpolation, False, last_key_frame_position, i, len(keyframe_positions), buffer)
# interpolation = "ease-out"
- else: # Middle images
- image = images[i-1]
- strength_from, strength_to = cn_strength_values[i-1] if i-1 < len(cn_strength_values) else (0.0, 1.0)
- revert_direction_at_midpoint = True
+
+ else: # middle images
+
+ # GET IMAGE AND KEYFRAME INFLUENCE VALUES
+ image = images[i-1]
+ key_frame_influence_from,key_frame_influence_to = key_frame_influence_values[i-1]
+ start_strength, mid_strength, end_strength = strength_values[i-1]
+ keyframe_position = keyframe_positions[i]
+
+ # CALCULATE WEIGHTS FOR FIRST HALF
+ previous_key_frame_position = keyframe_positions[i-1]
+ batch_index_from = calculate_influence_frame_number(keyframe_position, previous_key_frame_position, key_frame_influence_from)
+ batch_index_to_excl = keyframe_position
+
+ print("*********************************")
+ print(f"MIDDLE IMAGE - frame {i}")
+ print("------")
+ print("FRAME DETAILS FOR TESTING INFERENCE:")
+ print("batch_index_from", batch_index_from)
+ print("batch_index_to_excl", batch_index_to_excl)
+ print("strength_from", strength_from)
+ print("strength_to", strength_to)
+ print("interpolation", interpolation)
+ print("last_key_frame_position", last_key_frame_position)
+ print("i", i)
+ print("len(keyframe_positions)", len(keyframe_positions))
+ print("buffer", buffer)
+
+ print("------")
+ print(f"The first half of keyframe_position {keyframe_position} goes from {batch_index_from} to {batch_index_to_excl}, from {start_strength} to {mid_strength}")
+
+ first_half_weights, first_half_frame_numbers = calculate_weights(batch_index_from, batch_index_to_excl, start_strength, mid_strength, interpolation, False, last_key_frame_position, i, len(keyframe_positions), buffer)
+
+ # CALCULATE WEIGHTS FOR SECOND HALF
+ next_key_frame_position = keyframe_positions[i+1]
+ batch_index_from = keyframe_position
+ batch_index_to_excl = calculate_influence_frame_number(keyframe_position, next_key_frame_position, key_frame_influence_to)
+
+ print(f"The second half of keyframe_position {keyframe_position} goes from {batch_index_from} to {batch_index_to_excl}, from {mid_strength} to {end_strength}")
+ second_half_weights, second_half_frame_numbers = calculate_weights(batch_index_from, batch_index_to_excl, mid_strength, end_strength, interpolation, False, last_key_frame_position, i, len(keyframe_positions), buffer)
+
+ # COMBINE FIRST AND SECOND HALF
+ weights = np.concatenate([first_half_weights, second_half_weights])
+ frame_numbers = np.concatenate([first_half_frame_numbers, second_half_frame_numbers])
- # IMPORTS
+ # IMPORT REQUIRED NODES
latent_keyframe_interpolation_node = LatentKeyframeInterpolationNodeImport()
scaled_soft_control_net_weights = ScaledSoftUniversalWeightsImport()
timestep_keyframe_node = TimestepKeyframeNodeImport()
@@ -351,51 +446,57 @@ class BatchCreativeInterpolationNode:
apply_advanced_control_net = AdvancedControlNetApplyImport()
ipadapter_application = IPAdapterApplyImport()
ipadapter_encoder = IPAdapterEncoderImport()
-
- # CALCULATE WEIGHTS
- weights, frame_numbers = calculate_weights(batch_index_from, batch_index_to_excl, strength_from, strength_to, interpolation, revert_direction_at_midpoint, last_key_frame_position, i, len(influence_ranges), buffer)
-
- # CONTROL NET
+
+ # IF CONTROL NET IS USED, APPLY IT
if relative_cn_strength > 0.0:
cn_frame_numbers, cn_weights = process_weights(frame_numbers, weights, relative_cn_strength)
latent_keyframe, = latent_keyframe_interpolation_node.load_keyframe(cn_weights, cn_frame_numbers)
control_net_weights, _ = scaled_soft_control_net_weights.load_weights(soft_scaled_cn_weights_multiplier, False)
timestep_keyframe = timestep_keyframe_node.load_keyframe(start_percent=0.0, control_net_weights=control_net_weights, latent_keyframe=latent_keyframe, prev_timestep_keyframe=None)[0]
control_net = control_net_loader.load_controlnet(control_net_name, timestep_keyframe)[0]
- positive, negative = apply_advanced_control_net.apply_controlnet(positive, negative, control_net, image.unsqueeze(0), 1.0, 0.0, 1.0)
+ positive, negative = apply_advanced_control_net.apply_controlnet(positive, negative, control_net, image.unsqueeze(0), 1.0, ipadapter_start_at, ipadapter_end_at)
all_cn_frame_numbers.append(cn_frame_numbers)
all_cn_weights.append(cn_weights)
else:
all_cn_frame_numbers = None
all_cn_weights = None
-
- # IP ADAPTER
+ # IF IP ADAPTER IS USED, APPLY IT
if relative_ipadapter_strength > 0.0:
ipa_frame_numbers, ipa_weights = process_weights(frame_numbers, weights, relative_ipadapter_strength)
prepped_image = prep_image(image=image.unsqueeze(0), interpolation="LANCZOS", crop_position="pad", sharpening=0.0)[0]
mask = create_mask_batch(last_key_frame_position, ipa_weights, ipa_frame_numbers)
embed, = ipadapter_encoder.preprocess(clip_vision, prepped_image, True, 0.0, 1.0)
+
+ # model, = ipadapter_application.apply_ipadapter(ipadapter=ipadapter, model=model, weight=1.0, clip_vision=clip_vision,
+ # image=prepped_image, weight_type="original", noise=ipadapter_noise, embeds=None,
+ # attn_mask=mask, start_at=0.0, end_at=0.75, unfold_batch=True)
+
model, = ipadapter_application.apply_ipadapter(ipadapter=ipadapter, model=model, weight=1.0, image=None, weight_type="original",
- noise=ipadapter_noise, embeds=embed, attn_mask=mask, start_at=0.0, end_at=1.0, unfold_batch=True)
+ noise=ipadapter_noise, embeds=embed, attn_mask=mask, start_at=0.0, end_at=0.75, unfold_batch=True)
all_ipa_frame_numbers.append(ipa_frame_numbers)
all_ipa_weights.append(ipa_weights)
else:
all_ipa_frame_numbers = None
all_ipa_weights = None
- # cn_frame_numbers, cn_weights, ipadapter_frame_numbers, ipadapter_weights, buffer):
- print(f"all_cn_frame_numbers: {all_cn_frame_numbers}")
- print(f"all_cn_weights: {all_cn_weights}")
- print(f"all_ipa_frame_numbers: {all_ipa_frame_numbers}")
- print(f"all_ipa_weights: {all_ipa_weights}")
+
+ # PLOT WEIGHT COMPARISON
+ print("*********************************")
+ print("FRAME NUMBERS AND WEIGHTS")
+ print("all_ipa_frame_numbers")
+ print(all_ipa_frame_numbers)
+ print("all_ipa_weights")
+ print(all_ipa_weights)
+
+
+
comparison_diagram, = plot_weight_comparison(all_cn_frame_numbers, all_cn_weights, all_ipa_frame_numbers, all_ipa_weights, buffer)
return comparison_diagram, positive, negative, model, sparse_indexes, last_key_frame_position
-
# NODE MAPPING
NODE_CLASS_MAPPINGS = {
- "BatchCreativeInterpolation": BatchCreativeInterpolationNode
+ "BatchCreativeInterpolation": BatchCreativeInterpolationNode
}
NODE_DISPLAY_NAME_MAPPINGS = {
diff --git a/demo/creative_interpolation_example.json b/demo/creative_interpolation_example.json
index 5d1b44c..fa2616e 100644
--- a/demo/creative_interpolation_example.json
+++ b/demo/creative_interpolation_example.json
@@ -1,393 +1,77 @@
{
- "last_node_id": 473,
- "last_link_id": 918,
+ "last_node_id": 516,
+ "last_link_id": 978,
"nodes": [
{
- "id": 455,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": -835.8253173828125,
- "1": -1130.6640625,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
+ "id": 482,
+ "type": "KSampler",
+ "pos": [
+ 1585.330171916038,
+ -2137.643285948492
+ ],
"size": {
- "0": 454.0640869140625,
- "1": 388.03802490234375
+ "0": 300,
+ "1": 262
},
"flags": {},
"order": 0,
"mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## Understanding the settings\n\n
\nThere are 3 main settings:\n\n
\n\n- Key frame position\n- Length of influence\n- Strength of influence\n\n
\n\nThe type_of fields decide whether each of settings are the same for each frame or different.\n\n
\n\nWhen the type has been set to 'linear', you can adjust the value for every in with the _value fields.\n\n
\n\nWhen the type is set to 'dynamic', the text box below each setting are for the individual values - follow the format provided to set values for each frame.\n",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 450,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": -850,
- "1": -709,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 492.59747314453125,
- "1": 149.39620971679688
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## Setting frame position ⮕\n\n
\n\nSetting linear frame distribution makes the frames spaced out by the linear value - for example, if it's set to 16, the frames will be at positions 0, 16, 32, etc. If you set type to dynamic, you'll need to enter the values in the text box below.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 451,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": -849,
- "1": -540,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 497.679443359375,
- "1": 117.36077880859375
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## Set duration of frame influence ⮕\n
\n1.0 equals around the distance between this and the next frames, 2.0 equals twice this. You can set these values for each frame individually in the field below.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 452,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": -852,
- "1": -395,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 502.86639404296875,
- "1": 132.24179077148438
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## Set high and low point of influence strength ⮕\n
\n\nThe number are the range the strength runs from and to - the first value is the low point, the last is the high.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 466,
- "type": "PrimitiveNode",
- "pos": [
- 893.0571671339583,
- -1671.1880809802162
- ],
- "size": {
- "0": 210,
- "1": 82
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "outputs": [
- {
- "name": "INT",
- "type": "INT",
- "links": [
- 875
- ],
- "widget": {
- "name": "height"
- },
- "slot_index": 0
- }
- ],
- "title": "Height",
- "properties": {
- "Run widget replace on values": false
- },
- "widgets_values": [
- 512,
- "fixed"
- ]
- },
- {
- "id": 389,
- "type": "PreviewImage",
- "pos": [
- 271,
- -384
- ],
- "size": {
- "0": 969.0651245117188,
- "1": 246
- },
- "flags": {},
- "order": 18,
- "mode": 0,
"inputs": [
{
- "name": "images",
- "type": "IMAGE",
- "link": 737
+ "name": "model",
+ "type": "MODEL",
+ "link": null
+ },
+ {
+ "name": "positive",
+ "type": "CONDITIONING",
+ "link": null
+ },
+ {
+ "name": "negative",
+ "type": "CONDITIONING",
+ "link": null
+ },
+ {
+ "name": "latent_image",
+ "type": "LATENT",
+ "link": null
}
],
- "properties": {
- "Node name for S&R": "PreviewImage"
- }
- },
- {
- "id": 454,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": 153,
- "1": -735,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 231.76397705078125,
- "1": 258.7939758300781
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## Observe the graph to understand the the motion ⮕\n
\n As you tweak the settings, observe the impact on the graph. You can disconnect the positive, negative and model connections to just observe the graph without creating videos.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 456,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": 174,
- "1": -1051,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 210,
- "1": 266.1289367675781
- },
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## ⬅ Download the models from Comfy Manager\n
\nSearch the names and download the relevant models that are associated with the IPAdapter_plus node.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 445,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": -1575,
- "1": -1140,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 645.7035522460938,
- "1": 1039.391357421875
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "# A brief guide\n\n
\n\n## Philosophy for getting the most from this:\n\n
\n\nThis isn’t a tool like text to video that will perform well out of the box - it’s more like a paint brush, an artistic tool that you need to figure out how to get the best from. \n\n
\n\nThrough trial and error, you'll need to build an understanding of how the motion and settings work, what its limitations are, which inputs work best with it, etc.\n\n
\n\nIf you can figure out how to wield it, this approach can provide enough control for you to make beautiful things that match your imagination precisely.\n\n
\n\n## How to use this:\n
\n1.Select a folder with the images in them above. The most important thing that will influence the quality of your creation is the input images.\n\n
\n\n2.Try the basic settings to start. Based on the resulting generation, try to understand what happened - you can learn about the settings and observe the graphs to the right.\n\n
\n\n3.Tweak the settings until you achieve your desired effect. \n\n
\n\n## What this will & won't be suitable for:\n\nI believe that this will be good for a wide range of storytelling-driven and abstract motion.\n\nHowever, it probably won't be good for complex motion - other approaches like vid2vid are far more suitable for this.\n\n## If you're having problems:\n\n
\n\nFirst, download the latest version of this workflow from [here](https://raw.githubusercontent.com/peteromallet/steerable-motion/main/demo/creative_interpolation_example.json) and get the latest version of the node from Comfy Manager.\n\n
\n\nIf that doesn't work, drop into [our Discord](https://discord.gg/V72vk8T67n) and share your problem and I'll try to help ASAP.\n\n
\n\n\n## Want to join a community of people who are pushing open source models to their technical and artistic limits?\n\n
\n\nYou're welcome to join [our Discord](https://discord.gg/UJf6aum7WZ).\n\n
\n\nPlease share anything you generate in the steerable-motion channel.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 446,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": 2272.6748046875,
- "1": -1806.122802734375,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 210,
- "1": 271.66632080078125
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## ⬅ Tweak motion_scale to change amount of movement\n
\nYou can tweak motion_scale on the left to increase or decrease the amount of motion in the generation.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
- {
- "id": 369,
- "type": "IPAdapterModelLoader",
- "pos": [
- -75,
- -1010
- ],
- "size": {
- "0": 210,
- "1": 92.0848388671875
- },
- "flags": {},
- "order": 9,
- "mode": 0,
"outputs": [
{
- "name": "IPADAPTER",
- "type": "IPADAPTER",
- "links": [
- 910
- ],
- "shape": 3,
+ "name": "LATENT",
+ "type": "LATENT",
+ "links": [],
"slot_index": 0
}
],
"properties": {
- "Node name for S&R": "IPAdapterModelLoader"
+ "Node name for S&R": "KSampler"
},
"widgets_values": [
- "ip-adapter-plus_sd15.bin"
+ 32,
+ "fixed",
+ 25,
+ 5,
+ "dpmpp_2m_sde_gpu",
+ "exponential",
+ 1
]
},
{
"id": 370,
"type": "CLIPVisionLoader",
"pos": [
- -332,
- -1014
+ -280.7168099730984,
+ -1004.5074617878694
],
"size": {
"0": 210,
"1": 91.58576202392578
},
"flags": {},
- "order": 10,
+ "order": 1,
"mode": 0,
"outputs": [
{
@@ -408,64 +92,422 @@
]
},
{
- "id": 469,
- "type": "ACN_SparseCtrlRGBPreprocessor",
+ "id": 369,
+ "type": "IPAdapterModelLoader",
"pos": [
- -738,
- -1902
+ -20.716809973098563,
+ -1007.5074617878694
],
"size": {
- "0": 312.9380187988281,
- "1": 66
+ "0": 210,
+ "1": 92.0848388671875
},
"flags": {},
- "order": 26,
+ "order": 2,
"mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 881
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 882
- },
- {
- "name": "latent_size",
- "type": "LATENT",
- "link": 883
- }
- ],
"outputs": [
{
- "name": "proc_IMAGE",
- "type": "IMAGE",
+ "name": "IPADAPTER",
+ "type": "IPADAPTER",
"links": [
- 880
+ 910
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
- "Node name for S&R": "ACN_SparseCtrlRGBPreprocessor"
+ "Node name for S&R": "IPAdapterModelLoader"
+ },
+ "widgets_values": [
+ "ip-adapter-plus_sd15.bin"
+ ]
+ },
+ {
+ "id": 507,
+ "type": "Get image size",
+ "pos": [
+ 917,
+ -1043
+ ],
+ "size": {
+ "0": 210,
+ "1": 66
+ },
+ "flags": {},
+ "order": 3,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "INT",
+ "type": "INT",
+ "links": null,
+ "shape": 3
+ },
+ {
+ "name": "INT",
+ "type": "INT",
+ "links": null,
+ "shape": 3
+ },
+ {
+ "name": "TUPLE",
+ "type": "TUPLE",
+ "links": null,
+ "shape": 3
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "Get image size"
}
},
+ {
+ "id": 464,
+ "type": "ADE_EmptyLatentImageLarge",
+ "pos": [
+ -201,
+ -839
+ ],
+ "size": {
+ "0": 310.79998779296875,
+ "1": 74
+ },
+ "flags": {
+ "collapsed": false
+ },
+ "order": 27,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "width",
+ "type": "INT",
+ "link": 976,
+ "widget": {
+ "name": "width"
+ },
+ "slot_index": 0
+ },
+ {
+ "name": "height",
+ "type": "INT",
+ "link": 977,
+ "widget": {
+ "name": "height"
+ }
+ },
+ {
+ "name": "batch_size",
+ "type": "INT",
+ "link": 906,
+ "widget": {
+ "name": "batch_size"
+ },
+ "slot_index": 2
+ }
+ ],
+ "outputs": [
+ {
+ "name": "LATENT",
+ "type": "LATENT",
+ "links": [
+ 876,
+ 883
+ ],
+ "shape": 3,
+ "slot_index": 0
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "ADE_EmptyLatentImageLarge"
+ },
+ "widgets_values": [
+ 512,
+ 512,
+ 52
+ ],
+ "color": "#232",
+ "bgcolor": "#353"
+ },
+ {
+ "id": 436,
+ "type": "PreviewImage",
+ "pos": [
+ 485,
+ -556
+ ],
+ "size": {
+ "0": 820.0277099609375,
+ "1": 511.5301818847656
+ },
+ "flags": {},
+ "order": 24,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "link": 901
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "PreviewImage"
+ }
+ },
+ {
+ "id": 456,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": 221,
+ "1": -1010,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": {
+ "0": 210,
+ "1": 270
+ },
+ "flags": {},
+ "order": 4,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## ⬅ Download the models from Comfy Manager\n
\nSearch the names and download the relevant models that are associated with the IPAdapter_plus node.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 454,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": 212,
+ "1": -595,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": {
+ "0": 230,
+ "1": 260
+ },
+ "flags": {},
+ "order": 5,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## Observe the graph to understand the the motion ⮕\n
\n As you tweak the settings, observe the impact on the graph. You can disconnect the positive, negative and model connections to just observe the graph without creating videos.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 389,
+ "type": "PreviewImage",
+ "pos": [
+ 457,
+ -898
+ ],
+ "size": {
+ "0": 887.6273803710938,
+ "1": 246
+ },
+ "flags": {},
+ "order": 19,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "link": 737
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "PreviewImage"
+ }
+ },
+ {
+ "id": 445,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": -1589,
+ "1": -1463,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": {
+ "0": 650,
+ "1": 1040
+ },
+ "flags": {},
+ "order": 6,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "# A brief guide\n\n
\n\n## Philosophy for getting the most from this:\n\n
\n\nThis isn’t a tool like text to video that will perform well out of the box - it’s more like a paint brush, an artistic tool that you need to figure out how to get the best from. \n\n
\n\nThrough trial and error, you'll need to build an understanding of how the motion and settings work, what its limitations are, which inputs work best with it, etc.\n\n
\n\nIf you can figure out how to wield it, this approach can provide enough control for you to make beautiful things that match your imagination precisely.\n\n
\n\n## How to use this:\n
\n1.Select a folder with the images in them above. The most important thing that will influence the quality of your creation is the input images.\n\n
\n\n2.Try the basic settings to start. Based on the resulting generation, try to understand what happened - you can learn about the settings and observe the graphs to the right.\n\n
\n\n3.Tweak the settings until you achieve your desired effect. \n\n
\n\n## What this will & won't be suitable for:\n\nI believe that this will be good for a wide range of storytelling-driven and abstract motion.\n\nHowever, it probably won't be good for complex motion - other approaches like vid2vid are far more suitable for this.\n\n## If you're having problems:\n\n
\n\nFirst, download the latest version of this workflow from [here](https://raw.githubusercontent.com/peteromallet/steerable-motion/main/demo/creative_interpolation_example.json) and get the latest version of the node from Comfy Manager.\n\n
\n\nIf that doesn't work, drop into [our Discord](https://discord.gg/V72vk8T67n) and share your problem and I'll try to help ASAP.\n\n
\n\n\n## Want to join a community of people who are pushing open source models to their technical and artistic limits?\n\n
\n\nYou're welcome to join [our Discord](https://discord.gg/UJf6aum7WZ).\n\n
\n\nPlease share anything you generate in the steerable-motion channel.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 472,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": -1583,
+ "1": -357,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": [
+ 672.9640119267688,
+ 340.53735518126246
+ ],
+ "flags": {},
+ "order": 7,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## To download these models from Hugging Face\n
\n\nNavigate to the Comfy directory in your terminal and run the below for each of the models that you don't have - you can also find some of these on Comfy Manager:\n\n\n- wget -O models/controlnet/v3_sd15_sparsectrl_rgb.ckpt \"https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_sparsectrl_rgb.ckpt\"\n- wget -O models/loras/v3_sd15_adapter.ckpt \"https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_adapter.ckpt\"\n- wget -O models/clip_vision/SD1.5/pytorch_model.bin \"https://huggingface.co/openai/clip-vit-base-patch32/resolve/main/pytorch_model.bin\"\n- wget -O models/ipadapter/ip-adapter-plus-face_sd15.bin \"https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter-plus-face_sd15.bin\"\n- wget -O custom_nodes/ComfyUI-AnimateDiff-Evolved/models/v3_sd15_mm.ckpt \"https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_mm.ckpt\"",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 513,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": 2426,
+ "1": -1884,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": {
+ "0": 254.81239318847656,
+ "1": 404.44708251953125
+ },
+ "flags": {},
+ "order": 8,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## ⬅ Tweak the context to change how the motion is influences by previous and forthcoming motion\n
\n\n- context_stride + context_overlap = 2 seems to provide the smoothest motion but leaves some artifacts.\n- context_stride 1, context_overlap = 4 feels like the best combination of smooothness and artifact avoidance.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 446,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": 2385,
+ "1": -2182,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": {
+ "0": 210,
+ "1": 270
+ },
+ "flags": {},
+ "order": 9,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## ⬅ Tweak motion_scale to change amount of movement\n
\nYou can tweak motion_scale on the left to increase or decrease the amount of motion in the generation.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
{
"id": 461,
"type": "CheckpointLoaderSimple",
"pos": [
- 390,
- -1891
+ 383,
+ -1774
+ ],
+ "size": [
+ 350.53927023649453,
+ 98
],
- "size": {
- "0": 315,
- "1": 98
- },
"flags": {},
- "order": 11,
+ "order": 10,
"mode": 0,
"outputs": [
{
@@ -500,67 +542,19 @@
"Realistic_Vision_V5.0.safetensors"
]
},
- {
- "id": 467,
- "type": "ACN_SparseCtrlLoaderAdvanced",
- "pos": [
- -780,
- -1762
- ],
- "size": {
- "0": 314.50390625,
- "1": 150
- },
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "sparse_method",
- "type": "SPARSE_METHOD",
- "link": 907,
- "slot_index": 0
- },
- {
- "name": "tk_optional",
- "type": "TIMESTEP_KEYFRAME",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "CONTROL_NET",
- "type": "CONTROL_NET",
- "links": [
- 879
- ],
- "shape": 3,
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "ACN_SparseCtrlLoaderAdvanced"
- },
- "widgets_values": [
- "v3_sd15_sparsectrl_rgb.ckpt",
- true,
- 1,
- 1
- ]
- },
{
"id": 462,
"type": "CLIPTextEncode",
"pos": [
- 398,
- -1664
- ],
- "size": [
- 370.07847253978207,
- 96.74235957942187
+ 377,
+ -1593
],
+ "size": {
+ "0": 370.0784606933594,
+ "1": 96.74236297607422
+ },
"flags": {},
- "order": 19,
+ "order": 21,
"mode": 0,
"inputs": [
{
@@ -589,181 +583,19 @@
"color": "#232",
"bgcolor": "#353"
},
- {
- "id": 436,
- "type": "PreviewImage",
- "pos": [
- 454,
- -1018
- ],
- "size": {
- "0": 820.0277099609375,
- "1": 511.5301818847656
- },
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 901
- }
- ],
- "properties": {
- "Node name for S&R": "PreviewImage"
- }
- },
- {
- "id": 401,
- "type": "VHS_LoadImagesPath",
- "pos": [
- -1431,
- -1538
- ],
- "size": [
- 315,
- 194
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 737,
- 881,
- 908
- ],
- "shape": 3,
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null,
- "shape": 3
- },
- {
- "name": "INT",
- "type": "INT",
- "links": [],
- "shape": 3,
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "VHS_LoadImagesPath"
- },
- "widgets_values": {
- "directory": "input/input/",
- "image_load_cap": 0,
- "skip_first_images": 0,
- "select_every_nth": 1,
- "choose folder to upload": "image",
- "videopreview": {
- "hidden": false,
- "paused": false,
- "params": {
- "frame_load_cap": 0,
- "skip_first_images": 0,
- "filename": "input/input/",
- "type": "path",
- "format": "folder",
- "select_every_nth": 1
- }
- }
- },
- "color": "#332922",
- "bgcolor": "#593930"
- },
- {
- "id": 465,
- "type": "PrimitiveNode",
- "pos": [
- 893,
- -1826
- ],
- "size": {
- "0": 210,
- "1": 82
- },
- "flags": {},
- "order": 13,
- "mode": 0,
- "outputs": [
- {
- "name": "INT",
- "type": "INT",
- "links": [
- 874
- ],
- "widget": {
- "name": "width"
- },
- "slot_index": 0
- }
- ],
- "title": "Width",
- "properties": {
- "Run widget replace on values": false
- },
- "widgets_values": [
- 768,
- "fixed"
- ]
- },
- {
- "id": 342,
- "type": "ADE_AnimateDiffUniformContextOptions",
- "pos": [
- 1998,
- -1357
- ],
- "size": {
- "0": 417.6433410644531,
- "1": 189.57286071777344
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "outputs": [
- {
- "name": "CONTEXT_OPTIONS",
- "type": "CONTEXT_OPTIONS",
- "links": [
- 627
- ],
- "shape": 3,
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "ADE_AnimateDiffUniformContextOptions"
- },
- "widgets_values": [
- 16,
- 2,
- 2,
- "uniform",
- false
- ]
- },
{
"id": 463,
"type": "CLIPTextEncode",
"pos": [
- 364,
- -1452
+ 382,
+ -1413
+ ],
+ "size": [
+ 362.17516155787325,
+ 84.13288332508364
],
- "size": {
- "0": 438.03717041015625,
- "1": 112.69036102294922
- },
"flags": {},
- "order": 20,
+ "order": 22,
"mode": 0,
"inputs": [
{
@@ -787,91 +619,394 @@
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
- "embedding:EasyNegative"
+ "smoke"
],
"color": "#322",
"bgcolor": "#533"
},
{
- "id": 464,
- "type": "ADE_EmptyLatentImageLarge",
+ "id": 470,
+ "type": "LoraLoader",
"pos": [
- -342,
- -159
+ -681,
+ -1434
],
"size": {
- "0": 310.79998779296875,
- "1": 74
+ "0": 256.37469482421875,
+ "1": 126.03836059570312
},
- "flags": {
- "collapsed": false
- },
- "order": 25,
+ "flags": {},
+ "order": 18,
"mode": 0,
"inputs": [
{
- "name": "width",
- "type": "INT",
- "link": 874,
- "widget": {
- "name": "width"
- },
- "slot_index": 0
+ "name": "model",
+ "type": "MODEL",
+ "link": 896
},
{
- "name": "height",
- "type": "INT",
- "link": 875,
- "widget": {
- "name": "height"
- }
- },
- {
- "name": "batch_size",
- "type": "INT",
- "link": 906,
- "widget": {
- "name": "batch_size"
- },
- "slot_index": 2
+ "name": "clip",
+ "type": "CLIP",
+ "link": 893
}
],
"outputs": [
{
- "name": "LATENT",
- "type": "LATENT",
+ "name": "MODEL",
+ "type": "MODEL",
"links": [
- 876,
- 883
+ 909
+ ],
+ "shape": 3,
+ "slot_index": 0
+ },
+ {
+ "name": "CLIP",
+ "type": "CLIP",
+ "links": [
+ 894,
+ 895
+ ],
+ "shape": 3,
+ "slot_index": 1
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LoraLoader"
+ },
+ "widgets_values": [
+ "v3_sd15_adapter.ckpt",
+ 0.01,
+ 0.25
+ ]
+ },
+ {
+ "id": 467,
+ "type": "ACN_SparseCtrlLoaderAdvanced",
+ "pos": [
+ -709,
+ -1671
+ ],
+ "size": {
+ "0": 314.50390625,
+ "1": 150
+ },
+ "flags": {},
+ "order": 26,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "sparse_method",
+ "type": "SPARSE_METHOD",
+ "link": 907,
+ "slot_index": 0
+ },
+ {
+ "name": "tk_optional",
+ "type": "TIMESTEP_KEYFRAME",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "CONTROL_NET",
+ "type": "CONTROL_NET",
+ "links": [
+ 879,
+ 978
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
- "Node name for S&R": "ADE_EmptyLatentImageLarge"
+ "Node name for S&R": "ACN_SparseCtrlLoaderAdvanced"
},
"widgets_values": [
- 768,
- 512,
- 52
+ "v3_sd15_sparsectrl_rgb.ckpt",
+ true,
+ 1,
+ 1
+ ]
+ },
+ {
+ "id": 469,
+ "type": "ACN_SparseCtrlRGBPreprocessor",
+ "pos": [
+ -712,
+ -1830
],
- "color": "#232",
- "bgcolor": "#353"
+ "size": {
+ "0": 312.9380187988281,
+ "1": 66
+ },
+ "flags": {},
+ "order": 28,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": 881
+ },
+ {
+ "name": "vae",
+ "type": "VAE",
+ "link": 882
+ },
+ {
+ "name": "latent_size",
+ "type": "LATENT",
+ "link": 883
+ }
+ ],
+ "outputs": [
+ {
+ "name": "proc_IMAGE",
+ "type": "IMAGE",
+ "links": [
+ 880,
+ 963
+ ],
+ "shape": 3,
+ "slot_index": 0
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "ACN_SparseCtrlRGBPreprocessor"
+ }
+ },
+ {
+ "id": 451,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": -769,
+ "1": -434,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": [
+ 459.86432363243875,
+ 127.09552611282606
+ ],
+ "flags": {},
+ "order": 11,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## Set duration of frame influence ⮕\n
\n1.0 equals around the distance between this and the next frames, 2.0 equals twice this. You can set these values for each frame individually in the field below.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 452,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": -747,
+ "1": -252,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": [
+ 429.6674865443465,
+ 138.77713731825634
+ ],
+ "flags": {},
+ "order": 12,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## Set high and low point of influence strength ⮕\n
\n\nThe number are the range the strength runs from and to - the first value is the low point, the last is the high.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 450,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": -764,
+ "1": -615,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": [
+ 441.21501545567116,
+ 147.54996935485087
+ ],
+ "flags": {},
+ "order": 13,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## Setting frame position ⮕\n\n
\n\nSetting linear frame distribution makes the frames spaced out by the linear value - for example, if it's set to 16, the frames will be at positions 0, 16, 32, etc. If you set type to dynamic, you'll need to enter the values in the text box below.",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 455,
+ "type": "Note Plus (mtb)",
+ "pos": {
+ "0": -785,
+ "1": -1059,
+ "2": 0,
+ "3": 0,
+ "4": 0,
+ "5": 0,
+ "6": 0,
+ "7": 0,
+ "8": 0,
+ "9": 0
+ },
+ "size": {
+ "0": 450,
+ "1": 390
+ },
+ "flags": {},
+ "order": 14,
+ "mode": 0,
+ "inputs": [],
+ "outputs": [],
+ "title": "Note+ (mtb)",
+ "properties": {},
+ "widgets_values": [
+ "## Understanding the settings\n\n
\nThere are 3 main settings:\n\n
\n\n- Key frame position\n- Length of influence\n- Strength of influence\n\n
\n\nThe type_of fields decide whether each of settings are the same for each frame or different.\n\n
\n\nWhen the type has been set to 'linear', you can adjust the value for every in with the _value fields.\n\n
\n\nWhen the type is set to 'dynamic', the text box below each setting are for the individual values - follow the format provided to set values for each frame.\n",
+ "markdown",
+ ""
+ ],
+ "color": "#223",
+ "bgcolor": "#335",
+ "shape": 1
+ },
+ {
+ "id": 458,
+ "type": "VAELoader",
+ "pos": [
+ 876,
+ -1487
+ ],
+ "size": {
+ "0": 280.35577392578125,
+ "1": 95.60185241699219
+ },
+ "flags": {},
+ "order": 15,
+ "mode": 0,
+ "outputs": [
+ {
+ "name": "VAE",
+ "type": "VAE",
+ "links": [
+ 867,
+ 882
+ ],
+ "shape": 3,
+ "slot_index": 0
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "VAELoader"
+ },
+ "widgets_values": [
+ "vae-ft-mse-840000-ema-pruned.safetensors"
+ ]
+ },
+ {
+ "id": 508,
+ "type": "GetImageSize+",
+ "pos": [
+ 906,
+ -1706
+ ],
+ "size": {
+ "0": 210,
+ "1": 46
+ },
+ "flags": {},
+ "order": 20,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": 975
+ }
+ ],
+ "outputs": [
+ {
+ "name": "width",
+ "type": "INT",
+ "links": [
+ 976
+ ],
+ "shape": 3,
+ "slot_index": 0
+ },
+ {
+ "name": "height",
+ "type": "INT",
+ "links": [
+ 977
+ ],
+ "shape": 3,
+ "slot_index": 1
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "GetImageSize+"
+ }
},
{
"id": 468,
"type": "ACN_AdvancedControlNetApply",
"pos": [
- -305,
- -1816
+ -239,
+ -1880.1191788018743
],
"size": {
"0": 314.1339111328125,
"1": 246
},
"flags": {},
- "order": 27,
+ "order": 29,
"mode": 0,
"inputs": [
{
@@ -922,7 +1057,7 @@
"name": "positive",
"type": "CONDITIONING",
"links": [
- 915
+ 967
],
"shape": 3,
"slot_index": 0
@@ -931,7 +1066,7 @@
"name": "negative",
"type": "CONDITIONING",
"links": [
- 916
+ 968
],
"shape": 3,
"slot_index": 1
@@ -941,73 +1076,163 @@
"Node name for S&R": "ACN_AdvancedControlNetApply"
},
"widgets_values": [
- 1,
+ 0.9,
0,
- 0.7000000000000001
+ 0.33
]
},
{
- "id": 470,
- "type": "LoraLoader",
+ "id": 505,
+ "type": "ACN_AdvancedControlNetApply",
"pos": [
- -261,
- -1480
+ -233,
+ -1539
+ ],
+ "size": [
+ 285.6000061035156,
+ 246
],
- "size": {
- "0": 256.37469482421875,
- "1": 126.03836059570312
- },
"flags": {},
- "order": 17,
+ "order": 30,
"mode": 0,
"inputs": [
{
- "name": "model",
- "type": "MODEL",
- "link": 896
+ "name": "positive",
+ "type": "CONDITIONING",
+ "link": 967,
+ "slot_index": 0
},
{
- "name": "clip",
- "type": "CLIP",
- "link": 893
+ "name": "negative",
+ "type": "CONDITIONING",
+ "link": 968,
+ "slot_index": 1
+ },
+ {
+ "name": "control_net",
+ "type": "CONTROL_NET",
+ "link": 978
+ },
+ {
+ "name": "image",
+ "type": "IMAGE",
+ "link": 963
+ },
+ {
+ "name": "mask_optional",
+ "type": "MASK",
+ "link": null
+ },
+ {
+ "name": "timestep_kf",
+ "type": "TIMESTEP_KEYFRAME",
+ "link": null
+ },
+ {
+ "name": "latent_kf_override",
+ "type": "LATENT_KEYFRAME",
+ "link": null
+ },
+ {
+ "name": "weights_override",
+ "type": "CONTROL_NET_WEIGHTS",
+ "link": null
}
],
"outputs": [
{
- "name": "MODEL",
- "type": "MODEL",
+ "name": "positive",
+ "type": "CONDITIONING",
"links": [
- 909
+ 971
],
"shape": 3,
"slot_index": 0
},
{
- "name": "CLIP",
- "type": "CLIP",
+ "name": "negative",
+ "type": "CONDITIONING",
"links": [
- 894,
- 895
+ 972
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
- "Node name for S&R": "LoraLoader"
+ "Node name for S&R": "ACN_AdvancedControlNetApply"
},
"widgets_values": [
- "v3_sd15_adapter.ckpt",
- 1,
- 1
+ 0.7000000000000001,
+ 0.651,
+ 0.725
]
},
+ {
+ "id": 281,
+ "type": "VHS_VideoCombine",
+ "pos": [
+ 1588,
+ -1052
+ ],
+ "size": [
+ 810,
+ 1054
+ ],
+ "flags": {},
+ "order": 34,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "images",
+ "type": "IMAGE",
+ "link": 938
+ },
+ {
+ "name": "audio",
+ "type": "VHS_AUDIO",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "Filenames",
+ "type": "VHS_FILENAMES",
+ "links": null,
+ "shape": 3
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "VHS_VideoCombine"
+ },
+ "widgets_values": {
+ "frame_rate": 15,
+ "loop_count": 3,
+ "filename_prefix": "steerable-motion/AD_",
+ "format": "video/h264-mp4",
+ "pix_fmt": "yuv420p",
+ "crf": 20,
+ "save_metadata": true,
+ "pingpong": false,
+ "save_output": true,
+ "videopreview": {
+ "hidden": false,
+ "paused": false,
+ "params": {
+ "filename": "AD__00420.mp4",
+ "subfolder": "steerable-motion",
+ "type": "output",
+ "format": "video/h264-mp4"
+ }
+ }
+ }
+ },
{
"id": 354,
"type": "VHS_SplitImages",
"pos": [
- 1642,
- -966
+ 1639,
+ -1266
],
"size": {
"0": 231.97152709960938,
@@ -1016,13 +1241,13 @@
"flags": {
"collapsed": true
},
- "order": 29,
+ "order": 32,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
- "link": 756
+ "link": 923
}
],
"outputs": [
@@ -1043,7 +1268,7 @@
"name": "IMAGE_B",
"type": "IMAGE",
"links": [
- 758
+ 928
],
"shape": 3,
"slot_index": 2
@@ -1063,80 +1288,12 @@
"split_index": 4
}
},
- {
- "id": 458,
- "type": "VAELoader",
- "pos": [
- 907,
- -1450
- ],
- "size": {
- "0": 280.35577392578125,
- "1": 95.60185241699219
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 867,
- 882
- ],
- "shape": 3,
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAELoader"
- },
- "widgets_values": [
- "vae-ft-mse-840000-ema-pruned.safetensors"
- ]
- },
- {
- "id": 472,
- "type": "Note Plus (mtb)",
- "pos": {
- "0": -735,
- "1": -1575,
- "2": 0,
- "3": 0,
- "4": 0,
- "5": 0,
- "6": 0,
- "7": 0,
- "8": 0,
- "9": 0
- },
- "size": {
- "0": 292.2577209472656,
- "1": 176.61474609375
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [],
- "outputs": [],
- "title": "Note+ (mtb)",
- "properties": {},
- "widgets_values": [
- "## ⬆ Download these models from Hugging Face\n
\nGo [here](https://huggingface.co/guoyww/animatediff/tree/main) and download the models with the same name into your models/controlnet folder.",
- "markdown",
- ""
- ],
- "color": "#223",
- "bgcolor": "#335",
- "shape": 1
- },
{
"id": 292,
"type": "STMFNet VFI",
"pos": [
- 2063,
- -964
+ 2016,
+ -1267
],
"size": {
"0": 295.6000061035156,
@@ -1145,13 +1302,13 @@
"flags": {
"collapsed": true
},
- "order": 30,
+ "order": 33,
"mode": 0,
"inputs": [
{
"name": "frames",
"type": "IMAGE",
- "link": 758
+ "link": 928
},
{
"name": "optional_interpolation_states",
@@ -1164,7 +1321,7 @@
"name": "IMAGE",
"type": "IMAGE",
"links": [
- 656
+ 938
],
"shape": 3,
"slot_index": 0
@@ -1178,267 +1335,88 @@
15,
2,
true,
- true
+ false
]
},
{
- "id": 207,
- "type": "KSampler Adv. (Efficient)",
+ "id": 401,
+ "type": "VHS_LoadImagesPath",
"pos": [
- 1494,
- -1842
+ -1426.3693935183685,
+ -1835.5733992417513
],
- "size": {
- "0": 420.55169677734375,
- "1": 693.31201171875
- },
- "flags": {
- "pinned": false
- },
- "order": 28,
+ "size": [
+ 320,
+ 194
+ ],
+ "flags": {},
+ "order": 16,
"mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 815
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 915
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 916
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 876
- },
- {
- "name": "optional_vae",
- "type": "VAE",
- "link": 867
- },
- {
- "name": "script",
- "type": "SCRIPT",
- "link": null,
- "slot_index": 5
- }
- ],
"outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [],
- "shape": 3,
- "slot_index": 0
- },
- {
- "name": "CONDITIONING+",
- "type": "CONDITIONING",
- "links": [],
- "shape": 3,
- "slot_index": 1
- },
- {
- "name": "CONDITIONING-",
- "type": "CONDITIONING",
- "links": [],
- "shape": 3,
- "slot_index": 2
- },
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [],
- "shape": 3,
- "slot_index": 3
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [],
- "shape": 3,
- "slot_index": 4
- },
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
- 756
- ],
- "shape": 3,
- "slot_index": 5
- }
- ],
- "title": "KSampler Adv. (Efficient), CN sampler",
- "properties": {
- "Node name for S&R": "KSampler Adv. (Efficient)"
- },
- "widgets_values": [
- "enable",
- 6,
- null,
- 20,
- 8,
- "euler_ancestral",
- "normal",
- 0,
- 20,
- "disable",
- "auto",
- "true"
- ],
- "color": "#222233",
- "bgcolor": "#333355",
- "shape": 1
- },
- {
- "id": 187,
- "type": "ADE_AnimateDiffLoaderWithContext",
- "pos": [
- 1991,
- -1797
- ],
- "size": {
- "0": 261.322998046875,
- "1": 320.7745056152344
- },
- "flags": {
- "pinned": false
- },
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 900,
- "slot_index": 0
- },
- {
- "name": "context_options",
- "type": "CONTEXT_OPTIONS",
- "link": 627,
- "slot_index": 1
- },
- {
- "name": "motion_lora",
- "type": "MOTION_LORA",
- "link": null
- },
- {
- "name": "motion_model_settings",
- "type": "MOTION_MODEL_SETTINGS",
- "link": null,
- "slot_index": 3
- },
- {
- "name": "sample_settings",
- "type": "sample_settings",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 815
+ 737,
+ 881,
+ 908,
+ 975
],
"shape": 3,
"slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "ADE_AnimateDiffLoaderWithContext"
- },
- "widgets_values": [
- "v3_sd15_mm.ckpt",
- "sqrt_linear (AnimateDiff)",
- 1.5,
- false
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 281,
- "type": "VHS_VideoCombine",
- "pos": [
- 1521,
- -757
- ],
- "size": [
- 807.1564331054688,
- 792.1042887369791
- ],
- "flags": {},
- "order": 31,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 656
},
{
- "name": "audio",
- "type": "VHS_AUDIO",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "Filenames",
- "type": "VHS_FILENAMES",
+ "name": "MASK",
+ "type": "MASK",
"links": null,
"shape": 3
+ },
+ {
+ "name": "INT",
+ "type": "INT",
+ "links": [],
+ "shape": 3,
+ "slot_index": 2
}
],
"properties": {
- "Node name for S&R": "VHS_VideoCombine"
+ "Node name for S&R": "VHS_LoadImagesPath"
},
"widgets_values": {
- "frame_rate": 14,
- "loop_count": 0,
- "filename_prefix": "steerable-motion/AD_",
- "format": "video/h264-mp4",
- "pix_fmt": "yuv420p",
- "crf": 20,
- "save_metadata": true,
- "pingpong": false,
- "save_output": true,
+ "directory": "/workspace/ComfyUI/input/input_coffee/",
+ "image_load_cap": 0,
+ "skip_first_images": 0,
+ "select_every_nth": 1,
+ "choose folder to upload": "image",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
- "filename": "AD__00182.mp4",
- "subfolder": "steerable-motion",
- "type": "output",
- "format": "video/h264-mp4"
+ "frame_load_cap": 0,
+ "skip_first_images": 0,
+ "filename": "/workspace/ComfyUI/input/input_coffee/",
+ "type": "path",
+ "format": "folder",
+ "select_every_nth": 1
}
}
- }
+ },
+ "color": "#332922",
+ "bgcolor": "#593930"
},
{
"id": 473,
"type": "BatchCreativeInterpolation",
"pos": [
- -317,
- -845
+ -222,
+ -686
],
"size": {
"0": 400,
- "1": 564
+ "1": 656
},
"flags": {},
- "order": 21,
+ "order": 23,
"mode": 0,
"inputs": [
{
@@ -1526,6 +1504,12 @@
],
"shape": 3,
"slot_index": 5
+ },
+ {
+ "name": "COLOR_MATCH_FRAMES",
+ "type": "STRING",
+ "links": null,
+ "shape": 3
}
],
"properties": {
@@ -1535,19 +1519,243 @@
"control_v11f1e_sd15_tile_fp16.safetensors",
"linear",
24,
- "0,10,26,40",
+ "0,24,60",
"linear",
- 1.6,
- "1.0,1.0,1.0,0.5",
+ "0.85",
+ "(0.9,0.5),(0.2,0.3)",
"linear",
- "(0.3,0.60)",
+ "(0.25,0.4,0.25)",
"(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0)",
0.85,
4,
- 0.3,
+ 0,
1,
- 0.3
+ 0.2,
+ 0.34,
+ 0.65
]
+ },
+ {
+ "id": 187,
+ "type": "ADE_AnimateDiffLoaderWithContext",
+ "pos": [
+ 2025,
+ -2177
+ ],
+ "size": [
+ 312.0755090205557,
+ 252.39730613998154
+ ],
+ "flags": {
+ "pinned": false
+ },
+ "order": 25,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "MODEL",
+ "link": 900,
+ "slot_index": 0
+ },
+ {
+ "name": "context_options",
+ "type": "CONTEXT_OPTIONS",
+ "link": 627,
+ "slot_index": 1
+ },
+ {
+ "name": "motion_lora",
+ "type": "MOTION_LORA",
+ "link": null
+ },
+ {
+ "name": "motion_model_settings",
+ "type": "MOTION_MODEL_SETTINGS",
+ "link": null,
+ "slot_index": 3
+ },
+ {
+ "name": "sample_settings",
+ "type": "sample_settings",
+ "link": null
+ }
+ ],
+ "outputs": [
+ {
+ "name": "MODEL",
+ "type": "MODEL",
+ "links": [
+ 935
+ ],
+ "shape": 3,
+ "slot_index": 0
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "ADE_AnimateDiffLoaderWithContext"
+ },
+ "widgets_values": [
+ "v3_sd15_mm.ckpt",
+ "sqrt_linear (AnimateDiff)",
+ 1.3,
+ false
+ ],
+ "color": "#232",
+ "bgcolor": "#353"
+ },
+ {
+ "id": 342,
+ "type": "ADE_AnimateDiffUniformContextOptions",
+ "pos": [
+ 2074,
+ -1854
+ ],
+ "size": [
+ 271.8603479649696,
+ 365.0423100930834
+ ],
+ "flags": {},
+ "order": 17,
+ "mode": 0,
+ "outputs": [
+ {
+ "name": "CONTEXT_OPTIONS",
+ "type": "CONTEXT_OPTIONS",
+ "links": [
+ 627
+ ],
+ "shape": 3,
+ "slot_index": 0
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "ADE_AnimateDiffUniformContextOptions"
+ },
+ "widgets_values": [
+ 16,
+ 2,
+ 4,
+ "uniform",
+ false
+ ]
+ },
+ {
+ "id": 207,
+ "type": "KSampler Adv. (Efficient)",
+ "pos": [
+ 1486,
+ -2172
+ ],
+ "size": {
+ "0": 496.3030090332031,
+ "1": 655.8421630859375
+ },
+ "flags": {
+ "pinned": false
+ },
+ "order": 31,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "model",
+ "type": "MODEL",
+ "link": 935
+ },
+ {
+ "name": "positive",
+ "type": "CONDITIONING",
+ "link": 971
+ },
+ {
+ "name": "negative",
+ "type": "CONDITIONING",
+ "link": 972
+ },
+ {
+ "name": "latent_image",
+ "type": "LATENT",
+ "link": 876
+ },
+ {
+ "name": "optional_vae",
+ "type": "VAE",
+ "link": 867
+ },
+ {
+ "name": "script",
+ "type": "SCRIPT",
+ "link": null,
+ "slot_index": 5
+ }
+ ],
+ "outputs": [
+ {
+ "name": "MODEL",
+ "type": "MODEL",
+ "links": [],
+ "shape": 3,
+ "slot_index": 0
+ },
+ {
+ "name": "CONDITIONING+",
+ "type": "CONDITIONING",
+ "links": [],
+ "shape": 3,
+ "slot_index": 1
+ },
+ {
+ "name": "CONDITIONING-",
+ "type": "CONDITIONING",
+ "links": [],
+ "shape": 3,
+ "slot_index": 2
+ },
+ {
+ "name": "LATENT",
+ "type": "LATENT",
+ "links": [],
+ "shape": 3,
+ "slot_index": 3
+ },
+ {
+ "name": "VAE",
+ "type": "VAE",
+ "links": [],
+ "shape": 3,
+ "slot_index": 4
+ },
+ {
+ "name": "IMAGE",
+ "type": "IMAGE",
+ "links": [
+ 923
+ ],
+ "shape": 3,
+ "slot_index": 5
+ }
+ ],
+ "title": "KSampler Adv. (Efficient), CN sampler",
+ "properties": {
+ "Node name for S&R": "KSampler Adv. (Efficient)"
+ },
+ "widgets_values": [
+ "enable",
+ 5,
+ null,
+ 20,
+ 8,
+ "euler_ancestral",
+ "normal",
+ 0,
+ 20,
+ "disable",
+ "auto",
+ "true"
+ ],
+ "color": "#222233",
+ "bgcolor": "#333355",
+ "shape": 1
}
],
"links": [
@@ -1559,14 +1767,6 @@
1,
"CONTEXT_OPTIONS"
],
- [
- 656,
- 292,
- 0,
- 281,
- 0,
- "IMAGE"
- ],
[
737,
401,
@@ -1575,30 +1775,6 @@
0,
"IMAGE"
],
- [
- 756,
- 207,
- 5,
- 354,
- 0,
- "IMAGE"
- ],
- [
- 758,
- 354,
- 2,
- 292,
- 0,
- "IMAGE"
- ],
- [
- 815,
- 187,
- 0,
- 207,
- 0,
- "MODEL"
- ],
[
867,
458,
@@ -1607,22 +1783,6 @@
4,
"VAE"
],
- [
- 874,
- 465,
- 0,
- 464,
- 0,
- "INT"
- ],
- [
- 875,
- 466,
- 0,
- 464,
- 1,
- "INT"
- ],
[
876,
464,
@@ -1783,22 +1943,6 @@
1,
"CONDITIONING"
],
- [
- 915,
- 468,
- 0,
- 207,
- 1,
- "CONDITIONING"
- ],
- [
- 916,
- 468,
- 1,
- 207,
- 2,
- "CONDITIONING"
- ],
[
917,
473,
@@ -1814,16 +1958,120 @@
468,
1,
"CONDITIONING"
+ ],
+ [
+ 923,
+ 207,
+ 5,
+ 354,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 928,
+ 354,
+ 2,
+ 292,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 935,
+ 187,
+ 0,
+ 207,
+ 0,
+ "MODEL"
+ ],
+ [
+ 938,
+ 292,
+ 0,
+ 281,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 963,
+ 469,
+ 0,
+ 505,
+ 3,
+ "IMAGE"
+ ],
+ [
+ 967,
+ 468,
+ 0,
+ 505,
+ 0,
+ "CONDITIONING"
+ ],
+ [
+ 968,
+ 468,
+ 1,
+ 505,
+ 1,
+ "CONDITIONING"
+ ],
+ [
+ 971,
+ 505,
+ 0,
+ 207,
+ 1,
+ "CONDITIONING"
+ ],
+ [
+ 972,
+ 505,
+ 1,
+ 207,
+ 2,
+ "CONDITIONING"
+ ],
+ [
+ 975,
+ 401,
+ 0,
+ 508,
+ 0,
+ "IMAGE"
+ ],
+ [
+ 976,
+ 508,
+ 0,
+ 464,
+ 0,
+ "INT"
+ ],
+ [
+ 977,
+ 508,
+ 1,
+ 464,
+ 1,
+ "INT"
+ ],
+ [
+ 978,
+ 467,
+ 0,
+ 505,
+ 2,
+ "CONTROL_NET"
]
],
"groups": [
{
- "title": "First sampler, interpolation",
+ "title": "Sampler & AD",
"bounding": [
- 1377,
- -1935,
- 1163,
- 860
+ 1351,
+ -2293,
+ 1409,
+ 868
],
"color": "#8A8",
"font_size": 24
@@ -1831,10 +2079,10 @@
{
"title": "Increase Framerate",
"bounding": [
- 1400,
- -1041,
- 1079,
- 100
+ 1358,
+ -1360,
+ 1048,
+ 129
],
"color": "#8A8",
"font_size": 24
@@ -1842,10 +2090,10 @@
{
"title": "Saving",
"bounding": [
- 1407,
- -906,
- 1008,
- 1123
+ 1456,
+ -1163,
+ 1044,
+ 1843
],
"color": "#a1309b",
"font_size": 24
@@ -1853,8 +2101,8 @@
{
"title": "Group",
"bounding": [
- -872,
- -1228,
+ -828,
+ -1159,
2194,
1190
],
@@ -1864,8 +2112,8 @@
{
"title": "Group",
"bounding": [
- -1537,
- -1714,
+ -1530,
+ -1993,
580,
467
],
@@ -1875,8 +2123,8 @@
{
"title": "Basic Node",
"bounding": [
- 273,
- -1948,
+ 268,
+ -1905,
996,
680
],
@@ -1886,10 +2134,10 @@
{
"title": "Group",
"bounding": [
- -846,
- -2032,
- 1057,
- 754
+ -858,
+ -2003,
+ 1052,
+ 800
],
"color": "#3f789e",
"font_size": 24