Pbr текстурирование что это

Что такое PBR? Часть V

Ранее в блоге.

Часть I — кратко затронул историю становления термина PBR и вывел главный тезис. PBR это не шейдер и не текстура или какой-то отдельно взятый рендер движок — это в первую очередь принципы и основы современной компьютерной графики, кто-то называет это философией.

Часть II — была посвящена такому понятию как PBS — Физически корректный шейдинг, как неотделимая часть физически корректного рендеринга. Кратко рассмотрел, что такое BRDF функции.

Часть III Реализация GTR (GGX) функции в V-ray. Альтернативные, физически корректные, BRDF модели. Аналитические BRDF модели (Merl библиотека). Коммерческие BRDF решения — VRscans (VrayScanedMtl)

Часть IV.I — PBR шейдинг в Дисней. Реализация в V-ray
Часть IV.II — PBR шейдинг в Дисней. Реализация в V-ray
Часть IV.III — PBR шейдинг в Дисней. Реализация в V-ray

Часть V — PBR текстуры (Заключительная часть цикла)

Финал

Финальная статья цикла, будет посвящена PBR текстурам. Сразу определю — PBR или «не PBR» текстур не бывает. Бывают текстуры отвечающие или не отвечающие PBR принципам.

Изначально, была идея написать статью исключительно о PBR текстурах. Она возникла после того, как я прикупил сборник как бы PBR текстур от CGAxis — не покупайте и даже не качайте с торентов этот сборник, если вам действительно нужны PBR текстуры.

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

PBR текстуры

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

Через растровую текстуру можно задать не только сложный диффузный цвет поверхности, но и «запечь» некоторые её свойства. Использование текстур, в которых «запечены» свойства материала, пришло в массы из игровой индустрии. По сложившейся практике пользователю, предлагается три базовые текстурные карты — Diffuse, Specular\Metalness и Glossy\Roughness, по ситуации, подключают дополнительные технические карты — Opacity, Normal, Height, Ambient occlusion, Cavity, Emissive maps. Классический сет это четыре текстуры: Diffuse, Specular\Metalness и Glossy\Roughness, Normal

Важным недостатком так называемых «PBR текстур» является отсутствие гибкости. Так например — карта Glossy\Roughness предлагает мне уже зафиксированные значение шероховатости поверхности. А что если мне нужно сделать больше глянца, как быть? Понятно что мне, как пользователю с опытом, не составляет труда «подкрутить» все эти карты до нужного результата, а как быть менее опытным коллегам? Поэтому мне не особо понятен тот хайп, который был в свое время поднят вокруг PBR текстур.

PBR текстуры для меня, в первую очередь, это решение все же узкоспециальное, для таких направлений как VR, реал-тайм и игровые движки, где нужно максимально упростить и унифицировать шейдерные вычисления, когда текстуры запекаются комплексно для всей модели сразу. В этом контексте — PBR текстуры это простое и универсальное решение, своего рода кроссплатформенный набор «Сделай сам».

3d модель, шейдер которой сделан с соблюдением PBR принципов, будет рендериться, в любой современной рендер системе, без необходимости конвертировать материалы или что либо в них перенастраивать. Особенно если часть свойств шейдера, было зафиксировано (запечено) в текстурах, о которых я говорил выше. Это важное и ценное качество для 3d модели, особенно когда вы продаете её на стоке [Посмотреть стрим о 3D стоках]. Покупатель будет понимать, что купив ваш продукт, он получит универсальное шейдерное решение, которое будет давать одинаковый результат при рендеринге в независимости от используемой рендер системы.

Есть два шейдерных решения так или иначе поддерживаемых в большинстве рендер движков — Specular workflow и Metalness workflow. Эти решения отличаются набором необходимых текстур и соответственно слотами размещения. Итоговая разница не существенна, но заметна в ряде деталей. Забегая вперед сразу скажу, что Metalness workflow более удобен, более экономичен в расходовании видеопамяти (актуально для игровых движков), прост и поэтому стал теперь доминирующим рабочим пространством.

