19 июня, 2013

Gamma, ColorMapping and LinearWorkflow

Краткий обзор  и практическое применение Гаммы и Color Mapping в связке 3D max, V-ray и Nuke.

    Много было написано около этой темы, много домыслов и неверных выводов накручено. Многие уже брались за неё и бросали, возвращались и опять бросали так и не разобравшись зачем это надо, в надежде что всё и так хорошо. Но не всё так хорошо как кажется, особенно когда человек делает из своего хобби профессию и приносит свои навыки в рабочую среду где коллеги делают "рукалицо" от мысли: "что вот опять и всё по новой". Хочется кинуть и свои 5 копеек в этот фонтан с надеждой что читатели перестанут или хотя бы станут реже возвращаться к этому вопросу на форумах и в рабочих беседах.


Часть первая. Gamma. Начало.


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

Так-же у гаммы есть положительное свойство - повышение ступенек градиента в тёмном участке спектра, что позволяет хранить больше информации в тенях. Это особенно важно, так как наше восприятие особенно чувствительно к теням и мене к пересветам. Немного подробней об этом читайте ниже.


     Всё-бы ничего, но почему-то компьютерная графика была построена на математических принципах и все манипуляции с цветом сходятся на банальных арифметических операциях. И представьте теперь, что вам надо средний серый цвет увеличить в двое. В линейном пространстве "средний серый" равен 0.5* итого получается 0.5х2=1.0 то есть получится чистый белый цвет, что вполне логично, а не в линейном пространстве "средний серый" равен где-то навскидку 0.72, умножаем его на 2 и получается... ерунда  получается, ребята.
     Так вот Rendering это куча разных арифметических извратов и всякие мултиплееры, оверлееры и колорбёрны городят немного не то, что от них требуется если цветовое пространство не линейно. Поэтому те у кого глаза в состоянии отличить голубое от синего решили работать в "линейке", чтобы не создавать себе проблем на всех этапах обработки изображений.

     Правило: Приводим входящий материал в линейное пространство. Работаем в линейном пространстве. Гамма-коррекция применяется только к финальной картинке (причем в большинстве случаев это происходит автоматически).

Пример перевода гаммы есть в описании к Блендеру:

   Кста,  приводить Normal bump в линейное пространство не стоит, так как такие карты уже находятся в "линейке", при подключении таких текстур надо исключать их из коррекции.


Часть вторая. Color mapping.


     Кроме сложностей с гаммой мы имеем  проблему технологическую, которая упирается в возможности отображения. У нас имеется 2 основных способа отображение картинок - на бумаге и на экране. Оба способа  различаются принципиально тем что один отражает свет, а второй излучает, но тот и другой имеют очень ограниченный диапазон передачи интенсивности света, в сравнении с той которую мы можем увидеть, поэтому изображение надо "сжать" до нужного диапазона. Причём недостаточно просто сжать спектр, это надо сделать так чтобы в местах слабой чувствительности сжимать много, а там где у нас много чувствительности соответственно надо сжимать... ну вы поняли. Сейчас мы сделаем для ясности шаг в сторону, где я подготовил объяснение такому поведению.


В кустах, неподалёку. 

      Мы воспринимаем окружающий мир не линейно. Чтобы усилить ощущение чего либо в 2 раза нам недостаточно удвоить порцию... нам надо её утроить или учетверить, то есть если накрутить яркость источника света в 2 раза то по ощущениям мы скажем, что яркость увеличилась на 30%... вот такие мы "чёткие ребята". Все органы чувств работают в логарифмической пропорции. Обратный натуральный логарифм называют Экспонентой... которая и маячит в настройках Color Mapping. Логарифм - основная функция при преобразовании интенсивности, независимо от того изображение ли это, порция соли или радость от количества денег в банке.

График двоичного логарифма
График двоичного логарифма
 
    По этой причине мы хорошо различаем полутона в тёмных участках и более равнодушны к перепадам в ярких. Именно поэтому при сжатии мы пренебрегаем высокими значениями цвета.
   Представьте что в видимом нами мире разница в яркости может заходить далеко за миллион, а монитор в состоянии показать разницу примерно в 10 000. Колормапинг "ужимает" широкий диапазон яркости в тот маленький участок который может отобразить монитор или картинка напечатанная на листе бумаге, он делает это вместо наших глаз, а мозг интерпретирует картинку как готовое изображение. Обратите внимание на график Двоичного Логарифма, из него становится ясно сжатию подвергаются в основном светлые участки в то время как "тени" остаются без изменения, так мы избавляемся от неприятных "засветов" которыми грешат работы начинающих визуализаторов.
