ARNOLD · color_space (string, OCIO)RENDERMAN · linearize (bool)BŁĄD · podwójna dekodyzacja
Rozdział 11 / Tekstury

Color vs data w teksturach

Ten sam plik PNG oznacza dwie zupełnie różne rzeczy w zależności od jednego przełącznika przy slocie tekstury — i to najczęstszy błąd, jaki zobaczysz w cudzej scenie.

TL;DR
Etap: Kolor kontra dane

Dlaczego ten sam plik PNG znaczy dwie różne rzeczy

Plik graficzny sam w sobie nie wie, czym jest — to tylko siatka liczb 0–255 (albo 0–65535, przy 16 bitach). To, czy te liczby mają zostać zdekodowane krzywą sRGB przed użyciem w shadingu (Rozdział 5), zależy wyłącznie od tego, co ta tekstura reprezentuje. Albedo/base color to percepcyjnie zakodowany kolor — malarz czy fotograf pracował w przestrzeni, w której 50% szarości na ekranie odpowiada wartości ~188/255, nie 128/255 — więc wymaga dekodowania do linear, dokładnie jak każdy inny obraz sRGB. Roughness, metalness, normal, displacement, maska SSS to dane: liczby, które mają znaczyć dokładnie to, co jest zapisane w pliku, bez żadnej krzywej pośrodku. Zdekodowanie danych jak koloru przesuwa każdą z tych liczb w miejsce, którego artysta nigdy nie zamierzał.

Etap: Arnold

color_space jako string z configu OCIO

Node image w Arnoldzie ma parametr color_space — dziś string, którego lista dostępnych wartości pochodzi wprost z aktywnego configu OCIO (Rozdział 6), nie z zaszytej na sztywno listy. Typowe wartości: RAW (dla masek, roughness, displacement — bez żadnej konwersji), sRGB (dla tekstur 8–16 bit typu JPEG/PNG), ACEScg (gdy plik już jest w working space renderera). Jest też auto — ale to nie jest inteligentne wykrywanie po nazwie pliku: Arnold w trybie auto stosuje surową heurystykę, plik 8-bitowy traktuje jako sRGB, plik zmiennoprzecinkowy jako linear, i na tym kończy analizę.

Kluczowy, łatwy do przeoczenia fakt: Arnold sam nie czyta reguł plikowych (file rules) z configu OCIO — czyli tych reguł, które w configu mówią „każdy plik pasujący do wzorca *_BaseColor* jest sRGB, każdy pasujący do *_Roughness* jest Raw”. Te reguły potrafi zastosować aplikacja hosta (Maya, Houdini), o ile sama je propaguje do node'ów obrazu — jeśli nie propaguje, kolor_space trzeba ustawić ręcznie na każdym node'zie z osobna.

Etap: RenderMan

linearize jako grubszy przełącznik binarny

PxrTexture w RenderManie steruje tym samym przełącznikiem znacznie prościej: linearize — pojedynczy bool, domyślnie wyłączony, który po prostu odwraca krzywą sRGB. Włączony dla albedo/koloru, wyłączony dla roughness/displacement/normal — dokładnie ten sam podział co w Arnoldzie, tylko bez nazwanych przestrzeni barw na poziomie samego node'a. Zamiast tego RenderMan (od wersji 24) przenosi większość decyzji o przestrzeni barw wcześniej w pipeline'ie, do Texture Managera przy pieczeniu tekstur na .tex (Rozdział 12) — kolor_space jest tam często ustalany raz, na etapie txmake, zamiast być odczytywany dynamicznie przy każdym samplingu, jak w Arnoldzie.

AspektArnold (image)RenderMan (PxrTexture)
Parametrcolor_space (string)linearize (bool)
Nazwane przestrzenietak — z configu OCIOnie — tylko odwrócenie sRGB
Auto-detekcja po nazwie plikutylko jeśli host app propaguje file rules configuzwykle ustalane wcześniej, przy pieczeniu .tex
Moment decyzjiprzy odczycie tekstury / renderzeczęsto raz, przy txmake
Etap: Kiedy się myli

Podwójna dekodyzacja: dwa systemy próbujące zrobić to samo

Najczęstszy realny błąd nie polega na tym, że ktoś świadomie źle ustawia przełącznik — polega na tym, że dwa niezależne systemy próbują zdekodować tę samą teksturę, nie wiedząc o sobie nawzajem. Dwa udokumentowane, konkretne przykłady: w Mayi node aiImage potrafi utknąć na wartości „sRGB” i nie dawać się przełączyć, kolidując z własnym Color Space z node'a file. W Houdini node File COP ma osobny checkbox „Linearize Non-Linear Images”, który dekoduje teksturę dodatkowo, niezależnie od tego, co ustala config OCIO sceny czy sam Arnold — dwie dekodyzacje z rzędu na tej samej teksturze.

Objawy w każdą stronę są rozpoznawalne. Roughness albo normal map błędnie potraktowana jak sRGB (zdekodowana, choć nie powinna): dekodyzacja to krzywa wypukła w dolnym zakresie, więc wartości środkowego roughness zostają ściągnięte w dół — powierzchnia wygląda gładsza/bardziej błyszcząca, niż artysta zamierzył; normal map traci swój neutralny punkt odniesienia (128,128,255), więc detal bumpa wygląda subtelnie zniekształcony, nie tam, gdzie był wyrzeźbiony. Albedo błędnie potraktowane jak dane (nie zdekodowane, choć powinno): wartości zostają w swojej percepcyjnie podniesionej, zbyt jasnej formie, więc materiał wygląda wypłowiały i pozbawiony kontrastu, zanim jeszcze dotrze do niego jakiekolwiek światło.

Słowniczek
Kolor kontra dane (color vs. data)
Podział tekstur na percepcyjnie zakodowane (albedo, sRGB, wymaga dekodowania) i surowe liczby (roughness, normal, displacement — bez dekodowania).
color_space (Arnold)
String na node'zie image, wartości pochodzą z aktywnego configu OCIO.
linearize (RenderMan)
Bool na PxrTexture, odwraca krzywą sRGB — bez nazwanych przestrzeni barw.
File rules (OCIO)
Reguły w configu OCIO dopasowujące przestrzeń barw po wzorcu nazwy pliku — Arnold sam ich nie czyta, host app może.
Podwójna dekodyzacja
Błąd, gdy DCC i renderer niezależnie dekodują tę samą teksturę, np. Houdini File COP plus ustawienie renderera.