Specular workflow

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

Для Specular workflow используется базовый сет из следующих растровых карт

Metalness workflow

Для Metalness workflow используется базовый сет из следующих растровых карт

В чем разница этих решений?

Очевидно, что некоторые текстуры подключаются к разным слотам шейдера и в принципе отличаются по содержанию. Разница между Glossy\Roughness картами небольшая: Glossy map это инвертированная Roughness map, переключение между режимами Glossy\Roughness поддерживается не во всех движках, но в любом случае адаптировать эту карту под нужный режим не составит труда при помощи Photoshop. Карта нормалей (Normal Map) не меняется в обоих решениях. Принципиальное отличие только в двух текстурах Diffuse и Specular\Metalness.

Для рабочего процесса Specular workflow — диффузная карта «закрашивается» черным в тех местах, где поверхность должна проявлять «металличность», там же, где поверхность является диэлектриком, задается необходимый цвет. Через текстурную карту Specular задается степень зеркальности объекта для диэлектрических участков через оттенок серого, а для металлических участков через необходимый цвет металла.

У рабочего процесса Metalness workflow— диффузная карта полностью цветная, как для металлических участков шейдера, так и на участках с диэлектрическими свойствами поверхности. Через черно-белую текстурную карту Metalness мы «сообщаем» рендер движку, где метал, где диэлектрик. По сути карта Metalness выполняет функции маски, а вся необходимая информация «снимается» с карты Diffuse.

Считается что Metalness workflow экономичней в контексте расходования видеопамяти, так как черно белая маска практически ничего «не весит». Я сравнил два сета и действительно сет для Metalness workflow на 20% легче сета Specular workflow.

Недостатки и тонкости работы с Metalness и Specular workflow

Я не буду перетряхивать все рендер движки, на предмет того, как у них организовано подключение так называемых PBR текстур и ограничусь только V-ray.

Классическая схема подключения текстур в Specular workflow

Недостатком этой схемы является то, что она предполагает полное отключение опции IOR, что фактически делает это решение физически некорректным, но…

Некоторые ресурсы предлагают адаптированный к V-ray сет для Specular workflow. В этом сете есть дополнительная IOR карта, которую нужно подключать к слоту Fresnel IOR и так же немного измененная по цвету Specular карта. Такое решение делает шейдер более корректным и отвечающим принципам PBR.

Хотя визуальная разница между этими двумя решениями будет едва ли заметна неискушенному пользователю.

Для подключения текстурных карт в режиме Metalness workflow, необходимо на вкладке BRDF переключиться в режим Use Roughness

Здесь тоже, всё не «слава богу», но получше чем у Specular workflow. Работа со множителем IOR в этом режиме возможна и я могу установить необходимое по ситуации значение, без использования дополнительных текстурных карт. Но, как мне «посчастливилось» выяснить, комплексное значение IOR у металлов значительно ниже чем у диэлектриков. И в примере который я сейчас разбираю, так же есть необходимость подключения дополнительной карты с разными значениями IOR для металла и для окислившейся поверхности (диэлектрика).

В связи с этим фактом, что у металлов есть комплексное значение IOR, которое хоть и не значительно, но влияет на результат, для Вас готовится отдельная статья по металлам, где я обновлю свое мнение и добавлю новую информацию по настройке металлов в V-Ray Next.

В статье Understanding metalness вы можете найти табличку, скриншот которой представлен ниже, Vlado (папа V-ray) вычислил комплексные значения IOR для ряда металлов которые можно\нужно использовать в совместно со включенной опцией Metalness.

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

Поскольку карта с необходимым значением IOR, к этому сету не прилагалась, я сделал кастомное решение используя ноду Mix и карту Metalness в качестве маски для разных значений IOR. Значения для IOR я поставил следующие:

IOR 1.05 = 0.9524 RGB для металлической поверхности (среднее значение из таблицы Vlado)
IOR 1.5 = 0.6666 RGB для окиси на поверхности металла (диэлектрик)

