Шейдер кожи с использованием многослойного SSS

Материал из Blender3D.

Перейти к: навигация, поиск

Содержание

Шейдер кожи с использованием многослойного SSS

Автор: Victor Malherbe
Перевод: Буравчик

Введение

Органические материалы, вероятно, являются одними из самых сложных в настройке, поскольку их реализм не основывается исключительно на качестве текстуры. Текстура кожи часто выглядит пластмассовой, а при использовании подповерхностного рассеивания(SSS) становится похожей на воск.

Я пытался добиться реализма отрендеренной кожи в течение последних нескольких недель, или, по крайней мере, получить шейдер кожи, который бы не выглядел ужасно после рендеринга. Проведя некоторые исследования я начал собирать что-то типа "многослойного" шейдера кожи, в котором бы учитывались различные слои человеческой кожи. В Blender это означает использование отдельного материала для каждого слоя кожи (эпидерма, дерма и так далее) и объединение их в редакторе материалов для получения конечного результата.


Часть первая: Расслоение диффузии

Шаг первый: Структура кожи

Во-первых, займемся диффузией нашего материала: зеркальные отражения мы настроим отдельно. Прежде чем пытаться сымитировать вид кожи, мы должны разобраться с ее составом:
  • Верхним слоем кожи является эпидерма, которая слабо рассеивает свет. Ее цвет - желтовато-серый. На ступне, например, слой эпидермиса довольно толстый и поэтому кожа там выглядит почти желтой.
  • Глубже распологается слой дермы - она почти красная из-за присутствия крови. Дерма, в отличие от эпидермы, сильно рассеивает свет.
  • Даже если нижележащие ткани (мускулы, органы, хрящи и т.д.) почти незаметны, нам необходимо имитировать что-то похожее на фоновое рассеивание - когда уши, например, освещаются сзади, то они кажутся красными. Фоновое рассеивание ожно было бы сделать в слое дермы, поскольку в панели настроек SSS есть параметр Back, который позволяет отдельно настроить фронтальное и фоновое рассеивание. Но в конечном счете отделение фонового рассеивания от рассеивания в слое дермы дает больший контроль.
  • И последнее замечание о структуре кожи: в теории, над слоем эпидермы ничего нет. Однако использование SSS (даже в очень незначительной мере) ослабит действие карты неровностей в текстурах ваших моделей. Поэтому нам необходимо будет добавить еще один слой, который будет нерассеивающим диффузным слоем. Таким образом можно сохранить все неровности текстуры, а этот слой будет использован для текстурирования (по части диффузных шейдеров).
  • Просто взгляните на рисунок, который подытоживает все, что нам необходимо имитировать. Вооружившись этими знаниями мы готовы приступить к работе и настройке материалов.


Подповерхностное рассеивание
Подповерхностное рассеивание, или SSS,- это свойство, связанное с полупрозрачностью 
объектов, которые не являются ни полностью отражающими, ни полностью прозрачными. От 
отражающих поверхностей лучи света просто "отскакивают". Они проходят сквозь прозрачные и 
однородные объекты, преломляясь два раза (при падении на поверхность и при выходе из 
объекта). Но полупрозрачные объекты рассеивают падающий свет, преломляя лучи множество 
раз хаотичным образом до их выхода. Так получается поверхность с очень мягким отражением. 
Объектами, обладающими таким свойством, являются, например, молоко, воск, помидоры и т.д. 
Многие органические объекты рассеивают свет.

Шаг второй: Нерассеяная диффузия

Настройка освещения: прежде чем начать работу над шейдером, следует настроить простую, но в то же время удобную, тестовую сцену. Я использовал модель головы, предоставленную пользователем Maqs на форумах www.BlenderArtists.org, который так же дал мне разрешение использовать модель в этой статье. Он заслуживает благодарности еще и за то, что очень помог мне в работе над шейдером. Можно также использовать стандартную голову обезьянки ([клавиша Пробел] Add>>Mesh>>Monkey) вместо модели Maqs'а или даже использовать голову, импортированную из MakeHuman (File>>Import>>Wavefront).

Моя настройка освещения довольно проста: основной источник Lamp (Add>>Lamp>>Lamp) со включенными мягкими трассируемыми тенями (raytraced shadows) для освещения головы и лампа Rim со слегка голубоватым оттенком, освещающая объект сзади для подчеркивания контура.


