diff --git a/README.md b/README.md index 1a6561e..9eabab1 100644 --- a/README.md +++ b/README.md @@ -79,12 +79,17 @@ This custom node helps to conveniently enhance images through Detector, Detailer * PixelKSampleUpscalerProvider - An upscaler is provided that converts latent to pixels using VAEDecode, performs upscaling, converts back to latent using VAEEncode, and then performs k-sampling. This upscaler can be attached to nodes such as 'Iterative Upscale' for use. * Similar to 'Latent Scale (on Pixel Space)', if upscale_model_opt is provided, it performs pixel upscaling using the model. * PixelTiledKSampleUpscalerProvider - It is similar to PixelKSampleUpscalerProvider, but it uses ComfyUI_TiledKSampler and Tiled VAE Decoder/Encoder to avoid GPU VRAM issues at high resolutions. - * You need to install the [ComfyUI_TiledKSampler](https://github.com/BlenderNeko/ComfyUI_TiledKSampler) node extension. + * You need to install the [BlenderNeko/ComfyUI_TiledKSampler](https://github.com/BlenderNeko/ComfyUI_TiledKSampler) node extension. * DenoiseScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the denoise to target_denoise as the step progresses. * CfgScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the cfg to target_cfg as the step progresses. * PixelKSampleHookCombine - This is used to connect two PK_HOOKs. hook1 is executed first and then hook2 is executed. * If you want to simultaneously change cfg and denoise, you can combine the PK_HOOKs of CfgScheduleHookProvider and PixelKSampleHookCombine. +* NoiseInjectionHookProvider - During each iteration of IterativeUpscale, noise is injected into the latent space while varying the strength according to a schedule. + * You need to install the [BlenderNeko/ComfyUI_Noise](https://github.com/BlenderNeko/ComfyUI_Noise) node extension. + * The seed serves as the initial value required for generating noise, and it increments by 1 with each iteration as the process unfolds. + * The source determines the types of CPU noise and GPU noise to be configured. + * Currently, there is only a simple schedule available, where the strength of the noise varies from start_strength to end_strength during the progression of each iteration. * Iterative Upscale (Latent) - The upscaler takes the input upscaler and splits the scale_factor into steps, then iteratively performs upscaling. This takes latent as input and outputs latent as the result. @@ -95,7 +100,7 @@ This takes latent as input and outputs latent as the result. * Note: The latent encoded through VAEEncodeForInpaint cannot be used. * KSamplerProvider - This is a wrapper that enables KSampler to be used in TwoSamplersForMask TwoSamplersForMaskUpscalerProvider. * TiledKSamplerProvider - ComfyUI_TiledKSampler is a wrapper that provides KSAMPLER. - * You need to install the [ComfyUI_TiledKSampler](https://github.com/BlenderNeko/ComfyUI_TiledKSampler) node extension. + * You need to install the [BlenderNeko/ComfyUI_TiledKSampler](https://github.com/BlenderNeko/ComfyUI_TiledKSampler) node extension. * TwoAdvancedSamplersForMask - TwoSamplersForMask is similar to TwoAdvancedSamplersForMask, but they differ in their operation. TwoSamplersForMask performs sampling in the mask area only after all the samples in the base area are finished. On the other hand, TwoAdvancedSamplersForMask performs sampling in both the base area and the mask area sequentially at each step. * KSamplerAdvancedProvider - This is a wrapper that enables KSampler to be used in TwoAdvancedSamplersForMask. diff --git a/__init__.py b/__init__.py index 741c278..9c9cdca 100644 --- a/__init__.py +++ b/__init__.py @@ -138,6 +138,7 @@ NODE_CLASS_MAPPINGS = { "PixelKSampleHookCombine": PixelKSampleHookCombine, "DenoiseScheduleHookProvider": DenoiseScheduleHookProvider, "CfgScheduleHookProvider": CfgScheduleHookProvider, + "NoiseInjectionHookProvider": NoiseInjectionHookProvider, "BitwiseAndMask": BitwiseAndMask, "SubtractMask": SubtractMask, diff --git a/modules/impact/config.py b/modules/impact/config.py index 91559a0..45c4967 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -2,7 +2,7 @@ import configparser import os -version = "V3.18" +version = "V3.19" dependency_version = 9 diff --git a/modules/impact/core.py b/modules/impact/core.py index f2d3089..f4c9a87 100644 --- a/modules/impact/core.py +++ b/modules/impact/core.py @@ -757,7 +757,7 @@ def vae_decode(vae, samples, use_tile, hook): pixels = nodes.VAEDecode().decode(vae, samples)[0] if hook is not None: - hook.post_decode(pixels) + pixels = hook.post_decode(pixels) return pixels @@ -769,7 +769,7 @@ def vae_encode(vae, pixels, use_tile, hook): samples = nodes.VAEEncode().encode(vae, pixels)[0] if hook is not None: - hook.post_encode(samples) + samples = hook.post_encode(samples) return samples @@ -1158,6 +1158,41 @@ class PixelKSampleUpscaler: return refined_latent +# REQUIREMENTS: BlenderNeko/ComfyUI Noise +try: + class InjectNoiseHook(PixelKSampleHook): + target_cfg = 0 + + def __init__(self, source, seed, start_strength, end_strength): + super().__init__() + self.source = source + self.seed = seed + self.start_strength = start_strength + self.end_strength = end_strength + + def post_encode(self, samples): + # gen noise + size = samples['samples'].shape + seed = self.cur_step + self.seed + from custom_nodes.ComfyUI_Noise.nodes import NoisyLatentImage, InjectNoise + noise = NoisyLatentImage().create_noisy_latents(self.source, seed, size[3]*8, size[2]*8, size[0])[0] + + # inj noise + mask = None + if 'noise_mask' in samples: + mask = samples['noise_mask'] + + strength = self.start_strength + (self.end_strength-self.start_strength)*self.cur_step/self.total_step + samples = InjectNoise().inject_noise(samples, strength, noise, mask)[0] + + if mask is not None: + samples['noise_mask'] = mask + + return samples +except: + pass + + # REQUIREMENTS: BlenderNeko/ComfyUI_TiledKSampler try: class TiledKSamplerWrapper: diff --git a/modules/impact/impact_pack.py b/modules/impact/impact_pack.py index ec94f66..216b7c0 100644 --- a/modules/impact/impact_pack.py +++ b/modules/impact/impact_pack.py @@ -1074,6 +1074,40 @@ class CfgScheduleHookProvider: return (hook, ) +class NoiseInjectionHookProvider: + schedules = ["simple"] + + @classmethod + def INPUT_TYPES(s): + return {"required": { + "schedule_for_iteration": (s.schedules,), + "source": (["CPU", "GPU"],), + "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}), + "start_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 200.0, "step": 0.01}), + "end_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 200.0, "step": 0.01}), + }, + } + + RETURN_TYPES = ("PK_HOOK",) + FUNCTION = "doit" + + CATEGORY = "ImpactPack/Upscale" + + def doit(self, schedule_for_iteration, source, seed, start_strength, end_strength): + try: + hook = None + if schedule_for_iteration == "simple": + hook = core.InjectNoiseHook(source, seed, start_strength, end_strength) + + return (hook, ) + return (upscaler,) + except Exception as e: + print("[ERROR] NoiseInjectionHookProvider: 'ComfyUI Noise' custom node isn't installed. You must install 'BlenderNeko/ComfyUI Noise' extension to use this node.") + print(f"\t{e}") + pass + + + class DenoiseScheduleHookProvider: schedules = ["simple"]