После всех тестов, я отдаю свое предпочтение схеме — Metalness workflow + IOR map, так как она наиболее близка к физически корректном решению. Но и другие схемы вполне рабочие, разница будет заметна только на мелких деталях, да и то, только на композитных материалах, которые я выбрал для обзора, где одновременно используется два типа материала — метал и диэлектрик. В простых, однородных, материалах эти нюансы будут менее всего заметны.

Так же сделал рендеры с контрастной световой схемой, что бы сравнить все четыре схемы с оригинальным превью, эксперимент не удался…

Тут сложно дать однозначный и объективный комментарий и сделать какое то сравнение, так как у меня нет возможности задействовать HDRi карту, которая использовалось для рендеринга оригинального превью у шейдера. Так что «ноу комментс…» Оригинал поярче, но не факт что у превью не «подкручивали» цветность.

Что еще нужно знать при работе с так называемым PBR текстурами?

Та информация, которую я прояснил, в процессе работы с материалами к этой статье, стала откровением… Всю свою сознательную трудовую жизнь, когда уже многие начали работать в гамме 2.2 и я в том числе, все текстуры по умолчанию подгружались в этой гамме. Единственной картой, которая нуждалась в корректировке была карта нормалей (Normal Map) её нужно было подгружать в линейной гамме — 1.0

Когда я более подробно стал изучать PBR тему и работу с текстурами в частности, я был удивлен, когда узнал что и остальные текстуры, кроме Specular и Diffuse, необходимо было подгружать в линейной гамме.

Почему так?

Это связано с тем что все черно-белые текстуры, если грубо, участвуют в математических вычислениях. Так например в карте Metlaness, черный пиксель означает 0, белый пиксель означает 1. Математика это линейные вычисления, поэтому шейдерные вычисления так же происходят в линейном пространстве и только два шейдерных компонента — Specular и Diffuse должны быть в представлены гамме 2.2 поскольку это визуальные составляющие и их обработка происходит в нелинейном пространстве.

Specular workflows

Metalness workflow

Это правило, распространяется и на все другие шейдерные компоненты, которые реализуются через черно-белые растровые текстуры — они все должны подгружаться в гамме 1.0 не зависимо от того используете ли вы текстуры из PBR сборников или делаете что-то свое.

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

Яндекс.Дзен | ВКонтакте | YouTube | Instagram

Источник

Как создавать PBR текстуры: практический курс. Часть 1

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что этоPbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это‘), array(«string» => ‘Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это‘), ); if (!isset($_COOKIE[‘rek’])) < print($banners[$GLOBALS["banner_num"]]["string"]); >elseif ($_COOKIE[‘rek’] == «rek1») < print($banners[0]["string"]); >elseif ($_COOKIE[‘rek’] == «rek2») < print($banners[1]["string"]); >?>

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Это продолжение первого тома теоретических изысканий о том, что такое PBR. Этот (второй) том посвящен практическим приёмам по созданию PBR текстур.

Свет и материя

Практические рекомендации по созданию PBR текстур

Физически корректный рендеринг (PBR) можно рассматривать скорее как методику, а не как жесткий стандарт. Существуют его принципы и инструкции, но не верно считать его стандартом. Таким образом, могут быть различия в его реализации. Эти различия обычно можно найти в типах карт, используемых в процессе шейдинга (создания материалов), трактовке BRDF (двулучевой функции отражательной способности (ДФОС)) и в том, как значения данных отвечающих за шероховатость / глянцевитость могут быть переназначены в отдельных случаях. Иногда изменяются даже названия карт, но в основе использования PBR заложены одни и те же принципы.

В этом руководстве мы обсудим два наиболее распространенных подхода при создании материалов:

