From 4d41e150efa540a2eb5db192e50a4698812b3a31 Mon Sep 17 00:00:00 2001 From: Jordan Thompson Date: Fri, 25 Aug 2023 13:48:19 -0700 Subject: [PATCH] Perlin Power Fractal Latent Add Perlin Power Fractal Latent Patch Constant Number --- README.md | 1 + WAS_Node_Suite.py | 89 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9fec2ad..1552d15 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ - Number to Int - Number to String - Number to Text + - Perlin Power Fractal Latent: Create a power fractal based latent image. Doesn't work with all samplers (unless you add noise). - Random Number - Save Text File: Save a text string to a file - Samples Passthrough (Stat System): Logs RAM, VRAM, and Disk usage to the console. diff --git a/WAS_Node_Suite.py b/WAS_Node_Suite.py index 6feaf08..76dd8a6 100644 --- a/WAS_Node_Suite.py +++ b/WAS_Node_Suite.py @@ -418,6 +418,12 @@ def get_sha256(file_path): sha256_hash.update(chunk) return sha256_hash.hexdigest() +# Batch Seed Generator +def seed_batch(seed, batches, seeds): + rng = np.random.default_rng(seed) + btch = [rng.choice(2**32 - 1, seeds, replace=False).tolist() for _ in range(batches)] + return btch + # Download File def download_file(url, filename=None, path=None): if not filename: @@ -4156,8 +4162,8 @@ class WAS_Image_Perlin_Power_Fractal: def INPUT_TYPES(cls): return { "required": { - "width": ("INT", {"default": 512, "max": 2048, "min": 64, "step": 1}), - "height": ("INT", {"default": 512, "max": 2048, "min": 64, "step": 1}), + "width": ("INT", {"default": 512, "max": 8192, "min": 64, "step": 1}), + "height": ("INT", {"default": 512, "max": 8192, "min": 64, "step": 1}), "scale": ("INT", {"default": 100, "max": 2048, "min": 2, "step": 1}), "octaves": ("INT", {"default": 4, "max": 8, "min": 0, "step": 1}), "persistence": ("FLOAT", {"default": 0.5, "max": 100.0, "min": 0.01, "step": 0.01}), @@ -4179,7 +4185,78 @@ class WAS_Image_Perlin_Power_Fractal: image = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, seed) - return (pil2tensor(image), ) + return (pil2tensor(image), ) + +# PERLIN POWER FRACTAL LATENT + +class WAS_Perlin_Power_Fractal_Latent: + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "vae": ("VAE",), + "width": ("INT", {"default": 512, "max": 8192, "min": 64, "step": 1}), + "height": ("INT", {"default": 512, "max": 8192, "min": 64, "step": 1}), + "scale": ("INT", {"default": 100, "max": 2048, "min": 2, "step": 1}), + "octaves": ("INT", {"default": 8, "max": 8, "min": 0, "step": 1}), + "persistence": ("FLOAT", {"default": 1.0, "max": 100.0, "min": 0.01, "step": 0.01}), + "lacunarity": ("FLOAT", {"default": 2.0, "max": 100.0, "min": 0.01, "step": 0.01}), + "exponent": ("FLOAT", {"default": 4.0, "max": 100.0, "min": 0.01, "step": 0.01}), + "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), + "batch_size": ("INT", {"default": 1, "min": 1, "max": 64, "step": 1}) + }, + } + + RETURN_TYPES = ("LATENT",) + RETURN_NAMES = ("latents",) + FUNCTION = "power_fractal_latent" + + CATEGORY = "WAS Suite/Latent/Generate" + + def power_fractal_latent(self, vae, width, height, scale, octaves, persistence, lacunarity, exponent, seed, batch_size): + + WTools = WAS_Tools_Class() + encoder = nodes.VAEEncode() + rgbmix = WAS_Image_RGB_Merge() + + if batch_size > 1: + + latents = [] + seeds = seed_batch(seed, batch_size, 3) + + for batch in range(batch_size): + + batch_seeds = seeds[batch] + + r = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, batch_seeds[0]) + g = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, batch_seeds[1]) + b = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, batch_seeds[2]) + + rgb_noise = rgbmix.merge_channels(pil2tensor(r), pil2tensor(g), pil2tensor(b)) + encoded_noise = encoder.encode(pixels=rgb_noise[0], vae=vae) + + latents.append(encoded_noise[0]['samples']) + + latents = torch.cat(latents) + + return ({'samples': latents}, ) + + else: + + r = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, seed) + g = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, seed+1) + b = WTools.perlin_power_fractal(width, height, octaves, persistence, lacunarity, exponent, scale, seed+2) + + rgb_noise = rgbmix.merge_channels(pil2tensor(r), pil2tensor(g), pil2tensor(b)) + + tensors = rgb_noise + + latents = encoder.encode(pixels=tensors[0], vae=vae) + + return latents # IMAGE VORONOI NOISE FILTER @@ -9918,7 +9995,8 @@ class WAS_Text_to_Conditioning: CATEGORY = "WAS Suite/Text/Operations" def text_to_conditioning(self, clip, text): - return ([[clip.encode(text), {}]], ) + encode = clip.encode(text) + return ([[encode[0][0][0], encode[0][0][1], {}]], ) # TEXT PARSE TOKENS @@ -11463,7 +11541,7 @@ class WAS_Constant_Number: return (float(number), float(number), int(number) ) elif number_type == 'bool': boolean = (1 if int(number) > 0 else 0) - return (int(boolean), float(boolean), int(boolan) ) + return (int(boolean), float(boolean), int(boolean) ) else: return (number, float(number), int(number) ) @@ -13133,6 +13211,7 @@ NODE_CLASS_MAPPINGS = { "Number to Seed": WAS_Number_To_Seed, "Number to String": WAS_Number_To_String, "Number to Text": WAS_Number_To_Text, + "Perlin Power Fractal Latent": WAS_Perlin_Power_Fractal_Latent, "Prompt Styles Selector": WAS_Prompt_Styles_Selector, "Prompt Multiple Styles Selector": WAS_Prompt_Multiple_Styles_Selector, "Random Number": WAS_Random_Number,