Теперь мы можем приступить непосредственно к созданию шейдера. Добавте новый материал к вашему объекту (панель Materials, add new) и переименуйте его в "un-scattered_diffuse". Назначте материалу цвет естественной кожи и установите алгоритм диффузного отражения в Oren-Nayar. Диффузный шейдер Oren-Nayar во время рендеринга учитывает гипотетические микронеровности на поверхности, что позволяет получить грубую поверхность как у таких материалов, как глина, одежда, сухие камни и т.д. Поэтому он позволяет получить более естественное затенение. Не забудьте установить ползунок Spec в значение 0.00, поскольку зеркальным отражением мы займемся позже. Если вы приготовили несколько хороших текстур для вашей модели, то можете назначить их сейчас, за исключением текстуры зеркального отражения. Важно понять, что, хотя эпидерма и является верхним слоем кожи, мы не будем назначать текстуру на этот слой, так как эффект SSS сильно размоет эффект неровностей поверхности.


Шаг третий: Слой эпидемы

Теперь что касается слоя эпидермы. Нам предстоит создать шейдер, выглядящий как бескровное тело, поскольку кровь протекает в основном в слое дермы. В итоге он должен выглядеть серо-желтым и иметь небольшой эффект SSS. Добавьте новый материал и назовите его "epidermis", подберите для него цвет бледной кожи и посмотрите на настройки, которые я использовал для SSS (я не буду объяснять все детально, поскольку мы будем настраивать три слоя с эффектом SSS, смотрите скриншоты). Следует иметь ввиду, что для каждого слоя значение цветового охвата для красного канала должно быть в два раза больше значения цветового охвата зеленого канала, а

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


Шаг четвертый: Слой дермы

В реальности слой дермы имеет красный или оранжевый цвет из-за крови, протекающей по этому слою. После объединения всех диффузных слоев нам будет необходимо увидеть кровь, находящуюся под кожей. Поэтому добавте еще один материал, назовите его "dermis" и подберите для него красно-оранжевый оттенок. В отличие от эпидермы слой дермы должен сильно рассеивать свет, поэтому придется установить намного большее масштабное значение SSS. Взгляните на рисунок с настройками, которые я использовал. Обратите внимание, что ползунок Back установлен в 0.00, так как для фонового рассеивания мы будем использовать отдельный шейдер. И опять же, не забудьте установить ползунок Spec в нулевое значение.


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

Шаг пятый: Фоновое рассеивание

Теперь мы можем настроить фоновое рассеивание. Я предпочел отделить его от слоя дермы. Этим мы добились большего контроля над подповерхностным рассеиванием. Добавте еще один материал и назовите его, скажем, "back_scattering", подберите для него почти черный цвет, но не чистый черный - если ваш шейдер или текстура имеют чистый черный цвет, то ничего не будет рассеиваться, поскольку любой цвет, умноженный на черный, становится черным (чистый черный цвет имеет значения [0, 0, 0]). Теперь на панели SSS установите красный цвет и большое масштабное значение. Оно на самом деле зависит от размеров вашей модели, в моем случае я хотел добиться красноватого оттенка на ушах, но не слишком сильного (в противном случае возникло бы ощущение, что модель была совсем крошечная). Обратите внимание, что значение Back установлено на максимум, а Front равно 0. И, опять же, значение Spec установите нулевым.


Шаг шестой: Объединение всех диффузных слоев с помощью нодов материалов

Замечание
Параметр Eror: для тестовых рендеров лучше устанивить его в районе 0.5 или даже 1.0. 
Для финальных рендеров можно сделать его равным 0.1 или даже 0.05, если вым так хочется
получить болле точные вычисления или изображение большого размера.

Приступим: добавьте новый материал и назовите его "Combined_shaderы", нажмите кнопку Node. Откройте редактор нодов материалов и загрузите в него все материалы, созданные ранее (Пробел>>Add>>Input>>Material). Выполните это четыре раза и для каждой ноды назначте один из материалов кожи. Теперь можно свести все слои вместе. Добавьте новый оператор смешивания (Пробел>>Add>>Color>>Mix) и измените режим смешивания с Mix на Screen. Теперь соедините блок, содержащий слой эпидермы, с первым входом оператора Screen, и блок, содержащий слой дермы, со вторым входом. Коэффициент смешивания оставьте по умолчанию равным 0.50. Теперь выполните то же самое с материалом "Back_scattering", но оператор смешивания оставте на этот раз в режиме Add.
Фоновое рассеивание будет черным за исключением тех мест, где модель освещена сзади. Устанавливая оператор смешивания в режим Add, мы можем быть уверны, что темные области в фоновом рассеивании не повлияют на отрендеренное изображение, поскольку чистый черный цвет ([0, 0, 0]) ничего не изменяет. Значение Fac должно быть равно 1.0, иначе фоновое рассеивание не будет добавлено полностью. Ели же вы заметите, что эффект фонового рассеивания слишком ввелик, то вместо изменения настроек SSS материала можно уменьшить значение Fac оператора смешивания. И, наконец, объедините слой "unscattered_diffuse" с остальными слоями оператором Screen.
На этот раз я установил значение Fac равным 0.60. Вы сами можете решить какого типа кожу хотите видеть: более прозрачную или с более сильным отражением, которая поглощает мало света. Соедините ноду Screen c материалом Output.