как показано на рисунке 01:

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Инструменты Substance для создания PBR карт, входящие в состав программ SubstanceDesigner, SubstancePainter и Bitmap2Material 3, поддерживают оба эти подхода. Substance PBR-шейдеры metall/roughness и specular/glossiness используют т.н. GGX-разновидности функции BRDF, в которой не используется переназначение величин шероховатости и глянцевитости. Тем не менее, если пользовательские переназначения все же необходимы – это может быть легко реализовано в Substance материалах. Кроме того, пользовательские шейдеры поддерживаются инструментами Substance, что означает, что вы можете адаптировать Substance инструменты для всех пользовательских пайплайнов.

В первом томе данного издания мы рассмотрели PBR с технической и теоретической точки зрения. Во 2-м томе мы будем обсуждать практическое применение PBR текстур и сформулируем набор принципов, основанных на фундаментальных знаниях, установленных в первом томе. Мы начнем с переопределения PBR с художественной точки зрения. После этого мы рассмотрим workflow создания двух типов материала: metall/roughness и specular/glossiness, отвечающих общепринятым принципам и правилам. Затем мы подробно определим различия в методах создания (авторинга) таких типов материалов. Поэтому, стоит коротко напомнить основные моменты, чтобы получить полное представление об общих принципах создания PBR текстур.

Что такое PBR?

Физически корректный рендеринг (PBR) является методом затенения (шейдинга) и рендеринга, при котором обеспечивается более точное представление о том, как свет взаимодействует с поверхностью. Эти представления могут быть отнесены к физически корректному рендерингу (PBR) или физически корректному шейдину (PBS). В зависимости от того, какой аспект рабочего процесса обсуждается, PBS, как правило, специфичен для процесса шейдинга, а PBR, характерен для рендеринга и освещения. В комплексе оба термина описывают процесс достижения определенной цели с физически корректной точки зрения.

Каковы преимущества PBR?

Рассматриваемые преимущества PBR с художественной точки зрения и эффективности производства, могут заключаются в следующем:

Что это означает для художника?

Мы, как 3D художники должны думать несколько иначе о картах, которые описывают свойства поверхности. Существуют новые типы карт с правилами их создания и принципами которые стоит соблюдать.

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

Подход metall/roughness.

Подход metall/roughness определяется набором каналов, которые передаются в виде определённых текстур в PBR-шейдер. Основными картами при создании материала по подходу metall/roughness являются карты:

как показано на рисунке 02:

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Мы обсудим каждый из этих типов карт ниже. PBR-шейдеры также используют карту ambient occlusion, карту нормалей, и даже карту высоты для параллакс-маппинга, как показано на рисунке 03. Эти типы карт являются общими для обоих видов материалов (см. выше) и будут обсуждаться в разделе «Общие карты для обоих воркфлоу».

При создании metall/roughness материала, значение отражательной способности материала задается картой базового цвета, а для диэлектриков – также картой отраженного цвета. Отражения при скользящих углах падения определяются BRDF-моделью. Карта металличности работает как маска и используется для того, чтобы дифференцировать (отделить) данные для металлической поверхности от данных для неметаллической, найденные на текстуре базового цвета.

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Значения френелевского коэффициента F0 для диэлектриков (неметаллов) не определяются вручную, эту функцию берет на себя шейдер. Когда такой шейдер видит черный цвет на карте металличности, он обрабатывает соответствующие области в карте базового цвета как для диэлектрика и использует значение коэффициента отражения 4% (0,04 в линейном пространстве), как показано на рисунке 04. Как мы уже обсуждали в первой части, значение 4% считается наиболее распространенным для диэлектрических материалов. Важно отметить, что все значения, такие как: F0 для диэлектриков, отражающая способность, диапазон яркостей для альбедо (т.н. рассеянного цвета или чистого диффузного цвета), устанавливаются на основе реальных измерений. Яркости обеих карт на рисунке 04 также основаны на измерениях.