Логарифм и гамма это практически одно и тоже, но у них есть особенные различия в построение: для гаммы нужно иметь две крайние точки - ноль и единицу соответствующие черному и белому цвету, между этими точками строится кривая с силой изгиба равной гамме. А вот для экспоненты достаточно одной начальной точки и кривая может строится до бесконечности. Поэтому в линейном пространстве с высоким динамическим диапазоном (HDR) цвета, где нет ограничения на яркость применяется экспонента, а уже в в готовых применяют гамму. Есть конечно программы где можно применить гамму и к HDR изображению, но подобный изврат может привести к непредсказуемым значениям изначально стоящим выше единице.
     Колормаппинг и гамма-коррекция две похожие вещи, но занимается разными задачами. Гамма предназначена для компенсации "старого наследия", а Колормепинг сжимает "линейку".
То есть в работе мы учитываем два отдельных преобразования цвета и не надо их путать между собой.



 

Часть Третья.  Практическая работа


     Есть два основных пути изготовления картинок. Один путь подразумевает уже готовый файл на выходе из программы: с гаммой, обрезанной HDR, c минемальным количеством бит на канал, со всем тем что подразумевает отсутствее дальнейших правок. Второй готовит "сырой полуфабрикат" который будит "варится" до конца в программе пост обработки. Если мы готовим файл для поста то нам нужно сохранить линейное пространство + высокий динамический диапазон цветов. Мы рассмотрим на практике оба метода.

     В последней версии Макса из настроек Гаммы убрали Инпут с Оутпутом, поэтому надо установить общее значение гаммы - 2,2. 3D Мах сам буде приводить входящие текстуры в линейное пространство.

Настройки Колормапинга в 3D Max делаем такими:
Type - Linear multiply. - Мы же работаем в линейке
Dark - 1.
Bright - 1. - эти значения оставим по умолчанию если понадобится мы поменяем их на посте.
Гамма - 2,2. - Дело в том что эта гамма не будет применяться к финальному изображению и по факту останется - 1... потому что мы установим галочку в:
Don't affect colors - ставим галку. Делаем мы это для того чтобы остаться в линейном пространстве, но зная то что Враевский Семплер вечно не докладывает в тёмных местах, мы применяем гамму только к нему. Таким образом в темных участках у нас детали не пропадут и мы останемся в "линейке"
Clamp - Отключить, так как нам понадобится весь диапазон яркости.

     Сохранить такие изображения надо во Float point форматах (32 бит), таких как openEXR. Теперь на выходе у нас будет относительно точная модель представление цвета, почти как в реальности.


Готовим полуфабрикат.

     Признаюсь, мне нравится пост своей творческой гибкостью. Когда вся основная, грубая работа сделана и осталось "покрутить" кнопки для вкуса.
     Опустим детали свойственные для конкретных проектов и сразу перейдём к Колормапингу.
Итак у нас "линейная" картинка с выжженными светлыми участками. Вспоминая мой рассказ о особенностях восприятия мы повторим похожий фокус. Причем механика работы будет схожа с типом Reinhard в Колормаппинге V-ray.
     Нам понадобится 2 ноды: Grade и Log2Lin.
Grade будет выполнять роль мултиплеера всей картинки или значения ISO камеры если вам так удобней.

Log2Lin будет сжимать картинку, но для начала надо его настроить:
Operation - lin2log.
Black - 0
White - 255
Gamma - 1
Mix - 0.95

     "Сжимая" яркость мы делаем картинку темней поэтому сразу можете поставить значение Gain равное 5 в настройках Ноды Grade. В принципе на этом всё.
     Мiх Ноды Log2Lin будет осуществлять туже функцию что Burn value в Колормаппинге только в другую сторону, то есть если Burn value равно 0.3 то Mix ставте около 0.7

     Если вы хотите подправить Гамму, сделать тёмные места светлей то надо повысить Gain в ноде Grade и повысить Mix в Log2Lin


Без танцев.

     Если вы избегаете Поста, то можно Пост сделать в Колормапинге. Для этого лучше выбрать тип Rinhard, так как он занимается усреднением между линейкой и экспонентой через параметр Burn value. Если у вас "выжженные" цвета то достаточно понизить значение Burn value. Яркость картинки повышаете через параметр ISO и shutter speed в VrayPhysicalCam.

Gamma - 1
Clamp - 1
Don't affect colors - убрать галку.

     Так как теперь семплер будет раскидывать семплы исходя из видимой картинки то надо понизить порог шума в DMC Sampler c 0,01 для "линейки" примерно до 0,003.

Некоторые ребята вместо того чтобы понижать уровень шума просто повышают гамму на 2,2 а в настройках Гаммы Макса ставит еденичку в поле Оутпут. Я считаю это идеологически неверно хотя это тоже работает.




_______________________________________________________________________________

* Здесь и далее речь идёт о значениях цвета в Float Point где 0=черному цвету, а 1=белому.

Комментариев нет:

Отправить комментарий