Вы, возможно, обратили внимание, что я добавил контреллер RGB Curves после сведения слоев дермы и эпидермы. На самом деле настройка цвета кожи таким образом более удобна, чем изменеие параметров SSS в панели материалов. И последнее замечание об операторе Screen: теоретически, мы должны использовать оператор Mix для объединения слоев, поскольку мы всего лишь хотим увидеть все слои одновременно. Однако оператор Screen дает лучший результат, так как при использовании оператора Mix кожа выглядит плоской. Думаю, лучше использовать оператор Screen тогда, когда настройки освещения не сильно, образно говоря, экстремальны. В экстремальных условия освещения, например, при очень ярком свете, оператор Screen приводит к полностью неправильным цветам. Таким образом, выбор оператора Mix или Screen полностью зависит от ситуации.

Теперь текстура выглядит довольно хорошо. Но все же она еще похожа на резину. Очевидно, отсутствуют зеркальные отражения, поэтому приступим ко второй части.


Часть вторая. Добавление отражений

Шаг седьмой: Зеркальные отражения на двух слоях

Отражения, которые мы собираемся смоделировать, возникают по двум причинам: оражения от самой кожи (довольно мягкие и имеющие крупные размеры) и отражения от пота на коже, которые будут ярче и сильнее концентрированы. Оба отражения будут иметь голубоватый оттенок, чтоб уравновесить желтый цвет кожи. Лично я предпочел использовать стандартный шейдер Cook-Torrance для отражений, так как он, в отличие от шейдера Phong, позволяет получить что-то похожее на эффект Fresnel (отражения должны быть ярче под отстрым углом зрения).

Добавьте еще один шейдер в вашу модель и назовите его, напримет, "Skin_soft_speculars". Параметр Ref необходимо устонавить 0.00, поскольку диффузные отражения нам теперь не нужны. Цвет объекта можно сделать чистым черным.


Замечание
Эффект Fresnel часто упоминается, когда речь идет об отражающих поверхностях. Сила
отражения большинства поверхностей при взгладе на них под острым углом отличается от силы 
отражения при взгляде под почти прямым углом. Этот эффект и называется эффектом 
Fresnel.
Пример такого эффекта вы можете увидеть, взглянув в окно: при взгляде на стекло под острым углом сложно что-либо разглядеть за окном, так как поверхность стекла становится сильно отражающей в отличие случая, когда вы смотрите в окно обычным образом.

Так же вы межете отключить кнопку Diff в редакторе нодов после добавления вышего материала. Важно, что эти шейдеры обеспечивают только зеркальные отражения. Для отражений используется шейдер Cook-Torrence. Поскольку отражения для слоя кожи должны быть мягкими и иметь большую площадь, установите значение Spec равным 0.1 и Hard равным 10.
Настроив светло-голубой оттенок для этого материала, вы можете добавить еще один материал, назвав его, например, "Sweat_hard_speculars". Его единственное отличие от предыдущего материала в том, что ползунок Spec установлен в значение 0.3, а Hard - 30.


Шаг восьмой. Объединение зеркальных и диффузных отражений - конечное дерево нодов

Оба слоя зеркальных отражений теперь готовы. Выберите материал "Combined_shaders" и снова откройте редактор нодов. Добавьте оба материала с картами отражений. Объедините оба материала оператором Mix (как обычно, Пробел>>Add>>Color>>Mix и измените режим смешивания на Screen). Установите значение Faq равным 1.0. После оператора Mix можно добавить еще и контроллер RGB Curves, как это сделал я, для более быстрого контроля над яркостью отражений.

В довершение добавьте еще один оператор Screen, который наложит зеркальные отражения поверх диффузной части шейдера. Значение уровня смешивания установите равным 1.0. На рисунке слева показана часть дерева нодов, относящаяся к зеркальным отражениям материала, а на рисунке снизу показано полное дерево нодов материала.
Теперь наш шейдер готов к применению. Конечно, есть несколько аспектов, которые могут быть и должны быть улучшены для достижения фотореализма. Если вам еще не стало скучно, то, возможно, вам захочется продолжить чтение. Часть третья ждет вас!


Часть третья: Двигаемся дальше

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

1. Правильные блики с использованием мягких трассируемых отражений