В первом томе мы обсуждали понятие сохранения энергии где говорилось, что интенсивность света, отраженного от поверхности никогда не будет выше интенсивности света, падающего на поверхность. С точки зрения работы материалов, шейдеры, как раз, и осуществляют управление сохранением энергии, как в случае с шейдерами Substance. При подходе metall/roughness закон сохранения энергии нарушить невозможно. Баланс между дифузом (отраженным цветом) и отражательной способностью контролируется маской металличности. Это означает, что мы не можем смоделировать ситуацию, когда диффузную и отражательную составляющую можно объединить с целью отразить/преломить больше света, чем первоначально получила поверхность.

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Константа F0 для диэлектриков.

Инструментарий Substance или UnrealEngine 4 для metall/roughness материалов дает возможность контролировать зеркальность или блеск материала с помощью изменения значение константы F0 (коэффициента отражения по френелю) для диэлектриков. Это значение называется «specularLevel» в Substance. Значения константы F0 представлены интервалом 0,0 – 0,08, как показано на рисунке 05. Если вам в Substance Designer нужно вручную установить F0 для диэлектрика, вы можете сделать это, используя выход «specularLevel», как показано на рисунке 06. Мы подробно обсудим значения F0 для диэлектриков далее, при обсуждении подхода specular/glossiness.

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Карта базового цвета – это RGB карта, которая может содержать 2 типа данных:

как показано на рисунке 07.

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

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Рекомендации по созданию текстуры базового цвета.

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

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

Значения яркостей для карты, которая описывает отражательную способность для металлов, должны быть получены реальными измерениями значений. Значения коэффициента отражения находятся в диапазоне 70 – 100%. Этот диапазон может быть отображен значениями sRGB 180 – 255. В разделе Substance PBR Utilities мы обсудим инструменты, которые обеспечивают предустановленные значения F0 для обычных материалов. Полезным информационным ресурсом, кроме этого, может стать блог Себастьяна Лагарда (Sebastien Lagarde), где приведены графики значений яркостей для карт металличности и шероховатости.

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

В следующем разделе, посвященном картам, описывающим металлы, будет показано, что базовый цвет также может содержать значения для описания отражательной способности металлов. Если информацию об участках поверхности с загрязнениями или окислениями добавить к карте базового цвета, то это приведет к тому, что отражательная способность участков металла будет понижена до диапазона, которые не должен соответствовать значениям чистого металла. Добавление участков загрязнений или окисления также должны быть учтены в карте металличности. Значения для отражений на metallic map также должны быть снижены в этих областях, чтобы обозначить, что эти участки больше не рассматриваются в качестве исходного металла. Например, на рисунке 10 видно, что ржавый металл рассматривается как диэлектрик и описан черным цветом в карте металличности.

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Карта металличности (metallic map, в градациях серого, в линейном пространстве).

Карта металличности используется, чтобы определить, какие участки материала обозначают чистый необработанный металл. Карта металличности – это изображение в оттенках серого или, грубо говоря, чёрно-белая текстура. Она работает как маска для карты базового цвета, и указывает шейдеру, как необходимо интерпретировать данные, найденные в карте базового цвета. Данные в карте металличности не содержат реальных данных, которые непосредственно описывают качества металла. Эта карта просто указывает шейдеру, какие области на карте базового цвета должны быть поняты как диффузный цвет диэлектрика, а в каких областях – как отражающие участки для металла. В карте металличности, значение 0,0 (черный – 0 sRGB) представляет неметаллические области, а 1,0 (белый – 255 sRGB) – чистый металл.

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

Pbr текстурирование что это. Смотреть фото Pbr текстурирование что это. Смотреть картинку Pbr текстурирование что это. Картинка про Pbr текстурирование что это. Фото Pbr текстурирование что это

Рекомендации по созданию текстуры металличности.

При создании карт для металлов следует учитывать две важные особенности:

Далее эти особенности будут учтены отдельно при обсуждении практических рекомендаций для создания PBS текстур.

Если вы хотите более подробно узнать о фотореалистичном рендеринге, то вам сюда.

А если вы хотите более глубоко понять как создавать фотореалистичные материалы с помощью V-Ray, то читайте эту статью.

Подпишитесь на обновление блога (вот 3 причины для этого).

Похожие статьи:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *