240628 - ComfyUI Area Stuff
Spis Treści #
- Area Composition
- Co próbujemy zrobić?
- Rozwiązanie 1: Area Conditioning
- Wyjaśnienie
- Analiza: lewa strona rysunku
- Analiza: prawa strona rysunku
- Oki, budujemy całość
- Pierwsza iteracja (Conditioning Set Area)
- Druga iteracja (debugowanie przez ConditioningSetAreaStrength)
- Latent Correction
- Czemu tak?
- Jak to zrobić

1. Area Composition #
1.1. Co próbujemy zrobić? #
Wyobraźmy sobie typową sytuację tragiczną. Chcemy mieć:
- po LEWEJ stronie żółwia i kota
- po PRAWEJ stronie jest podejrzany grzyb
- żółw i kot patrzą na grzyb
- jesteśmy w stylu neo-noir + neony.
A wyszło jak zwykle:

- zrobił nam się żółwiogrzyb (co całkiem pasuje patrząc na autora)
- "lewo" i "prawo" są względne. Tzn, zupełnie nie złapał kompozycji
Naszym celem jest zrobienie czegoś takiego:
- żółw i kot są po LEWEJ stronie rysunku
- żółw i kot PATRZĄ na grzyb
Na tym samym seedzie.
1.2. Rozwiązanie 1: Area Conditioning #
1.2.1. Wyjaśnienie #
Rozwiązaniem są węzły pozwalające na robienie conditioning danego obszaru.
Wpierw określmy co chcemy osiągnąć.
- PO LEWEJ STRONIE chcemy mieć kota siedzącego na żółwiu
- PO PRAWEJ STRONIE chcemy mieć grzyb typu 'suspicious majestic veiled mushroom ' (cokolwiek to jest)
I chcemy, by kot patrzył na grzyb.
Czyli chcemy wygenerować wynik będący superpozycją LEWEJ i PRAWEJ idei.
1.2.2. Analiza: lewa strona rysunku #
Po lewej stronie chcemy mieć kota siedzącego na żółwiu w konkretnym stylu.
- prompt pozytywny:
cat sits on top of a turtle, neo-noir, neons - prompt negatywny:
text, watermark, copyright, author, blurry, distorted, cropped, merged animal, chimera, bad animal
Czyli mikro-pipeline (za sekundę wyjaśnię):

- Latent Image ma szerokość 512 (bo cały rysunek ma szerokość 1024 a to ma być pół)
- Węzeł
Conditioning Set Areatu niewiele robi; docelowo on ma ograniczyć siłę tego prompta do połowy rysunku- ale jest tu by zapewnić, że to jest output tego prompta
Jak widzicie, jak go wyłączę, nic się nie dzieje:

Ok, czas na prawą stronę.
1.2.3. Analiza: prawa strona rysunku #
Po prawej stronie chcemy mieć podejrzany grzyb.
- prompt pozytywny:
cat sits on top of a turtle, neo-noir, neons - prompt negatywny:
text, watermark, copyright, author, blurry, distorted, cropped, merged animal, chimera, bad animal- (ten sam, ale jakbym się BARDZO starał to mogę zrobić inny)

- Latent Image ma szerokość 512
1.2.4. Oki, budujemy całość #
1.2.4.1. Pierwsza iteracja (Conditioning Set Area)
Wiemy jak wygląda to co chcemy po LEWEJ stronie rysunku, wiemy jak wygląda to co chcemy po PRAWEJ. Teraz kwestia połączenia tego w całość.
To robiliśmy używając węzła Embeddings Combine (dodawanie szumów).
Więc ostateczny pipeline:

Nie jest idealnie, ale jest znacznie lepiej. A teraz przejdźmy przez ten pipeline, a zwłaszcza conditionujące węzły (niebieskie i jasnoniebieskie):
- NAJPIERW Niebieski Conditioning Set Area pobiera Conditioning z CLIP (czyli embeddingi) i ogranicza je przestrzennie:
- "cat on top of turtle" idzie w x: [0, 1024] (czyli na cały rysunek)
- "suspicious mushroom" idzie w x: [512, 1024] (czyli po prawej)
- POTEM mając powyższe, łączymy je do kupy przez łączenie szumów (Conditioning Combine). To pierwsze jasnoniebieskie.
- POTEM nakładamy na to opis całej sceny
- prompt:
cat sits on a turtle on the left and they look at the mushroom on the right
- prompt:
- POTEM robimy jeszcze raz Conditioning Combine, czyli łączymy całość sceny z wynikiem tego co było wcześniej
1.2.4.2. Druga iteracja (debugowanie przez ConditioningSetAreaStrength)
Oki, czy od razu widzicie, czemu to nie zadziałało tak jak chciałem?
- Pierwszy Area Combine dotyczył całej szerokości sceny
- Drugi Area Combine dotyczył prawej strony rysunku
Jeśli zmienię układ w prosty sposób (width: 1024 -> width: 512), dostanę zabawną, malformowaną scenę:

Dostałem to, czego CHCĘ z perspektywy kompozycji, ale nie wyszło to co CHCIAŁEM patrząc na perfekcję żółwia i kota.
Dobrze. Przejdźmy do kolejnego istotnego węzła - ConditioningSetAreaStrength (kolor czarny).

Ten węzeł robi wagi dla conditioningu, który z niego wychodzi. Jako, że jest ustawione na 1 (100%), nic nie robi.
A teraz ustawmy na 0% - jakie odpowiedzi dostajemy?

Oki - czyli wyraźnie dostajemy "kotożółwia" a nie "kota siedzącego na żółwiu". Widać, na czym musimy popracować.
Po pewnej modyfikacji prompta udało mi się "zejść" z kotożółwia.

Tu teoretycznie można się jeszcze pobawić z innymi CombineAverage by dostać lepszą odpowiedź; w praktyce, jeśli mam się AŻ TAK bawić to lepszy będzie Inpainting tbh.
Teraz włączmy integrację z grzybami (jako, że do tego służy parametr STRENGTH to usuwam czarny węzeł i szukam takich wartości STRENGTH i takich promptów, by dostać mniej więcej to czego szukam; dodatkowo zrobiłem niewielki overlap między rysunkami):

Od razu lepiej. Teraz czas włączyć "kontroler sceny" (nie wiem jeszcze z jaką siłą wysłać oba conditioningi).

Lepiej. Mam ekstra kota po prawej stronie, ale z tym da się żyć ;-).
ZMIENIAM SAMPLER na Converging, czyli taki bardziej deterministyczny. I trochę pracuję nad promptem.

Jak widzicie w tym powyżej, WYRAŹNIE jest różnica między "ten fragment pochodzi z lewego a ten z prawego". Właśnie do tego służy siła conditioningu sceny. Spróbuję popracować z wagami przy tym nowym samplerze.
Popatrzcie na te dwa rysunki poniżej. Różnica niby nie jest duża, ale to zupełnie inne byty:

Moim zdaniem, rysunek z lewej strony lepiej odzwierciedla to, co chcemy. Przejdźmy więc do latent image correction. Tu nie ma nic więcej do zrobienia - naprawimy to dalej, w kolejnej iteracji :-).
2. Latent Correction #
2.1. Czemu tak? #
Typowa strategia za załączonym filmikiem - dobrze w pierwszym przebiegu zdefiniować scenę a potem w następnych przebiegach naprawić scenę i zrobić, by działała dobrze. To jest prostsze i daje lepsze efekty.
2.2. Jak to zrobić: #

- Dodajemy nowy KSampler. OUTPUT poprzedniego (LATENT) trafia jako input do nowego.
- Używamy ten sam model.
- Możemy użyć ten sam scheduler, CZĘSTO używa się inny seed (by nie przepalić obrazka)
- Możemy użyć ten sam prompt, można inny
Teraz - jako, że jest inny seed, on dąży do innego obrazka idealnego. Popatrzcie co się stanie jeśli ustawię DENOISE na 0.9 (czyli "lekko się zainspiruj poprzednimi pikselami"):

MÓJ ŻÓŁW ZANIKNĄŁ!!!
Za to jeśli podam poprzedni seed i denoise 0.9:

Obrazek jest naprawiony, ale CAŁKOWICIE przepalony. W związku z tym, odpalam inny seed i modyfikuję prompt. Zróbmy tak, by ten obrazek dobrze wyglądał.

Nadal łatwiej by się to robiło inpaintingiem by dodać (a po inpaintingu skorygować).
Ale jeśli zrobimy łańcuch (chain) KSamplerów, co jest naprawdę tanie (jeden model, zero lor itp) to możemy wygenerować na podstawie sceny serio godną odpowiedź, zwłaszcza, jeśli pobawimy się promptami. Po dodaniu aspektu horroru (oczywiście, nie byłbym sobą):
