Grabduck

The Foundry Nuke. Введение

:

большое разрешение — по клику

Снова здравствуй, Хабр!

В этом посте я бы хотел рассказать о великолепной программе под названием Nuke от компании The Foundry, которая уже затрагивалась вот в этом посте, но вызвала много вопросов читателей, далеких от 3д графики в общем, и от 3д-композитинга в частности.

Если описать в двух предложениях, то Нюк является мировым стандартом в композитинге и пост-обработке, и был одним из ключевых инструментов в подавляющем большинстве голливудских фильмов с бюджетом, отличным от кустарного.
Да что вообще говорить — Аватар, Трон: Наследие, Трансформеры, Watchmen, Властелины Колец, и большинство остальных голливудских блокбастеров были сделаны именно в Нюке.

Познакомился я с ним примерно три года назад, и сразу же в него влюбился: это одна из самых гениальных программ, что я когда-либо видел — как в плане используемых подходов, так и в плане юзабилити.

В этом посте не урок, а объяснение на пальцах концепций и принципов, на которых он построен — что это за зверь, для чего он нужен, с чем его едят, и насколько он вкусный.

В процессе написания поста я понял, что все, что я хотел бы описать, просто не уместится ни в один пост, ни в цикл статей. Хоть пост и получился длинным, но это вершина айсберга — в нем описывается чуть менее 0.01% всего, чем хочется поделиться.

Интересно?
Добро пожаловать под кат! Осторожно! Много трафика, Джобса, чайников, и надкусанных НЛО.

В качестве вступления приведу несколько видео, наиболее ярко представляющих эту программу.

Небольшая ремарка: некоторые вещи я буду описывать в сравнении с фотошопом, так как он знаком всем читателям, а сравнивать с софтом для композитинга смысла не имеет: мало читателей с ним знакомо, а те, что знакомы — все знают и без меня.

Небольшая ремарка номер два: я получил кармы (спасибо!) и перенес в наиболее подходящий блог. В данном случае это «Обработка изображений», а не «3д графика», так как материал именно этого поста больше подходит для него: Нюк большей частью заточен под обработку видео и имеет огромный арсенал средств, но ни что не мешает использовать его для обработки отдельных изображений — просто как единственный кадр. Хотя он имеет гигантское значение в 3д графике и она была бы другой без него.


Начнем издалека.

Давным-давно, во времена первых семи максов, господства scanline рендера, и моего детства, на выходе из 3д-пакета (допустим, 3ds max) мы получали финальную картинку/серию картинок, которые выглядели круто по тем временам, но сейчас ни чего, кроме улыбки не вызывают.

Большие студии же (ILM, Weta, Pixar, DreamWorks, Digital Domain, Blur, и так далее), использовали с еще более давних времен «разделение труда», именуемое пайплайном (pipeline): одни люди делают модели и геометрию, другие рисуют текстуры, третьи анимируют, четвертые рендерят, пятые занимаются композитингом, пост-эффектами, и пост-обработкой, шестые — продают, а седьмые — получают кассовые сборы из кинотеатров.

Нас интересует именно часть пайплайна от рендеринга до пост-обработки, а именно: композитинг, пост-эффекты, и пост-обработка, все вместе называемые VFX.

Цель всего этого действа — как можно лучше интегрировать трехмерные объекты в двухмерные изображения, полученные с камеры (посмотрите на Джобса с чайником), создавая иллюзию того, что этот объект там так и был, либо собрать по кусочкам несколько различных трехмерных сцен (или даже одну), наконец, придать всему законченный вид — такой, который увидит зритель (например, в кинотеатре).

В основе технической составляющей данного подхода лежит такой принцип:

После расчета сцены 3д-пакет выдает не финальное изображение, а «суповой набор» из «полуфабрикатов», именуемых пассами (pass) — некоторое количество составных частей изображения в виде отдельных изображений: цвет объектов, блики, отражения/преломления, освещение, тени, ambient occlusion, глубина, всевозможные маски, и даже data-пассы (о которых чуть позже), где цвет пикселя кодирует какое-нибудь значение (например, позицию этого пикселя в мировых координатах, или направление и скорость движения).


Ну и зачем, спросите вы, нужно городить огород с пассами, если можно сразу получить готовое изображение в формате jpeg?

А затем, что гибкость такого подхода и его возможности поражают воображение: не нужно каждый раз с нуля пересчитывать сцену, занимая часы, или даже дни, если захотелось что-то поправить — это можно сделать в реалтайме, просто подкорректировав нужный пасс — как в фотошопе, с той лишь разницей, что фотошопу 99% возможностей и мощи Нюка и не снились, что я и продемонстрирую на примере фотожабы с Джобсом.


1. HDR и 32 битный цвет


В отличие от фотошопа, где 32 битность поддерживается криво и ей нельзя нормально пользоваться, Нюк — это полностью 32 битное линейное пространство.