Вы, вероятно, множество раз замечали, что зеркальные отражения - это не совсем удачный метод моделирования реального поведения света. В теории, блики возникают по причине объектов, имеющих яркость выше среднего уровня. Поэтому зеркальные отражения являются самым простым способом получения бликов. Они не могут отражать ничего, кроме светлых объектов, и зеркальное отражение на поверхности не соответствует реальной форме отражаемого объекта (по крайней мере в Blender).

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

Что если мы попробуем настроить блики, используя трассируемые отражения? Конечно, это будет накладно с точки зрения времени рендеринга. Но зато мы получим более удовлетворительный результат. Давайте попробуем. Все что нужно сделать - добавить новый шейдер, который будет контролировать только мягкие отражения, и объединить его с основним шейдером. Решение о полной или частичной замене зеркальных отражений я оставляю на ваше усмотрение, так как это сильно влияет на время рендеринга.

Во-первых, следует учесть, что поверхность не может быть полностью отражающей, поскольку мы хотим видеть только блики. Как будет выглядеть блик, если наш материал отражает только 50% света? Белый объект будет выглядеть белым только на 50%, если он отражается от поверхности с пятидесятипроцентным отражением. Ответ прост: благодаря параметру Emit можно получить объекты "белее белого". Настраивая этот параметр, мы получим правильные отражения на поверхности, которая плохо отражает свет. Взгляните на рендер, на котором показаны отражения трех плоскостей. Эти плоскости отличаются только значением Emit, которое увеличивается слева направо.


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

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


Вместо объяснения деталей используемых настроек сцены я сделал скриншот тех значений, которые использовал в следующем рендере. Тридцать две выборки - это хороший компромис между временем рендеринга и качеством. Для финального рендеринга лучше использовать 64 или 128 выборок. Более высокие значения приводят к такому незначительному уменьшению шума, что разницу сложно заметить.


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

2. Совершенствуем шейдер далее

Шейдер, над которым мы работали, является "базовым" материалом, пригодным для болшинства случаев. И, конечно же, он может быть настроен в зависимости от того типа кожи, который вы хотите получить после рендеринга. Допустим, вы хотите получить "пушистую" кожу. Тогда ваш материал должен выглядеть мягко, с небольшим эффектом Fresnel, имитирующим бесчисленные волоски, которые становятся лучше различимы при взгляде под острым углом. Подобный эффект может быть получен настройками нодов Normal и Geometry в редакторе нодов материалов.
Или, если вам не хочется делать это нодами, можно использовать диффузный шейдер Minnaert вместо Oren-Nayar, который я использовал для нерассеивающего диффузного слоя. Эффекта "улучшения" краев так же можно добиться использованием мягких трассируемых теней с небольшим эффектом Fresnel. Вы можете погонять настройки материала по собственному вкусу: то, что я предложил - это всего лишь "скелет", базовая заготовка, которую можно изменять и настраивать под собственные нужды.

Вот еще одна идея для исследования: составляя дерево нодов, мы использовали фиксированные значения операторов смешивания, но ведь можно использовать текстуры для контроля параметра Fac. К примеру, значение оператора Screen между слоями дермы и эпидермы равно 0.6, хотя в действительности оно не постоянно: на подошвах кожа кажется желтой из-за более тостого слоя эпидермы; губы кажутся почти красными, так как слой эпидермы тонок в таких чувствительных местах, ну и так далее.

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


3. Тонкости рендеринга

В заключение приведу некоторые приемы рендеринга/постобработки, которые помогут усилить реализм отрендеренной кожи.
Перый трюк доволно простой: для увеличения яркости и контраста отрендеренного изображения вы можете использовать ноду наложения при постобработке, с помощью которой наложить отрендеренное изображение на само себя. Цвета, контраст и т.д., естественно, могут быть подкорректированы контроллером RGB Curves. Еще бы я посоветовал использовать Ambient Occlusion! Кожа, конечно же, имеет свойство отсвечивать на саму себя. Чем ближе два участка друг к другу, тем более насыщенными (оранжевыми в случае с кожей) они кажутся вследствие многочисленных отражений света между этими участвами. AO так же дает ощущение глубины отрендеренных полигонов. Вам лишь нужно настроить проход AO так, чтоб он был оранжевым, и затем умножить его на отрендеренное изображение, как показано на рисунке слева. Вы заметите, что, например, веки и губы лучше "прорисованы", если так можно сказать.

Примеры некорректной настройки освещения модели головы
Примеры некорректной настройки освещения модели головы


Заключение

В итоге мы получили вполне реалистичный шейдер, который, надеюсь, в дальнейшем поможет вам избавиться от обычно пластиково выглядящей кожи. Во-первых, я хотел бы поблагодарить сообщество Blender, от которго я получил много ценных советов. И, помимо прочего, спасибо вам за чтение. Все, что мне нужно вам пожелать - Happy Blending!

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


Личные инструменты