Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 1. Пиксель
О чем эта серия уроков?
В данной серии статей я постараюсь максимально раскрыть теорию создания текстур для игровой индустрии, начиная от самого понятия «пиксель» и заканчивая построением сложных материалов (шейдеров) в игровом движке на примере Unreal Engine 4.
Часть 1. Пиксель — вы ее читаете.
Часть 2. Маски и текстуры здесь.
Часть 3. PBR и материалы здесь.
Часть 4. Модели, нормали и развертка здесь.
Часть 5. Система материалов здесь.
Я попытаюсь охватить такие программы, как Windows Paint, Photoshop, Substance Painter, Substance Designer и, возможно, Quixel (Не особо вижу смысла в этой программе, так как после прочтения всех статей у читающих должно сформироваться полностью понимание того, как работать с текстурами, и Quixel станет интуитивно понятен).
Я постараюсь разобрать максимально подробно такие понятия, как PBR, маски и различные виды текстур.
И все это будет рассмотрено с самых низких и базовых уровней для первоклашек и тех, кто с этим вообще никогда и ни-ни, чтобы по завершении прочтения этих статей, у читающего не оставалось никаких вопросов, было максимальное понимание, как это все работает, и он мог начать уверено работать с текстурами и шейдерами в любом ПО, так как основа (база, суть) у всех одна.
Я не совершенен. Я не считаю, что я знаю эту тему от и до. Я начал писать эту статью, чтобы помочь своим знакомым втягиваться в этот прекрасный мир текстурирования без моей помощи — чтобы они могли в любой момент открыть статьи, прочитать их и понять, как им с этим работать и что им делать. И я буду благодарен всем вам, если вы поможете мне с заполнением этого тутора, чтобы мы все могли дать ссылку на эти статьи нужным людям, и они могли быстро втянуться в это направление. Я очень прошу всех, кому не безразлична эта тема и тема обучения этому направлению, помочь мне в комментариях — вносить свои правки или пожелания, если вдруг что-то я упущу или ошибусь в чем-то.
Очень прошу всех, кто может придумать другие примеры для лучшего понимания какого-то блока, отписаться в комментариях, чтобы я мог добавить эти примеры в статью. Вдруг, мои примеры окажутся недостаточными для полного понимания основы?
Итак, ребятушки, поехали =)
Часть 1. Пиксель
А что такое пиксель?
Понятие «пиксель» используется в определении физического элемента матрицы дисплея, а так же наименьшей цветовой точкой в изображении, из кучки которых формируется само изображение.
Понятие «пиксель» равноправно используется и там и там по той простой причине, что в целом принцип работы у этого элемента одинаков и в мониторах и в изображениях с небольшими отличиями. Поэтому для начала давайте разберем принцип работы пикселя на мониторе.
Пиксель и мониторы
(Описание работы пикселей ниже является абстрактным и не описывает реальные физические явления работы ЖК-мониторов).
В мониторах пиксель является физическим элементом, состоящим из 3х светящихся элементов 3 цветов — Красного, Зеленого и Синего. Интенсивность каждого элемента (сила свечения) определяет цвет пикселя. То есть, если зеленый и синий элементы перестают полностью светиться, а красный элемент остается включенным, то на экране это будет уже красная точка (красный пиксель), и если физически максимально приблизиться к монитору — можно разглядеть, как эта красная точка справа от себя имеет черный пробел — два погасших элемента.
Диапазон Интенсивности и Цвет пикселей
Еще раз повторим. Цвет пикселя определяется 3 световыми элементами — красным, зеленым и синим. В зависимости от их настройки свечения получается сам цвет. Это важно.
Теперь представим это в виде шкалы интенсивности каждого элемента, где зеленый цвет представляет текущую интенсивность, а в квадрате справа цвет, который примерно получается из комбинации интенсивности элементов:
Представим, что на рисунке показана максимальная интенсивность свечения всех элементов пикселя, что в итоге дает нам белый пиксель на мониторе. Соответственно, если мы уменьшим интенсивность Зеленого и Синего элементов до 0, то получим исключительно яркий красный цвет:
А так же мы подходим к очень важному моменту — диапазону интенсивности.
Диапазон интенсивности (назовем его так) — это диапазон состояния элемента от его минимального состояния (отсутствия свечения полностью) до его максимального состояния (максимальная яркость свечения).
Это можно выразить во многих форматах, например:
- — От 0% до 100%. То есть, элемент может светиться в пол силы, иначе говоря, на 50%.
- — От 0 до 6000 свечей. То есть, максимальная яркость элемента (100%) — 6000 свечей, а мощность на 75% будет равна соответственно 4500 свечам.
- — От 0 до 255. То есть, 30% в этом диапазоне будут равны 76,5.
- — От 0 до 1. То же самое, что 100%, только вместо 100 использовать 1. Это удобно для вычислений, что мы обязательно рассмотрим позже.
В наших уроках мы будем использовать последний вариант представления диапазона, так как он удобен для расчетов, в чем мы в дальнейшем убедимся.
Оффтоп
В реальности (за пределами наших условностей) яркость света в мониторах измеряется в единицах измерения "candela", что в переводе с итальянского означает «свеча». В мире принято обозначать яркость и писать cd (русском варианте кд). В нашем туторе для того, чтобы обозначить именно условность этих значений, я буду продолжать использовать слово "свеча".
Отдельное спасибо за корректировку Vitter'у.
Отдельное спасибо за корректировку Vitter'у.
В наших уроках мы будем использовать последний вариант представления диапазона, так как он удобен для расчетов, в чем мы в дальнейшем убедимся.
Теперь добавим к нашей шкале диапазоны интенсивности и получим следующую картинку:
Сейчас мы видим, что интенсивность R = 1, интенсивность G = 0.55-0.60, а B = 0. В итоге мы получаем примерно оранжевый цвет, который выдают нам на мониторах пиксели. Можно физически максимально близко приблизиться к монитору и попробовать рассмотреть пиксели в квадрате результата — вы не увидите в этих пикселях синего элемента, так как он полностью отключен (его интенсивность равна 0).
Важно понимать, что у каждого монитора, в зависимости от производителя матрицы, сборки и каких-то дополнительных параметров, сам уровень яркости может полностью разниться.
Например, диапазон яркости пикселя у матриц мониторов:
- — Samsung может быть 6000 свечей.
- — LG = 5800 свечей.
- — HP = 12000 свечей.
Это абстрактные цифры, не имеющие никакого отношения к реальности, нужны для того, чтобы было понимание, что у каждого монитора максимальная сила интенсивности может быть разной, а вот диапазон интенсивности всегда один — от 0 до 1. То есть, когда вы выкручиваете до 1 интенсивность красного элемента, то у вас он начинает светиться максимально ярко, потому что 1 = максимум.
Сейчас у нас появилось максимальное представление о том, как выстраивается цвет на мониторе — миллион пикселей настраивают интенсивность своих элементов так, чтобы в сумме получался нужный цвет. Если вы читаете на белом фоне черными буквами этот текст, то уже должны понимать, что сами буквы отображаются пикселями, которые полностью выключили свое свечение, а белый фон состоит из пикселей, которые включили интенсивность всех своих элементов на максимум.
Если заходить совсем глубоко в этот океан, то можно обнаружить, что у пикселя есть 2 диапазона интенсивности свечения — это диапазон интенсивности каждого элемента, и общий диапазон интенсивности, который определяет в целом яркость всего монитора (для примера яркость монитора убавляют в темноте и прибавляют, когда очень светло).
Разрешение экрана и размеры пикселей
И так, поняв, как выстраивается цвет в пикселях, мы понимаем, как формируется изображение на мониторе. А какой размер у пикселя? И почему размер важен?
Чем меньше пиксель в размерах, тем больше можно их засунуть в монитор. Однако само количество пикселей всегда ограничено разрешением экрана.
Например, экран с разрешением 1920х1080 содержит в себе 2 073 600 пикселей. То есть, ширина экрана состоит из 1920 пикселей, а высота = 1080 пикселям. Перемножив эти два значения, мы получаем площадь (количество) пикселей.
Таким образом, в зависимости от диагонали монитора и разрешения экрана, пиксель на экране имеет свои размеры. Так, при диагонали монитора в 19 дюймов и разрешении 1920х1080 размер пикселя будет меньше, чем у монитора 24-х дюймов и таким же разрешением. Соответственно, если мы будем брать 24-хдюймовый монитор с разрешением 2560х1440, то размер пикселей у него будет меньше, чем у предыдущего примера.
Итого
У нас есть представление, как формируется цвет пикселей на мониторе.
У нас есть представление о размерах пикселей, и что они могут изменяться в зависимости от самого монитора.
У нас есть представление, что при разрешении 1920х1080 на мониторах телефона картинки будут смотреться детальнее и четче, так как пиксели меньше.
И в целом, у нас есть понимание того, как формируется изображение на мониторе.
Пиксель в изображениях
Еще раз. Понятие «пиксель» используется в определении физического элемента матрицы дисплея, а так же наименьшей цветовой точкой в изображении, из кучки которых формируется само изображение.
Формирование цвета
Давайте рассмотрим изображение, какую-нибудь картинку. Например, моего кота:
Данная картинка имеет разрешение 178х266 пикселей. То есть, картинка состоит из 47.348 пикселей и занимает на экране всего 2.2 процента пространства. А так ли это? Действительно ли эта картинка занимает на вашем мониторе 47.348 физических пикселей? А если масштаб картинки уменьшить? При уменьшении и увеличении картинки число пикселей, из которых она состоит, не изменяется, а значит, пиксели в картинке явно подразумевают что-то другое, отличное от пикселей в мониторе. И да, и нет.
Пиксель в изображении — это наименьшая цветовая точка, из кучки которых составляется изображение. Количество пикселей в картинке никак не привязано к монитору и зависит от того, кто создавал эту картинку (или что создавало). В данном примере, количество пикселей зависело от моих кривых рук — я вырезал фото случайным образом и получил картинку с таким количеством пикселей.
Чтобы было проще понять, что такое «пиксель» в изображении, стоит обратиться к программной реализации этого объекта.
Пиксель в изображении для компьютера — это набор цифр. Условно говоря, этот блок (кирпич, квадрат) — один белый квадратик на ухе кота занимает 32 бита. Когда компьютер хочет отобразить моего кота на вашем мониторе, он считывает каждый пиксель изображения (все 47.348 пикселей поочередно), и выводит их на монитор. При масштабе изображения 1 к 1 (1 пиксель изображения равен 1 пикселю монитора или, иначе говоря, масштаб равен 100%), размер изображения занимает точно такое же количество пикселей монитора, какое имеет сам.
Каждый такой пиксель состоит из 4 значений (каналов) по 8 бит = 32 бита.
3 значения отводятся на распределение интенсивности цветов Красного, Зеленого и Синего (вспоминая, как работает пиксель в мониторе, сразу становится понятно, как эти значения влияют на цвет).
1 значение отводится прозрачности (об этом позже).
(В этих уроках мы будем рассматривать только 32-битные изображения и 8 битные каналы. Все остальное — это уже частности и прочие стандарты, которые работают по аналогии).
Каждое значение (канал) может быть в интервале от 0 до 255 целых чисел, или иначе — 256 значений, что равно 8 битам.
Иначе говоря:
Если каналы, отвечающие за зеленый и синий буду равны 0, а красный будет равен 255 — то пиксель изображения будет максимально красным.
Если значение зеленого поднять до 128 (что равно середине или 0.5), то пиксель будет оранжевым, как на примере с пикселями от монитора выше.
Или вот такой вот еще пример:
В этом изображении параметры Оттенок, Контраст и Яркость на самом деле никак не влияют на формирование цвета. Это производные, которые высчитываются автоматически из текущих значений каналов, а не хранятся в них, поэтому пугаться такого количества цифр не нужно.
То есть, у пикселя изображения есть три канала (три значения), которые имеют свой диапазон интенсивности от 0 до 255. Регулируя интенсивность канала, можно получать различные оттенки цветов.
С этого момента мы начнем пользоваться программой Adobe Photoshop, потому что у нее есть отличный способ визуализации составления цвета из 3-х каналов (и даже больше, но об этом потом).
Так завелось, что для визуального отображения диапазона интенсивности начали использовать оттенки белого цвета.
Самый черный цвет = 0.
Самый белый цвет = 1 (или 255, если рассматривать шкалу от 0 до 255).
И выглядит это вот так:
Кстати, настройкой интенсивности в Photoshop отвечает параметр Level (используемое обозначение диапазона 0 — 100). Где 65 можно расценивать, как 65% от интенсивности или 0.65:
Помните, как на скриншоте настроек цвета в Paint я просил не обращать внимания на другие параметры? На самом деле, и в Photoshop можно не обращать внимания на другие параметры. Все управляется с помощью 3 каналов — RGB. Остальные значения здесь высчитываются исходя из значений RGB. Но ими можно воспользоваться, например, указывая интенсивность в параметре Level от 0 до 100, и тогда Photoshop за нас высчитает нужные значения для RGB.
В Photoshop можно переключаться на каждый канал отдельно и видеть, как в диапазоне от 0 до 1 белого цвета обозначена интенсивность каждого канала:
Красный канал:
Зеленый канал:
Синий канал:
Ну и еще раз, как все вместе выглядит:
Теперь, понимая, как складывается цвет пикселя из суммы каналов, как визуализируется интенсивность каждого из каналов, можно понять, какие цвета примерно у объектов, если смотреть каждый канал раздельно. Например, оранжевое покрывало справа сверху на красном канале ярко-белое (интенсивность от 0.8 и выше), на зеленом канале средняя интенсивность (около 0.5), а на синем канале оно практически черное (интенсивность около 0). В совокупности получился оранжевый цвет.
Итого
Пиксель в изображении формирует цвет примерно так же, как и пиксель на мониторе По факту, когда картинка 1 к 1 масштабом пиксель изображения говорит пикселю монитора, как ему светить. А вот изменение масштаба изображения уже заставляет ПО, в котором это происходит, обрабатывать картинку иначе.
(Далее абзац с субъективным представлением о процессах работы) Насколько я понимаю, то при увеличении масштаба картинки, ПО просто красит кучку пикселей (например, 4 на 4) в одинаковый цвет (как будто это один пиксель), формируя ощущение приближения картинки и ее пикселизацию. А вот при уменьшении масштаба картинки, когда на 1 реальный пиксель монитора начинает приходиться 2 и более пикселя изображения, ПО начинает усреднять цвет нескольких пикселей изображения, которые воюют за 1 пиксель монитора. И при увеличении и при уменьшении масштаба картинки ПО так или иначе использует свои алгоритмы обработки изображений.
Дополнительно:
Выше расписана система построения изображения без какого либо сжатия. А вообще, существуют разновидности методов сжатия картинки, при которых значения либо урезаются, либо берутся средние у рядом стоящих, и так далее — нас это сейчас не интересует, и методы сжатия — это уже способы урезания объема памяти на компьютере, которые отталкиваются от данного представления работы пикселя.
Изображения и Маски
И теперь постепенно мы подбираемся к самому интересному — маскам.
Первая маска, с которой мы уже столкнулись, но не озвучили этого — это маска прозрачности.
Напоминаем, что пиксель имеет 4 канала по 8 бит. Из них 3 канала отвечают за формирование цвета, а 4тый отвечает за прозрачность.
Маска прозрачности — это 4-ый канал в пикселе изображения, который говорит о том, что этот пиксель должен отображаться полностью, иметь прозрачность или не отображаться полностью.
То есть, этот канал так же имеет размер в 8 бит и может иметь значения от 0 до 255. Где 0 — максимально прозрачный, а 255 — максимально НЕ прозрачный.
Если у вас в изображении нет канала прозрачности, то его легко добавить, нажав на добавление канала:
И у вас сразу появится Альфа-канал.
Сейчас, все значения в этом канале равны 0, и он визуально полностью черный.
Далее я обозначил зону 100% видимости — выделил моего кота, прорисовав в канале альфа силуэт кота:
Теперь, если включить отображение всех 3х каналов + Альфа-канала, то можно увидеть следующее:
Photoshop пометил красным зоны, которые полностью прозрачны, чтобы я понимал, что при выгрузке прозрачного изображения попавшие в красную зону пиксели будут записаны, у них будет значение во всех 4 каналах, но так, как в 4-ом канале у них стоит значение 0, то они не будут отображаться и, следовательно, будут висеть грузом для файла изображения.
Вот так выглядит экспортированное изображение в PNG формате со слоем прозрачности (на самом деле, это был Tiff, но роли это не играет никакой):
Теперь нужно отметить, что когда я рисовал маску прозрачности, то на ней были плавные переходы (то есть, не грубо 1 и 0, а 1 по центру, а по краям мягкие перепады с 1 до 0). Это позволило создать полупрозрачные пиксели, которые на этом изображении показывают, как плавно вокруг кота картинка переходит в прозрачность.
Так плавно мы подошли к следующей обширной теме, которую я постараюсь осветить в ближайшее время — к маскам и первому уроку текстурирования.
Спасибо за внимание, жду ваших пожеланий и корректировок =)