Pixely jsou vektory

Jak lineární algebra, matematika vektorů a matic, stojí za nodem ColorMatrix, world position passem a deep compositingem v Nuke a proč z vás její znalost udělá rychlejšího a odvážnějšího compositora.

Compositing · Nuke · 13 min

Otevřete skript Nuke z jakéhokoli celovečerního filmu a najdete stovky nodů: grady, merge, masky, relighty, deep merge. Pod téměř každým z nich sedí jedna malá myšlenka z lineární algebry. Seznam čísel je **vektor** a mřížka čísel, **matice**, dokáže posunout každý vektor v obraze najednou. Barva pixelu je vektor. Pixel ve world position passu je také vektor, ale tentokrát je to bod ve 3D scéně. Deep pixel je celý seznam takových vektorů. Tento článek ukazuje, jak compositoři tu jedinou myšlenku používají: v nodu ColorMatrix ke změně sytosti, míchání kanálů a převodu barevných prostorů; na world position passu ke stavbě 3D masek, přidání světla a přechodu mezi prostorem kamery a světa; a v deep compositingu, kde každý pixel nese mnoho vzorků a soubory bobtnají. Každý obrázek je kreslen živě z jedné malé 3D místnosti renderované ve vašem prohlížeči, takže čísla, která vidíte, jsou čísla, která se používají.

Pixel je seznam čísel

V Nuke je pixel RGB obrazu troje čísla: červená, zelená a modrá. Lineární algebra nazývá takový seznam čísel vektorem a můžete ho nakreslit jako šipku. Začněte v černém rohu krychle, kde jsou všechna tři čísla nula, a cestujte podél červené, zelené a modré hrany o tolik, kolik říká každý kanál. Bílá je vzdálený roh, (1, 1, 1). Tmavě oranžová je krátká šipka nakloněná k červené. Nuke pracuje v 32bitové plovoucí čárce a lineárním světle, takže šipka smí krychli opustit: jasný odlesk může být (4,2, 3,8, 3,1) a hodnota může klesnout i pod nulu. Myslet na barvy jako na šipky je krok, který odemkne všechno ostatní, protože o posouvání šipek existuje celý obor matematiky.

Kanál nemusí držet barvu. 3D renderer může do červeného, zeleného a modrého slotu dalších passů, často zvaných AOV (arbitrary output variables), zapsat jiné vektory. Pro compository je nejužitečnější **world position pass**, obvykle zvaný P. Každý pixel ukládá souřadnice x, y a z ve 3D scéně, kde paprsek kamery narazil na povrch. Normálový pass, N, ukládá, kam ten povrch směřuje. Hloubkový pass ukládá, jak daleko byl. Pokud jste se kdy divili, jak může compositor nagradovat jen stěnu, aniž by nakreslil jediný roto tvar, P je odpověď: každý pixel zadní stěny v naší místnosti nese vlastní pozici stěny ve světě. V Nuke tyto passy přicházejí jako další vrstvy ve vícekanálovém EXR a Foundry poznamenává, že v NukeX je lze také vygenerovat ze záběru nodem DepthGenerator.

Mřížka 3×3, která posune každou barvu

Foundry popisuje nod ColorMatrix jednoduše: násobí hodnoty RGB každého pixelu maticí 3×3 a „výstupní hodnoty každého primárního barevného kanálu se počítají ze vstupních hodnot všech tří kanálů“. Čtěte matici po řádcích. Horní řádek říká, kolik ze staré červené, zelené a modré jde do nové červené. Druhý řádek staví novou zelenou a třetí novou modrou. To je celé násobení maticí: tři vážené součty provedené na každém pixelu najednou. Nod má také obvyklý vstup masky, posuvník mix a volbu nejdřív unpremultiplikovat alfou, takže ho můžete použít jako kterýkoli jiný barevný nod ve skriptu.

Protože každá barva je šipka, matice ve skutečnosti nemění barvy jednu po druhé. Ohýbá celou barevnou krychli najednou. **Jednotková matice**, s jedničkami na diagonále a nulami všude jinde, nechá krychli na pokoji. Čísla na diagonále natahují krychli podél jedné osy, což je přesně to, co dělá gain na jediném kanálu. Čísla mimo diagonálu naklánějí jednu osu k druhé, což míchá kanály. Rovné čáry zůstávají rovné a černá zůstává černá, a právě to pravidlo z ní dělá *lineární* operaci. Proto také matice nikdy nemůže přidat offset nebo křivku: na lift, gammu nebo měkký přechod stále potřebujete Grade nebo ColorLookup.

Matice, po které compositoři sahají nejčastěji, je sytost. Nejprve vezměte jas pixelu, vážený součet s váhami Rec.709: 0,2126 pro červenou, 0,7152 pro zelenou a 0,0722 pro modrou. Pak prolněte mezi tou šedou a původní barvou. Zapsáno jako matice, každý řádek začíná jako váhy jasu krát (1 − s) a s se přičte na diagonálu. Při s = 1 dostanete jednotkovou matici a nic se nezmění. Při s = 0 jsou všechny tři řádky stejné, takže každý kanál dostane stejnou hodnotu a obraz zešedne. Nad 1 se barvy odtlačí dál od sebe. Protože tři váhy dávají dohromady přesně jedna, neutrálně šedý pixel zůstává stejnou šedou, ať je s jakékoli, a proto matice sytosti nikdy neposune vaši šedou tabulku.

Míchání kanálů je místo, kde si čísla mimo diagonálu zaslouží své místo. Prohození červené a modré je matice s jedničkami ve dvou protilehlých rozích. Černobílý obraz vytvořený jen z červeného kanálu, jako červený filtr na černobílém filmu, je matice, jejíž tři řádky jsou všechny (1, 0, 0). Poslání červené do zelené, zelené do modré a modré do červené otočí každý odstín o třetinu barevného kruhu. Compositoři používají takové mixy k opravě záběrů, které přijdou s kanály ve špatném pořadí, k vytažení čistšího klíče z toho kanálu, který má největší kontrast, nebo ke stavbě jasové masky z vlastní směsi kanálů.

Práce, kterou ColorMatrix ve skutečné pipeline dělá nejčastěji, je **převod barevného prostoru**. Dva lineární barevné prostory, které se liší jen primárními barvami, jako lineární Rec.709 a ACEScg, spojuje přesně jedna matice 3×3. ACEScg má mnohem širší primární barvy, takže stejná oranžová je popsána jinými, méně extrémními čísly. Protlačte hodnoty Rec.709 převodní maticí a dostanete hodnoty ACEScg, které znamenají stejnou barvu. Zapomeňte na převod a zobrazte ta čísla, jako by byla stále Rec.709, a obraz vypadá vybledle, klasická chyba, když se plate a CG render potkají v různých prostorech. Nody OCIO v Nuke to za vás obvykle řeší, ale pod kapotou je změna primárních barev v lineárním světle tato jediná matice.

ColorMatrix má zaškrtávací políčko **invert**. Reference Foundry říká, že aplikuje inverzi matice místo matice samotné, a inverze je ta jediná matice, která přesně ruší tu první. Převod do ACEScg a zpět je matice následovaná svou inverzí, a protože Nuke drží 32bitové floaty včetně záporných hodnot, cesta tam a zpět vrátí původní čísla. Ne každou matici však lze vrátit. Jediné číslo zvané **determinant** měří, jak moc matice krychli zmáčkne. Pokud je nula, krychle byla zploštěna a informace je navždy pryč. Plná desaturace je klasický případ: jakmile je každý pixel šedý, žádná matice na světě vám neřekne, jakou barvu měl.

Masky a světlo, které žijí ve 3D

Zpět k position passu. Ukažte na zadní stěnu a hodnota z zůstává všude stejná, −4, protože každý pixel té stěny leží ve světě na stejné rovině. Ukažte na podlahu a y je vždy nula. Každý pixel je vektor, adresa ve 3D scéně, a ta adresa nezávisí na tom, kde kamera stojí. To dělá P pro compositora tak mocným. Maska postavená z P je připojená ke světu, ne k obrazovce, takže se drží stěny, když se kamera hýbe, a nikdy ji nemusíte trackovat ani animovat roto tvar.

Nejjednodušší 3D maska je koule. Vyberte bod ve světě, říkejme mu c. Pro každý pixel vezměte vektor P − c a změřte jeho délku: to je vzdálenost od povrchu v tom pixelu k vašemu bodu. Kde je vzdálenost menší než poloměr, je maska bílá a přes měkký okraj přechází do černé. Artisti to staví malým nodem Expression nebo sdíleným gizmem, často zvaným P_Matte, a nod PositionToPoints od Foundry, který „generuje 3D point cloud z xyz obrazu, jako je position pass“, vám umožní vidět mrak ve 3D vieweru, abyste kouli umístili, kam chcete.

Koule vypadá ze všech stran stejně, ale krabice ne. Tyrkysová bedna v naší místnosti je otočená o 30 stupňů, takže krabicová maska postavená přímo z P by ji přeřízla. Řešením je posunout svět tak, aby bedna seděla rovně. Odečtěte střed bedny od P nodem Add a pak zbytek otočte rotační maticí. Rotace je jen další matice 3×3 složená z kosinů a sinů, takže to zvládne obyčejná ColorMatrix aplikovaná na kanály P, přestože byl nod navržen pro barvu. Poté jeden jednoduchý test, jsou x, y a z každé mezi −0,5 a 0,5, dá krabicovou masku, která přesně kopíruje strany bedny. ColorMatrix drží jen 3×3, takže umí otáčet a škálovat, ale ne nic posouvat; posun vždy pochází z offsetu.

S P a N dohromady můžete do renderu přidat světlo, aniž byste se vraceli do 3D. Pro každý pixel je vektor od povrchu k lampě L − P. Vydělte ho jeho délkou, abyste dostali směr, udělejte **skalární součin** s normálou N a víte, jak přímo ten povrch míří ke světlu. Vydělte druhou mocninou vzdálenosti a máte přirozený úbytek světla. Foundry popisuje nod Relight jako nod, který bere „2D obraz obsahující normálový a point position pass“ a nechá vás ho nasvítit 3D světly, kamerou a materiálem, a tato aritmetika je jeho jádrem. Nemůže vrhat nové stíny, protože pass zná jen přední povrch, ale pro rychlý kop navíc, pohyblivé praktické světlo nebo barevný akcent je rychlý a interaktivní.

Bod lze popsat ze dvou míst: od počátku světa, nebo od kamery. Přechod mezi nimi potřebuje **matici 4×4**. Řádek a sloupec navíc umožní jedné matici držet rotaci a posun dohromady, což 3×3 nemůže. Trik je zapsat každý bod jako (x, y, z, 1), tzv. homogenní souřadnice. Transformace kamery je přesně taková matice a nod Camera v Nuke jednu nese. Vynásobte světový bod inverzí matice kamery a dostanete bod v prostoru kamery, kde se kamera dívá podél své vlastní osy −z. Vydělte x a y vzdáleností před objektivem, přenásobte ohniskovou vzdáleností a víte, kam bod dopadne v rámu. Takhle vám trackovaná kamera umožní připnout 2D prvek přesně nad 3D bod a takhle lze world position pass proměnit v pass v prostoru kamery.

Jakmile je P v compu, mnoho každodenních prací se smrskne na řádek matematiky. Výšková mlha je rampa na kanálu y passu P. Vzdálenostní mlha používá délku P minus pozici kamery. Studený grade jen na zadní stěně je test na z passu P, na „pozici stěny“ samotné. Všechny tři zůstávají správné, když se kamera hýbe, všechny tři lze změnit během vteřin, když režisér požádá, a žádná z nich nepotřebuje roto tvar ani nový render od lighting oddělení.

Mnoho vzorků v každém pixelu

Běžný plochý obraz drží jednu barvu a jednu alfu na pixel. Foundry popisuje deep obrazy jako obrazy obsahující „více vzorků na pixel v různých hloubkách“, každý s vlastní barvou, krytím a hloubkou vůči kameře. Sledujte jeden pixel naší místnosti, nyní plné nízké mlhy, a jeho paprsek projde plátkem za plátkem tenkého kouře, než dorazí k podlaze. Plochý render to všechno zmáčkne do jednoho čísla. Deep render drží každý plátek jako vlastní vzorek s přední a zadní hloubkou, takže se každý pixel stane seznamem vektorů seřazeným podle vzdálenosti. Nuke tyto seznamy načítá nodem DeepRead z deep souborů OpenEXR a formátu .dtex od Pixaru.

Odměna přijde, když kombinujete prvky. DeepMerge od Foundry „slučuje vzorky z deep obrazů a řeší holdouty“: prokládá vzorky obou vstupů podle hloubky, takže CG prvek zapadne na správné místo uvnitř kouře, zčásti skrytý tím, co leží před ním, a zčásti skrývající to, co leží za ním. S plochými obrazy byste potřebovali holdout matte renderovanou pro každý prvek proti každému dalšímu a nový render pokaždé, když se něco pohne. Plochý merge podle hloubky má jen jednu vzdálenost na pixel, takže jeho test je všechno, nebo nic: koule buď projde rovnou mlhou, nebo za ní zmizí, s tvrdými, schodovitými hranami. Proto Foundry říká, že s deep daty můžete „vyrenderovat pozadí jednou a později přesunout objekty na jiná místa a do jiných hloubek“.

Někdy plochý svět stále potřebuje matte. DeepHoldout vezme hlavní deep obraz a holdout deep obraz a vrátí plochý obraz hlavního vstupu „s dírami tam, kde objekty v holdout vstupu zakryly jeho části“, buď jen jako alfa matte, nebo jako barvu plus alfu. Compositoři ho používají k předání čistého, už vykrytého prvku zbytku plochého skriptu, nebo k získání alfy pro efekt, který existuje jen ve 2D, jako záře nebo lens flare, které mají potemnět tam, kde je CG prvek zahrabaný v kouři.

Lighting týmy renderují deep, ale look záběru se staví v plochém compu. **DeepRecolor** oba světy spojuje. Foundry ho popisuje jako sloučení „barevné informace standardního 2D a deep obrazu“: vezme barvu každého pixelu z plochého obrazu a rozprostře ji přes každý vzorek odpovídajícího deep pixelu. Ve výchozím stavu unpremultiplikuje alfou plochého obrazu a pak znovu vynásobí vlastní alfou každého vzorku. Se zapnutým *target input alpha* rozdělí plochou alfu mezi vzorky tak, aby zploštělý výsledek přesně odpovídal plochému obrazu, což pomáhá, když komprese nebo změna shaderu posunula deep alfy. Nagradujete tedy plate jako obvykle, přebarvíte deep data a každý DeepMerge poté nese váš grade.

Protože každý deep vzorek má hloubku podél známého paprsku kamery, je to také bod ve 3D: pozice kamery plus směrový vektor paprsku krát hloubka. DeepToPoints dělá přesně tohle. Foundry říká, že transformuje „vzorky deep pixelů na body ve 3D prostoru, které vidíte ve 3D pohledu Nuke, jako point cloud“, a navrhuje použít ho jako poziční referenci. Vidíte místnost, mlhu jako mrak bledých bodů a svůj CG prvek uvnitř a můžete proti nim zarovnat karty, částice nebo nové 3D prvky, aniž byste žádali o nový render.

To všechno má cenu a tou cenou je místo na disku. Plochý RGBA pixel v half floatu je 8 bajtů. Deep vzorek potřebuje barvu a alfu plus přední a zadní hloubku, šest hodnot obvykle uložených jako 32bitové floaty, tedy 24 bajtů, a každý pixel navíc zaznamenává, kolik vzorků drží. Naše malá místnost má v průměru asi **šest** vzorků na pixel; vlasy, kouř, listí a pohybové rozmazání mohou skutečné záběry dohnat k desítkám. Vynásobte to při 4K a jediný snímek je mnohonásobně větší než jeho plochá verze, ještě než přidáte jediný další pass. Deep soubory OpenEXR lze komprimovat, ale jen bezztrátově, takže se nikdy nezmenší tak, jak se může zmenšit plochý beauty.

Deep se tedy používá tam, kde se vyplatí: objemy, vlasy, silné pohybové rozmazání a záběry, kde se mnoho prvků kříží v hloubce. Lighting týmy ladí, jak jemně renderer krájí objemy, a compositoři zahazují, co nepotřebují, například pomocí DeepCrop, který Foundry popisuje jako ořez „deep dat vůči dané hloubce“. Heatmapa ukazuje, kde cena skutečně je. Zamlžená podlaha drží téměř všechny vzorky, zatímco každý pixel stěn vzadu je jediný neprůhledný vzorek.

Dohromady je skript compositora řetězec vektorů a matic. Barva přichází jako vektory a ColorMatrix ji otočí do správného prostoru a správného looku. P a N přicházejí jako vektory a stávají se maskami a světlem skrze skalární součiny, délky a rotace. Matice 4×4 kamery spojuje svět s rámem. Deep pixely jsou seznamy vektorů, které DeepMerge řadí podle hloubky. Matematiku nikdy nemusíte dělat ručně, protože ji Nuke dělá pro každý pixel, ale vědět, že nod je ve skutečnosti devět čísel nebo skalární součin, vám řekne, co umí a co ne, a dovolí vám postavit nástroj, který v nabídce chybí.

Zdroje a další čtení

  • Foundry, Nuke Reference Guide, „ColorMatrix“: learn.foundry.com
  • Foundry, Nuke Reference Guide, „Relight“ a „PositionToPoints“: Relight · PositionToPoints
  • Foundry, Nuke User Guide, „Deep Compositing“: learn.foundry.com
  • Foundry, Nuke Reference Guide, „Deep Nodes“, „DeepHoldout“, „DeepRecolor“, „DeepToPoints“: Deep Nodes · DeepHoldout · DeepRecolor · DeepToPoints
  • Academy of Motion Picture Arts and Sciences, „ACEScg: A Working Space for CGI Render and Compositing“ (S-2014-004)
  • Doporučení ITU-R BT.709, hodnoty parametrů pro HDTV (primární barvy a váhy jasu)
  • Dokumentace OpenEXR, „Interpreting OpenEXR Deep Pixels“: openexr.com
  • Gilbert Strang, *Introduction to Linear Algebra* (6. vyd., Wellesley-Cambridge Press, 2023)

*Všechny obrázky jsou ilustrace počítané ve vašem prohlížeči z jedné jednoduché ray tracované místnosti, ne skutečné produkční rendery ani screenshoty Nuke. Deep data, merge a relighting jsou skutečné výpočty na té malé scéně. Popisy nodů sledují vlastní dokumentaci Foundry k říjnu 2026.*

Zpět na blog