Это значит то, что вместо традиционных целочисленных 8 бит на канал (True Color — 24 бита в сумме из трех каналов) в нюке используется 32 бит в формате с плавающей запятой (обычный сишный float) на каждый канал, что дает возможность пикселям принимать любые значения, входящие в дапазон поддерживаемых типом данных float — в том числе и отрицательные.

Посмотрите — все цвета, что вы видите на экране монитора, в представлении float лежат в диапазоне от 0 до 1, но цвету пикселя ни что не мешает иметь запредельные значения, например такие:

На этом скриншоте у цвета синей полоски в центре красная и зеленая компонента имеют значения около минус шести тысяч, а синий — вообще около пяти миллиардов.

Для чего нужны такие большие диапазоны цветов? Хороший вопрос — отвечу я.
Нужны они для того, чтобы можно было иметь и ультраглубокие тени «чернее черного», и ультраяркие света «белее белого» в одном и том же цветовом пространстве и свободно ими оперировать без потерь и ошибок округления (это важно): менять экспозицию, сдвиг, гамму, производить с ними различные математические операции, и так далее.

Более того, это дает возможность получать дата-пассы из 3д-пакета, которые были бы в принципе невозможны при использовании обычных целочисленных 8 бит на канал.

Есть много форматов файлов для хранения изображений с большим динамическим диапазоном, но чаще всего используется exr, который стал стандартом индустрии де-факто за его гибкость: можно хранить неограниченное количество пассов в любом формате цвета внутри одного файла (правда, он может достигать очень внушительных размеров — у меня в среднем получается от гигабайта на одно изображение 4000х5000).

Резюмируя, можно сказать, что с точки зрения цвета, пайплайн выглядит так:

1) Получить все пассы от 3д-пакета в формате exr и в 32bit float на канал, весом в несколько (десятки, сотни) гигабайт.
2) Загрузить их в Нюк, там провести все цветокоррекции, добавить все эффекты, итд., а на выходе получить финальный jpg (avi в случае видео) в 8 бит на канал и весом в несколько мегабайт.

Также, стоит отметить, что 8 битные изображения (sRGB), загруженные в нюк, подвергаются обратной гамма-коррекции, чтобы их цветовое пространство стало линейным, а в окне просмотра и при выводе — прямой гамма-коррекции, хотя пользователь об этом может и не догадываться.
А вот 32-битные изображения линейны сами по себе — они не модифицируются.

Для чего нужна линейность? Для того, чтобы математические операции (даже банальное наложение двух изображений основано на определенных формулах) имели предсказуемую, единообразную природу.

2. Процедурный неразрушающий подход в виде дерева


Основой нюка является дерево узлов (node graph), позволяющее гибко редактировать что угодно и как угодно, при этом не теряя ни бита, так как каждый узел (node) представляет собой какое-то действие. Именно действие: загрузить изображение, наложить несколько изображений, размыть, смешать с другим, ну и так далее: все, что душе угодно — выбор огромен. Каждый нод имеет большое количество настроек, а между собой они соединяются ребрами ориентированного графа, именуемыми пайпами (pipe).

Продемонстрирую все это на простом, но полностью притянутом за уши примере (НЛО я векторно срисовал в нюке отсюда, когда делал Джобса, а потом сохранил как jpeg для упрощения данного примера):

1) Наложение двух изображений в режиме multiply (многие режимы наложения — точно такие же, как в фотошопе):

2) Надкусим НЛО на манер Apple — сделаем круг в векторе и вычтем из нашего хабраНЛО.

3) В отдельной ветке дерева скопируем из хабралого синий канал во все остальные, получив монохромное изображение — интенсивность у синего канала была около 0.4, поэтому лого стало серым, опустим серый до черного, чтобы получить черное лого, и размоем его (blur).

4) Наложим размытое черное лого на наше НЛО в режиме умножения, объединив обе ветки дерева, и выведем результат в файл.

Для чего я все это показал? А для того, чтобы продемонстрировать мощь дерева.

Очень сильно упрощая: Допустим, нужно наложить два слоя, а потом их размыть.

Чтобы реализовать это в фотошопе у нас есть два варианта:

1) Мы их объединим/схлопнем, тем самым необратимо теряя оба, а потом размоем через фильтры. А если потом что-то не понравится и нужно будет изменить? Начинай с начала.

2) Мы их дублируем и делаем невидимыми, а потом повторим пункт 1.
Хорошо, мы теперь имеем бэкапы оригинальных слоев и можем их поменять в случае необходимости. Но тогда встает проблема посерьезнее — нужно наизусть помнить, какие манипуляции с ними проводились, чтобы их повторить. А если мы забыли? Делай снова!

Единственный выход — либо делать отдельный action для каждого своего действия (извращение), либо называть каждый слой так, чтобы он отражал свою историю.

