mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): sdxl graphs
This commit is contained in:
parent
a62b4a26ef
commit
fbfdd3e003
@ -1,7 +1,6 @@
|
|||||||
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
||||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||||
import type { ParameterStrength } from 'features/parameters/types/parameterSchemas';
|
|
||||||
import { isEqual, pick } from 'lodash-es';
|
import { isEqual, pick } from 'lodash-es';
|
||||||
import type { Invocation } from 'services/api/types';
|
import type { Invocation } from 'services/api/types';
|
||||||
|
|
||||||
@ -10,14 +9,13 @@ export const addImageToImage = async (
|
|||||||
manager: KonvaNodeManager,
|
manager: KonvaNodeManager,
|
||||||
l2i: Invocation<'l2i'>,
|
l2i: Invocation<'l2i'>,
|
||||||
denoise: Invocation<'denoise_latents'>,
|
denoise: Invocation<'denoise_latents'>,
|
||||||
vaeSource: Invocation<'main_model_loader' | 'seamless' | 'vae_loader'>,
|
vaeSource: Invocation<'main_model_loader' | 'sdxl_model_loader' | 'seamless' | 'vae_loader'>,
|
||||||
imageOutput: Invocation<'canvas_paste_back' | 'img_nsfw' | 'img_resize' | 'img_watermark' | 'l2i'>,
|
|
||||||
originalSize: Dimensions,
|
originalSize: Dimensions,
|
||||||
scaledSize: Dimensions,
|
scaledSize: Dimensions,
|
||||||
bbox: CanvasV2State['bbox'],
|
bbox: CanvasV2State['bbox'],
|
||||||
strength: ParameterStrength
|
denoising_start: number
|
||||||
): Promise<Invocation<'img_resize' | 'l2i'>> => {
|
): Promise<Invocation<'img_resize' | 'l2i'>> => {
|
||||||
denoise.denoising_start = 1 - strength;
|
denoise.denoising_start = denoising_start;
|
||||||
|
|
||||||
const cropBbox = pick(bbox, ['x', 'y', 'width', 'height']);
|
const cropBbox = pick(bbox, ['x', 'y', 'width', 'height']);
|
||||||
const initialImage = await manager.util.getImageSourceImage({
|
const initialImage = await manager.util.getImageSourceImage({
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager';
|
||||||
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
||||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||||
import type { ParameterPrecision, ParameterStrength } from 'features/parameters/types/parameterSchemas';
|
import type { ParameterPrecision } from 'features/parameters/types/parameterSchemas';
|
||||||
import { isEqual, pick } from 'lodash-es';
|
import { isEqual, pick } from 'lodash-es';
|
||||||
import type { Invocation } from 'services/api/types';
|
import type { Invocation } from 'services/api/types';
|
||||||
|
|
||||||
@ -10,16 +10,16 @@ export const addInpaint = async (
|
|||||||
manager: KonvaNodeManager,
|
manager: KonvaNodeManager,
|
||||||
l2i: Invocation<'l2i'>,
|
l2i: Invocation<'l2i'>,
|
||||||
denoise: Invocation<'denoise_latents'>,
|
denoise: Invocation<'denoise_latents'>,
|
||||||
vaeSource: Invocation<'main_model_loader' | 'seamless' | 'vae_loader'>,
|
vaeSource: Invocation<'main_model_loader' | 'sdxl_model_loader' | 'seamless' | 'vae_loader'>,
|
||||||
modelLoader: Invocation<'main_model_loader'>,
|
modelLoader: Invocation<'main_model_loader' | 'sdxl_model_loader'>,
|
||||||
originalSize: Dimensions,
|
originalSize: Dimensions,
|
||||||
scaledSize: Dimensions,
|
scaledSize: Dimensions,
|
||||||
bbox: CanvasV2State['bbox'],
|
bbox: CanvasV2State['bbox'],
|
||||||
compositing: CanvasV2State['compositing'],
|
compositing: CanvasV2State['compositing'],
|
||||||
strength: ParameterStrength,
|
denoising_start: number,
|
||||||
vaePrecision: ParameterPrecision
|
vaePrecision: ParameterPrecision
|
||||||
): Promise<Invocation<'canvas_paste_back'>> => {
|
): Promise<Invocation<'canvas_paste_back'>> => {
|
||||||
denoise.denoising_start = 1 - strength;
|
denoise.denoising_start = denoising_start;
|
||||||
|
|
||||||
const cropBbox = pick(bbox, ['x', 'y', 'width', 'height']);
|
const cropBbox = pick(bbox, ['x', 'y', 'width', 'height']);
|
||||||
const initialImage = await manager.util.getImageSourceImage({
|
const initialImage = await manager.util.getImageSourceImage({
|
||||||
@ -121,7 +121,6 @@ export const addInpaint = async (
|
|||||||
type: 'canvas_paste_back',
|
type: 'canvas_paste_back',
|
||||||
mask_blur: compositing.maskBlur,
|
mask_blur: compositing.maskBlur,
|
||||||
source_image: { image_name: initialImage.image_name },
|
source_image: { image_name: initialImage.image_name },
|
||||||
mask: { image_name: maskImage.image_name },
|
|
||||||
});
|
});
|
||||||
g.addEdge(alphaToMask, 'image', createGradientMask, 'mask');
|
g.addEdge(alphaToMask, 'image', createGradientMask, 'mask');
|
||||||
g.addEdge(i2l, 'latents', denoise, 'latents');
|
g.addEdge(i2l, 'latents', denoise, 'latents');
|
||||||
@ -129,6 +128,8 @@ export const addInpaint = async (
|
|||||||
g.addEdge(vaeSource, 'vae', createGradientMask, 'vae');
|
g.addEdge(vaeSource, 'vae', createGradientMask, 'vae');
|
||||||
g.addEdge(modelLoader, 'unet', createGradientMask, 'unet');
|
g.addEdge(modelLoader, 'unet', createGradientMask, 'unet');
|
||||||
g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask');
|
g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask');
|
||||||
|
g.addEdge(createGradientMask, 'expanded_mask_area', canvasPasteBack, 'mask');
|
||||||
|
|
||||||
g.addEdge(l2i, 'image', canvasPasteBack, 'target_image');
|
g.addEdge(l2i, 'image', canvasPasteBack, 'target_image');
|
||||||
|
|
||||||
return canvasPasteBack;
|
return canvasPasteBack;
|
||||||
|
@ -10,21 +10,13 @@ import type { Invocation } from 'services/api/types';
|
|||||||
*/
|
*/
|
||||||
export const addNSFWChecker = (
|
export const addNSFWChecker = (
|
||||||
g: Graph,
|
g: Graph,
|
||||||
imageOutput: Invocation<'l2i'> | Invocation<'img_nsfw'> | Invocation<'img_watermark'> | Invocation<'img_resize'>
|
imageOutput: Invocation<'l2i' | 'img_nsfw' | 'img_watermark' | 'img_resize' | 'canvas_paste_back'>
|
||||||
): Invocation<'img_nsfw'> => {
|
): Invocation<'img_nsfw'> => {
|
||||||
const nsfw = g.addNode({
|
const nsfw = g.addNode({
|
||||||
id: NSFW_CHECKER,
|
id: NSFW_CHECKER,
|
||||||
type: 'img_nsfw',
|
type: 'img_nsfw',
|
||||||
is_intermediate: imageOutput.is_intermediate,
|
|
||||||
board: imageOutput.board,
|
|
||||||
use_cache: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// The NSFW checker node is the new image output - make the previous one intermediate
|
|
||||||
imageOutput.is_intermediate = true;
|
|
||||||
imageOutput.use_cache = true;
|
|
||||||
imageOutput.board = undefined;
|
|
||||||
|
|
||||||
g.addEdge(imageOutput, 'image', nsfw, 'image');
|
g.addEdge(imageOutput, 'image', nsfw, 'image');
|
||||||
|
|
||||||
return nsfw;
|
return nsfw;
|
||||||
|
@ -2,7 +2,7 @@ import type { KonvaNodeManager } from 'features/controlLayers/konva/nodeManager'
|
|||||||
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
||||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||||
import { getInfill } from 'features/nodes/util/graph/graphBuilderUtils';
|
import { getInfill } from 'features/nodes/util/graph/graphBuilderUtils';
|
||||||
import type { ParameterPrecision, ParameterStrength } from 'features/parameters/types/parameterSchemas';
|
import type { ParameterPrecision } from 'features/parameters/types/parameterSchemas';
|
||||||
import { isEqual, pick } from 'lodash-es';
|
import { isEqual, pick } from 'lodash-es';
|
||||||
import type { Invocation } from 'services/api/types';
|
import type { Invocation } from 'services/api/types';
|
||||||
|
|
||||||
@ -11,17 +11,15 @@ export const addOutpaint = async (
|
|||||||
manager: KonvaNodeManager,
|
manager: KonvaNodeManager,
|
||||||
l2i: Invocation<'l2i'>,
|
l2i: Invocation<'l2i'>,
|
||||||
denoise: Invocation<'denoise_latents'>,
|
denoise: Invocation<'denoise_latents'>,
|
||||||
vaeSource: Invocation<'main_model_loader' | 'seamless' | 'vae_loader'>,
|
vaeSource: Invocation<'main_model_loader' | 'sdxl_model_loader' | 'seamless' | 'vae_loader'>,
|
||||||
modelLoader: Invocation<'main_model_loader'>,
|
modelLoader: Invocation<'main_model_loader' | 'sdxl_model_loader'>,
|
||||||
originalSize: Dimensions,
|
originalSize: Dimensions,
|
||||||
scaledSize: Dimensions,
|
scaledSize: Dimensions,
|
||||||
bbox: CanvasV2State['bbox'],
|
bbox: CanvasV2State['bbox'],
|
||||||
compositing: CanvasV2State['compositing'],
|
compositing: CanvasV2State['compositing'],
|
||||||
strength: ParameterStrength,
|
denoising_start: number,
|
||||||
vaePrecision: ParameterPrecision
|
vaePrecision: ParameterPrecision
|
||||||
): Promise<Invocation<'canvas_paste_back'>> => {
|
): Promise<Invocation<'canvas_paste_back'>> => {
|
||||||
denoise.denoising_start = 1 - strength;
|
|
||||||
|
|
||||||
const cropBbox = pick(bbox, ['x', 'y', 'width', 'height']);
|
const cropBbox = pick(bbox, ['x', 'y', 'width', 'height']);
|
||||||
const initialImage = await manager.util.getImageSourceImage({
|
const initialImage = await manager.util.getImageSourceImage({
|
||||||
bbox: cropBbox,
|
bbox: cropBbox,
|
||||||
@ -56,21 +54,21 @@ export const addOutpaint = async (
|
|||||||
g.addEdge(initialImageAlphaToMask, 'image', maskCombine, 'mask2');
|
g.addEdge(initialImageAlphaToMask, 'image', maskCombine, 'mask2');
|
||||||
|
|
||||||
// Resize the combined and initial image to the scaled size
|
// Resize the combined and initial image to the scaled size
|
||||||
const resizeMaskToScaledSize = g.addNode({
|
const resizeInputMaskToScaledSize = g.addNode({
|
||||||
id: 'resize_mask_to_scaled_size',
|
id: 'resize_mask_to_scaled_size',
|
||||||
type: 'img_resize',
|
type: 'img_resize',
|
||||||
...scaledSize,
|
...scaledSize,
|
||||||
});
|
});
|
||||||
g.addEdge(maskCombine, 'image', resizeMaskToScaledSize, 'image');
|
g.addEdge(maskCombine, 'image', resizeInputMaskToScaledSize, 'image');
|
||||||
|
|
||||||
// Resize the initial image to the scaled size and infill
|
// Resize the initial image to the scaled size and infill
|
||||||
const resizeImageToScaledSize = g.addNode({
|
const resizeInputImageToScaledSize = g.addNode({
|
||||||
id: 'resize_image_to_scaled_size',
|
id: 'resize_image_to_scaled_size',
|
||||||
type: 'img_resize',
|
type: 'img_resize',
|
||||||
image: { image_name: initialImage.image_name },
|
image: { image_name: initialImage.image_name },
|
||||||
...scaledSize,
|
...scaledSize,
|
||||||
});
|
});
|
||||||
g.addEdge(resizeImageToScaledSize, 'image', infill, 'image');
|
g.addEdge(resizeInputImageToScaledSize, 'image', infill, 'image');
|
||||||
|
|
||||||
// Create the gradient denoising mask from the combined mask
|
// Create the gradient denoising mask from the combined mask
|
||||||
const createGradientMask = g.addNode({
|
const createGradientMask = g.addNode({
|
||||||
@ -82,7 +80,7 @@ export const addOutpaint = async (
|
|||||||
fp32: vaePrecision === 'fp32',
|
fp32: vaePrecision === 'fp32',
|
||||||
});
|
});
|
||||||
g.addEdge(infill, 'image', createGradientMask, 'image');
|
g.addEdge(infill, 'image', createGradientMask, 'image');
|
||||||
g.addEdge(maskCombine, 'image', createGradientMask, 'mask');
|
g.addEdge(resizeInputMaskToScaledSize, 'image', createGradientMask, 'mask');
|
||||||
g.addEdge(vaeSource, 'vae', createGradientMask, 'vae');
|
g.addEdge(vaeSource, 'vae', createGradientMask, 'vae');
|
||||||
g.addEdge(modelLoader, 'unet', createGradientMask, 'unet');
|
g.addEdge(modelLoader, 'unet', createGradientMask, 'unet');
|
||||||
g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask');
|
g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask');
|
||||||
@ -94,12 +92,12 @@ export const addOutpaint = async (
|
|||||||
g.addEdge(i2l, 'latents', denoise, 'latents');
|
g.addEdge(i2l, 'latents', denoise, 'latents');
|
||||||
|
|
||||||
// Resize the output image back to the original size
|
// Resize the output image back to the original size
|
||||||
const resizeImageToOriginalSize = g.addNode({
|
const resizeOutputImageToOriginalSize = g.addNode({
|
||||||
id: 'resize_image_to_original_size',
|
id: 'resize_image_to_original_size',
|
||||||
type: 'img_resize',
|
type: 'img_resize',
|
||||||
...originalSize,
|
...originalSize,
|
||||||
});
|
});
|
||||||
const resizeMaskToOriginalSize = g.addNode({
|
const resizeOutputMaskToOriginalSize = g.addNode({
|
||||||
id: 'resize_mask_to_original_size',
|
id: 'resize_mask_to_original_size',
|
||||||
type: 'img_resize',
|
type: 'img_resize',
|
||||||
...originalSize,
|
...originalSize,
|
||||||
@ -114,12 +112,12 @@ export const addOutpaint = async (
|
|||||||
// Resize initial image and mask to scaled size, feed into to gradient mask
|
// Resize initial image and mask to scaled size, feed into to gradient mask
|
||||||
|
|
||||||
// After denoising, resize the image and mask back to original size
|
// After denoising, resize the image and mask back to original size
|
||||||
g.addEdge(l2i, 'image', resizeImageToOriginalSize, 'image');
|
g.addEdge(l2i, 'image', resizeOutputImageToOriginalSize, 'image');
|
||||||
g.addEdge(createGradientMask, 'expanded_mask_area', resizeMaskToOriginalSize, 'image');
|
g.addEdge(createGradientMask, 'expanded_mask_area', resizeOutputMaskToOriginalSize, 'image');
|
||||||
|
|
||||||
// Finally, paste the generated masked image back onto the original image
|
// Finally, paste the generated masked image back onto the original image
|
||||||
g.addEdge(resizeImageToOriginalSize, 'image', canvasPasteBack, 'target_image');
|
g.addEdge(resizeOutputImageToOriginalSize, 'image', canvasPasteBack, 'target_image');
|
||||||
g.addEdge(resizeMaskToOriginalSize, 'image', canvasPasteBack, 'mask');
|
g.addEdge(resizeOutputMaskToOriginalSize, 'image', canvasPasteBack, 'mask');
|
||||||
|
|
||||||
return canvasPasteBack;
|
return canvasPasteBack;
|
||||||
} else {
|
} else {
|
||||||
@ -154,7 +152,6 @@ export const addOutpaint = async (
|
|||||||
id: 'canvas_paste_back',
|
id: 'canvas_paste_back',
|
||||||
type: 'canvas_paste_back',
|
type: 'canvas_paste_back',
|
||||||
mask_blur: compositing.maskBlur,
|
mask_blur: compositing.maskBlur,
|
||||||
mask: { image_name: maskImage.image_name },
|
|
||||||
});
|
});
|
||||||
g.addEdge(maskAlphaToMask, 'image', maskCombine, 'mask1');
|
g.addEdge(maskAlphaToMask, 'image', maskCombine, 'mask1');
|
||||||
g.addEdge(initialImageAlphaToMask, 'image', maskCombine, 'mask2');
|
g.addEdge(initialImageAlphaToMask, 'image', maskCombine, 'mask2');
|
||||||
@ -165,6 +162,7 @@ export const addOutpaint = async (
|
|||||||
g.addEdge(vaeSource, 'vae', createGradientMask, 'vae');
|
g.addEdge(vaeSource, 'vae', createGradientMask, 'vae');
|
||||||
g.addEdge(modelLoader, 'unet', createGradientMask, 'unet');
|
g.addEdge(modelLoader, 'unet', createGradientMask, 'unet');
|
||||||
g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask');
|
g.addEdge(createGradientMask, 'denoise_mask', denoise, 'denoise_mask');
|
||||||
|
g.addEdge(createGradientMask, 'expanded_mask_area', canvasPasteBack, 'mask');
|
||||||
g.addEdge(infill, 'image', canvasPasteBack, 'source_image');
|
g.addEdge(infill, 'image', canvasPasteBack, 'source_image');
|
||||||
g.addEdge(l2i, 'image', canvasPasteBack, 'target_image');
|
g.addEdge(l2i, 'image', canvasPasteBack, 'target_image');
|
||||||
|
|
||||||
|
@ -10,21 +10,13 @@ import type { Invocation } from 'services/api/types';
|
|||||||
*/
|
*/
|
||||||
export const addWatermarker = (
|
export const addWatermarker = (
|
||||||
g: Graph,
|
g: Graph,
|
||||||
imageOutput: Invocation<'l2i'> | Invocation<'img_nsfw'> | Invocation<'img_watermark'> | Invocation<'img_resize'>
|
imageOutput: Invocation<'l2i' | 'img_nsfw' | 'img_watermark' | 'img_resize' | 'canvas_paste_back'>
|
||||||
): Invocation<'img_watermark'> => {
|
): Invocation<'img_watermark'> => {
|
||||||
const watermark = g.addNode({
|
const watermark = g.addNode({
|
||||||
id: WATERMARKER,
|
id: WATERMARKER,
|
||||||
type: 'img_watermark',
|
type: 'img_watermark',
|
||||||
is_intermediate: imageOutput.is_intermediate,
|
|
||||||
board: imageOutput.board,
|
|
||||||
use_cache: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// The watermarker node is the new image output - make the previous one intermediate
|
|
||||||
imageOutput.is_intermediate = true;
|
|
||||||
imageOutput.use_cache = true;
|
|
||||||
imageOutput.board = undefined;
|
|
||||||
|
|
||||||
g.addEdge(imageOutput, 'image', watermark, 'image');
|
g.addEdge(imageOutput, 'image', watermark, 'image');
|
||||||
|
|
||||||
return watermark;
|
return watermark;
|
||||||
|
@ -157,7 +157,9 @@ export const buildSD1Graph = async (state: RootState, manager: KonvaNodeManager)
|
|||||||
addLoRAs(state, g, denoise, modelLoader, seamless, clipSkip, posCond, negCond);
|
addLoRAs(state, g, denoise, modelLoader, seamless, clipSkip, posCond, negCond);
|
||||||
|
|
||||||
// We might get the VAE from the main model, custom VAE, or seamless node.
|
// We might get the VAE from the main model, custom VAE, or seamless node.
|
||||||
const vaeSource: Invocation<'main_model_loader' | 'seamless' | 'vae_loader'> = seamless ?? vaeLoader ?? modelLoader;
|
const vaeSource: Invocation<
|
||||||
|
'main_model_loader' | 'sdxl_model_loader' | 'sdxl_model_loader' | 'seamless' | 'vae_loader'
|
||||||
|
> = seamless ?? vaeLoader ?? modelLoader;
|
||||||
g.addEdge(vaeSource, 'vae', l2i, 'vae');
|
g.addEdge(vaeSource, 'vae', l2i, 'vae');
|
||||||
|
|
||||||
if (generationMode === 'txt2img') {
|
if (generationMode === 'txt2img') {
|
||||||
@ -169,11 +171,10 @@ export const buildSD1Graph = async (state: RootState, manager: KonvaNodeManager)
|
|||||||
l2i,
|
l2i,
|
||||||
denoise,
|
denoise,
|
||||||
vaeSource,
|
vaeSource,
|
||||||
imageOutput,
|
|
||||||
originalSize,
|
originalSize,
|
||||||
scaledSize,
|
scaledSize,
|
||||||
bbox,
|
bbox,
|
||||||
params.img2imgStrength
|
1 - params.img2imgStrength
|
||||||
);
|
);
|
||||||
} else if (generationMode === 'inpaint') {
|
} else if (generationMode === 'inpaint') {
|
||||||
const { compositing } = state.canvasV2;
|
const { compositing } = state.canvasV2;
|
||||||
@ -188,7 +189,7 @@ export const buildSD1Graph = async (state: RootState, manager: KonvaNodeManager)
|
|||||||
scaledSize,
|
scaledSize,
|
||||||
bbox,
|
bbox,
|
||||||
compositing,
|
compositing,
|
||||||
params.img2imgStrength,
|
1 - params.img2imgStrength,
|
||||||
vaePrecision
|
vaePrecision
|
||||||
);
|
);
|
||||||
} else if (generationMode === 'outpaint') {
|
} else if (generationMode === 'outpaint') {
|
||||||
@ -204,7 +205,7 @@ export const buildSD1Graph = async (state: RootState, manager: KonvaNodeManager)
|
|||||||
scaledSize,
|
scaledSize,
|
||||||
bbox,
|
bbox,
|
||||||
compositing,
|
compositing,
|
||||||
params.img2imgStrength,
|
1 - params.img2imgStrength,
|
||||||
vaePrecision
|
vaePrecision
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,18 @@ import {
|
|||||||
VAE_LOADER,
|
VAE_LOADER,
|
||||||
} from 'features/nodes/util/graph/constants';
|
} from 'features/nodes/util/graph/constants';
|
||||||
import { addControlAdapters } from 'features/nodes/util/graph/generation/addControlAdapters';
|
import { addControlAdapters } from 'features/nodes/util/graph/generation/addControlAdapters';
|
||||||
|
import { addImageToImage } from 'features/nodes/util/graph/generation/addImageToImage';
|
||||||
|
import { addInpaint } from 'features/nodes/util/graph/generation/addInpaint';
|
||||||
import { addIPAdapters } from 'features/nodes/util/graph/generation/addIPAdapters';
|
import { addIPAdapters } from 'features/nodes/util/graph/generation/addIPAdapters';
|
||||||
import { addNSFWChecker } from 'features/nodes/util/graph/generation/addNSFWChecker';
|
import { addNSFWChecker } from 'features/nodes/util/graph/generation/addNSFWChecker';
|
||||||
|
import { addOutpaint } from 'features/nodes/util/graph/generation/addOutpaint';
|
||||||
import { addSDXLLoRAs } from 'features/nodes/util/graph/generation/addSDXLLoRAs';
|
import { addSDXLLoRAs } from 'features/nodes/util/graph/generation/addSDXLLoRAs';
|
||||||
import { addSDXLRefiner } from 'features/nodes/util/graph/generation/addSDXLRefiner';
|
import { addSDXLRefiner } from 'features/nodes/util/graph/generation/addSDXLRefiner';
|
||||||
import { addSeamless } from 'features/nodes/util/graph/generation/addSeamless';
|
import { addSeamless } from 'features/nodes/util/graph/generation/addSeamless';
|
||||||
|
import { addTextToImage } from 'features/nodes/util/graph/generation/addTextToImage';
|
||||||
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
|
import { addWatermarker } from 'features/nodes/util/graph/generation/addWatermarker';
|
||||||
import { Graph } from 'features/nodes/util/graph/generation/Graph';
|
import { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||||
import { getBoardField, getSDXLStylePrompts, getSizes } from 'features/nodes/util/graph/graphBuilderUtils';
|
import { getBoardField, getSDXLStylePrompts, getSizes } from 'features/nodes/util/graph/graphBuilderUtils';
|
||||||
import { isEqual, pick } from 'lodash-es';
|
|
||||||
import type { Invocation, NonNullableGraph } from 'services/api/types';
|
import type { Invocation, NonNullableGraph } from 'services/api/types';
|
||||||
import { isNonRefinerMainModelConfig } from 'services/api/types';
|
import { isNonRefinerMainModelConfig } from 'services/api/types';
|
||||||
import { assert } from 'tsafe';
|
import { assert } from 'tsafe';
|
||||||
@ -48,7 +51,6 @@ export const buildSDXLGraph = async (state: RootState, manager: KonvaNodeManager
|
|||||||
negativePrompt,
|
negativePrompt,
|
||||||
refinerModel,
|
refinerModel,
|
||||||
refinerStart,
|
refinerStart,
|
||||||
img2imgStrength,
|
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
assert(model, 'No model found in state');
|
assert(model, 'No model found in state');
|
||||||
@ -105,10 +107,6 @@ export const buildSDXLGraph = async (state: RootState, manager: KonvaNodeManager
|
|||||||
type: 'l2i',
|
type: 'l2i',
|
||||||
id: LATENTS_TO_IMAGE,
|
id: LATENTS_TO_IMAGE,
|
||||||
fp32: vaePrecision === 'fp32',
|
fp32: vaePrecision === 'fp32',
|
||||||
board: getBoardField(state),
|
|
||||||
// This is the terminal node and must always save to gallery.
|
|
||||||
is_intermediate: false,
|
|
||||||
use_cache: false,
|
|
||||||
});
|
});
|
||||||
const vaeLoader =
|
const vaeLoader =
|
||||||
vae?.base === model.base
|
vae?.base === model.base
|
||||||
@ -119,8 +117,7 @@ export const buildSDXLGraph = async (state: RootState, manager: KonvaNodeManager
|
|||||||
})
|
})
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
let imageOutput: Invocation<'l2i'> | Invocation<'img_nsfw'> | Invocation<'img_watermark'> | Invocation<'img_resize'> =
|
let imageOutput: Invocation<'l2i' | 'img_nsfw' | 'img_watermark' | 'img_resize' | 'canvas_paste_back'> = l2i;
|
||||||
l2i;
|
|
||||||
|
|
||||||
g.addEdge(modelLoader, 'unet', denoise, 'unet');
|
g.addEdge(modelLoader, 'unet', denoise, 'unet');
|
||||||
g.addEdge(modelLoader, 'clip', posCond, 'clip');
|
g.addEdge(modelLoader, 'clip', posCond, 'clip');
|
||||||
@ -169,52 +166,51 @@ export const buildSDXLGraph = async (state: RootState, manager: KonvaNodeManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (generationMode === 'txt2img') {
|
if (generationMode === 'txt2img') {
|
||||||
if (!isEqual(scaledSize, originalSize)) {
|
imageOutput = addTextToImage(g, l2i, originalSize, scaledSize);
|
||||||
// We are using scaled bbox and need to resize the output image back to the original size.
|
|
||||||
imageOutput = g.addNode({
|
|
||||||
id: 'img_resize',
|
|
||||||
type: 'img_resize',
|
|
||||||
...originalSize,
|
|
||||||
is_intermediate: false,
|
|
||||||
use_cache: false,
|
|
||||||
});
|
|
||||||
g.addEdge(l2i, 'image', imageOutput, 'image');
|
|
||||||
}
|
|
||||||
} else if (generationMode === 'img2img') {
|
} else if (generationMode === 'img2img') {
|
||||||
denoise.denoising_start = refinerModel ? Math.min(refinerStart, 1 - img2imgStrength) : 1 - img2imgStrength;
|
imageOutput = await addImageToImage(
|
||||||
|
g,
|
||||||
const { image_name } = await manager.util.getImageSourceImage({
|
manager,
|
||||||
bbox: pick(bbox, ['x', 'y', 'width', 'height']),
|
l2i,
|
||||||
preview: true,
|
denoise,
|
||||||
});
|
vaeSource,
|
||||||
|
originalSize,
|
||||||
if (!isEqual(scaledSize, originalSize)) {
|
scaledSize,
|
||||||
// We are using scaled bbox and need to resize the output image back to the original size.
|
bbox,
|
||||||
const initialImageResize = g.addNode({
|
refinerModel ? Math.min(refinerStart, 1 - params.img2imgStrength) : 1 - params.img2imgStrength
|
||||||
id: 'initial_image_resize',
|
);
|
||||||
type: 'img_resize',
|
} else if (generationMode === 'inpaint') {
|
||||||
...scaledSize,
|
const { compositing } = state.canvasV2;
|
||||||
image: { image_name },
|
imageOutput = await addInpaint(
|
||||||
});
|
g,
|
||||||
const i2l = g.addNode({ id: 'i2l', type: 'i2l' });
|
manager,
|
||||||
|
l2i,
|
||||||
g.addEdge(vaeSource, 'vae', i2l, 'vae');
|
denoise,
|
||||||
g.addEdge(initialImageResize, 'image', i2l, 'image');
|
vaeSource,
|
||||||
g.addEdge(i2l, 'latents', denoise, 'latents');
|
modelLoader,
|
||||||
|
originalSize,
|
||||||
imageOutput = g.addNode({
|
scaledSize,
|
||||||
id: 'img_resize',
|
bbox,
|
||||||
type: 'img_resize',
|
compositing,
|
||||||
...originalSize,
|
refinerModel ? Math.min(refinerStart, 1 - params.img2imgStrength) : 1 - params.img2imgStrength,
|
||||||
is_intermediate: false,
|
vaePrecision
|
||||||
use_cache: false,
|
);
|
||||||
});
|
} else if (generationMode === 'outpaint') {
|
||||||
g.addEdge(l2i, 'image', imageOutput, 'image');
|
const { compositing } = state.canvasV2;
|
||||||
} else {
|
imageOutput = await addOutpaint(
|
||||||
const i2l = g.addNode({ id: 'i2l', type: 'i2l', image: { image_name } });
|
g,
|
||||||
g.addEdge(vaeSource, 'vae', i2l, 'vae');
|
manager,
|
||||||
g.addEdge(i2l, 'latents', denoise, 'latents');
|
l2i,
|
||||||
}
|
denoise,
|
||||||
|
vaeSource,
|
||||||
|
modelLoader,
|
||||||
|
originalSize,
|
||||||
|
scaledSize,
|
||||||
|
bbox,
|
||||||
|
compositing,
|
||||||
|
refinerModel ? Math.min(refinerStart, 1 - params.img2imgStrength) : 1 - params.img2imgStrength,
|
||||||
|
vaePrecision
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const _addedCAs = addControlAdapters(state.canvasV2.controlAdapters.entities, g, denoise, modelConfig.base);
|
const _addedCAs = addControlAdapters(state.canvasV2.controlAdapters.entities, g, denoise, modelConfig.base);
|
||||||
@ -241,6 +237,11 @@ export const buildSDXLGraph = async (state: RootState, manager: KonvaNodeManager
|
|||||||
imageOutput = addWatermarker(g, imageOutput);
|
imageOutput = addWatermarker(g, imageOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is the terminal node and must always save to gallery.
|
||||||
|
imageOutput.is_intermediate = false;
|
||||||
|
imageOutput.use_cache = false;
|
||||||
|
imageOutput.board = getBoardField(state);
|
||||||
|
|
||||||
g.setMetadataReceivingNode(imageOutput);
|
g.setMetadataReceivingNode(imageOutput);
|
||||||
return g.getGraph();
|
return g.getGraph();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user