Даже на изображениях с небольшим числом слоев это приводит к лютым, мозговырывающим названиям, а про изображения с большим числом слоев я и не говорю. У меня есть несколько psd трехлетней давности с несколькими тысячами активных слоев, и мне не хочется их открывать — не говоря о редактировании.

Так как нюк оперирует с действиями (процедурный подход), то таких проблем, как описаны выше для фотошопа, просто нет в принципе, by design: можно подать другие исходные изображения на входы дерева и получить то, что нужно.

Кстати, если сделать цепочку из Merge в нюке, то это будет абсолютный эквивалент слоев.

Кстати, скрипты нюка весят довольно мало — самый большой скрипт, что я делал, весил около 500кб, и при этом он был огромен.


На это у меня ушло около трех часов, а вот скриншот дерева:

Сначала я выбрал вот эту фотографию из выдачи гугла (большая по клику):

Почему я выбрал именно это изображение? Потому что оно идеально для демонстрации многих вещей, не имеющих аналогов в фотошопе, плюс на экране макбука есть отражение лица — оно нам пригодится в дальнейшем.

Потом я сделал простенькую сцену в 3ds max, где наложил лого хабра из шапки сайта на примитив teapot, дешево осветил одним источником, и бросил HDRI карту на окружение, чтобы на чайнике были всякие разные отражения.

Также, я на глаз сделал несколько цилиндров, которые не видны камере, но затеняют чайник в пассе с ambient occlusion, чтобы симулировать контактные тени от пальцев.

После расчета я получил 32 битный exr со всеми пассами, плюс отдельный exr с ambient occlusion, так как считал его отдельно.

Вот они все:

1) Сведенное изображение, которое показывает в окне рендера и которое многие используют как финальное, если не пользуются композитингом (см. самое начало поста). Также оно называется Beauty pass.
Но это не для нас — нам этого не достаточно, так что едем дальше.

2) Пассы, из которых состоит картинка выше:

Diffuse pass — плоские текстуры объектов и их цвет

Lighting pass — тени и освещение. Вообще, все эти вещи делаются в отдельных пассах, но в данном случае я их вывел в одном — для упрощения.

Reflection pass — все отражения, что есть в сцене

Specular pass — блики от источников света

Ambient Occlusion pass

Так как потом выяснилось, что затенение от цилиндров не соответствует расположению пальцев, я перерисовал это затенение вручную в нюке:

Получать Beauty pass из этих компонентов мы будем вот по такой формуле:
Beauty = Diffuse * Lighting + Specular + Reflection

Diffuse * Lighting:

Diffuse * Lighting + Specular:

Diffuse * Lighting + Specular + Reflection (в пасс reflection добавлено отражение с монитора макбука — об этом расскажу ниже):

Теперь нужно добавить контактные тени из AO — умножаем получившийся Beauty на Ambient Occlusion:

Обратите внимание: добавились тени около ручки, добавляя реализма.

Делаем цветокоррекцию, чтобы цвета чайника были как можно ближе к цветам оригинальной фотографии (а вот это уже почти невозможно без 32 битного цвета — будет слишком много потерь и округлений):

3) Z-Depth pass — глубина изображения. Один из data-пассов — цвет пикселя кодирует расстояние от него до камеры. Чем ярче пиксель, тем он ближе к зрителю.
Используется для эффектов типа Depth of Field, Defocus, Bokeh/Convolve, и так далее. Также, удобен для наложения двух изображений с учетом глубины, если у них обоих есть пасс с глубиной в одном и том же пространстве.

Теперь нужно сделать размытие по глубине, чтобы оно соответствовало оригинальной фотографии (посмотрите на макбук — он далеко не четкий).

Калибровочный вывод от эффекта Depth of Field:

Зеленое — в фокусе, красное — ближе к камере и размыто, синее — дальше от камеры и размыто.

Результат работы глубины поля:

Добавляем зерно на глаз — чтобы как можно лучше соответствовало зерну на фотографии. Нюк имеет средства для совмещения зернистости (анализируется зерно из оригинала и генерируется аналогичное), но я не стал ими пользоваться ради простоты примера.

4) В отдельной ветке дерева мы берем отражение джобса с макбука:

Далее мы его трансформируем, делаем цветокоррекцию, и накладываем на Reflection pass:

Результат вы уже видели выше. Так как это происходит в виде дерева, то приходится вот так разрывать повествование — что поделать.

5) Еще одной веткой дерева мы ретушируем макбук и фон (аналогично работе clone stamp в фотошопе):

Потом делаем маску для наложения НЛО на фон с помощью методов keying (да, зеленые фоны в Аватаре заменяли на Пандору именно с помощью Нюка):

6) Размоем надкусанное НЛО, нанесем на него зерно, и добавим в фон.

7) В векторе нарисуем маску для пальцев, которые будут выходить перед чайником:

Ну, и, наконец, наложим чайник с использованием маски.


Спасибо kuzubov, за то, что уступил мне тему поста про нюк, который хотел написать сам.