Расписание курсов 🔔 Vehicles and Props: старт курса 14 ноября, продолжительность 3 месяца. Gas Station: старт курса 20 декабря, продолжительность 2 месяца. На курсе Environment Artist допускаются студенты, успешно прошедшие один из курсов: Gas Station / Vehicles and Props. Продолжительность обучения 12 месяцев. #индустрия@cgitems
PBR. Физически корректный рендер

PBR. Физически корректный рендер

В этой статье мы поговорим про такое понятие как PBR и разберемся, почему оно важно для 3d художников. Начнем с общего обзора, разберемся с его происхождением и в итоге подойдем к более конкретным техническим моментам, также мы пройдемся по основным текстурным картам, так как они, по сути, являются самой важной частью PBR рендера.

Понятие PBR

Оно расшифровывается как Physically Based Rendering - физически корректный рендер, или, иначе говоря, рендер основанный на физике поведения света и его взаимодействия с материалами. Если говорить простыми словами, то это способ отображения графики при помощи расчета и моделирования падения, отражения и преломления света в реальном времени, как это было бы в реальном мире.

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

CGitems.ru_PBR_1.jpg Максимально наглядное представление луча света - на примере видно, что имеется источник света, или “точка старта лучей” и, собственно, сам пучок света.

История PBR

Работа над физически точной визуализацией началась в 1980 годах. Преимущественно она велась в Корнельском университете (Cornell University, США). В 2004 году исследователи Мэтт Фарр (Matt Pharr), Грег Хамфрис (Greg Humphreys) и Пэт Ханрахан (Pat Hanrahan) издали книгу под названием «Physically Based Rendering», тем самым дав толчок распространению как понятию, так и самой технологии. По словам авторов эта книга «описывает как математическую теорию современной фотореалистичной системы рендеринга, так и её практическую реализацию.

Идеи и программное обеспечение в этой книге показывают, как создавать и использовать полнофункциональную систему рендеринга, способную создавать потрясающие образы». Эта книга является фундаментальным трудом в области компьютерной графики и принесла авторам ряд наград за достижения в области создания спецэффектов. Отдельно стоит выделить Пэта Ханрахана, так как он в целом является крупным деятелем в области компьютерной графики, был одним из первых сотрудников Pixar, имеет немало наград за развитие компьютерной графики и связан с уже знакомым нам Эдом Катмуллом (статья про топологию). Как видите, мир компьютерной графики весьма тесен.

CGitems.ru_PBR_2.jpg Пэт Ханрахан

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

Принципы работы PBR

Джо «EarthQuake» Уилсон - специалист из Marmoset и автор статей на polycount (и не только) утверждает, что PBR это скорее идея, чем набор строгих правил. Но при этом эта идея имеет некоторые конкретные примечания.

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

CGitems.ru_PBR_3.jpg Пример PBR-рендеринга из статьи Джо Уилсона на сайте Marmoset

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

Какие бывают материалы и в чем их принципиальная разница

Можно выделить две группы материалов - металлы и диэлектрики (материалы которые не проводят электричество). Говоря иначе - металлы и неметаллы. Металлы не пропускают свет, они только отражают его весь, или практически весь. Диэлектрики обладают таким свойством как диффузное отражение - лучи света проходят под поверхность материала и часть из них поглощается, а часть возвращается в виде отражения. В частности, это проявляется в блике этих материалов - у металла он будет цветной, а у диэлектрика - белый. Это подводит нас к таким понятиям как Diffuse (рассеивание) и Specular (отражение). Эти понятия часто можно встретить в работе с 3D моделями и это напрямую касается процессов текстурирования.

CGitems.ru_PBR_4.jpg Эта схема показывает принцип работы Specular - луч света падает на поверхность, нормаль поверхности задает угол под которым происходит отражение. Луч света отразится под углом противоположным углу падения.

На следующей схеме можно наблюдать как работает Diffuse - рассеивание света. Луч проникает под поверхность объекта и часть его отражается обратно. Это свойство материалов влияет на цвет частиц, которые будут рассеиваться наружу, от поверхности. Проще говоря - показывает нам его цвет. Это подводит нас к теме Diffuse color, иначе говоря Albedo.

Говоря простым языком - это цвет материала видимый глазу. Мы еще коснемся этой темы чуть позже. А пока поговорим об еще одном свойстве материалов, связанном с отражением света.

CGitems.ru_PBR_5.jpg CGitems.ru_PBR_13.jpg

Эффект Френеля

Этот эффект назван в честь французского физика Огюстена Жана Френеля. Он является одним из создателей волновой теории света.

CGitems.ru_PBR_6.jpg Огюстен Жан Френель

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

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

CGitems.ru_PBR_7.jpg

Первое - на всех материалах отражение будет максимальным на краях. То есть они будут вести себя как идеальное зеркало вне зависимости от типа материала.

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

CGitems.ru_PBR_8.jpg На схеме, взятой с сайта Marmoset видно, что два материала - резина и хром, на старте (от центра) имеют разные значения базовых отражений, но к краю это значение практически одновременно начинает стремиться к 100% отражению.

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

И еще одно примечание - эффект Френеля становится менее заметным при увеличении шероховатости поверхности.
Давайте сделаем основной вывод - при наличии эффекта Френеля края объектов будут наиболее яркими, так как буду отражать максимум света.

Translucency и Transparency (просвечиваемость и прозрачность)

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

Хороший пример - кожа.

CGitems.ru_PBR_9.jpg В случае с прозрачностью все понятно - в этом случае диффузия материала будет еще ниже и свет практически полностью будет проникать через него. Например, как через стекло.

Energy Conservation (Закон сохранения энергии)

Отражение и диффузия это, по сути, противоположные понятия, как мы уже поняли из раздела про металлы и диэлектрики, но при этом они зависимы друг от друга. Свет должен проникнуть под поверхность материала, чтобы подвергнуться диффузии и частично отразиться, показав нам цвет материала (в случае с диэлектриком). Этого не произойдет, если он будет отражен практически полностью без проникновения под поверхность (в случае с металлом). По закону сохранения энергии количество отраженного света не может превысить количество поглощенного. Опять же, звучит достаточно сложно, благо, в современных программах вроде Marmoset Toolbag существуют автоматизированные средства контроля таких параметров.

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

CGitems.ru_PBR_10.jpg CGitems.ru_PBR_11.jpg CGitems.ru_PBR_12.jpg CGitems.ru_PBR_14.jpg

Microsurface (микроповерхности). Roughness

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

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

CGitems.ru_PBR_15.jpg На примере выше видно, что свет падает под общим углом, но от поверхности отражается хаотично из за ее шероховатости. CGitems.ru_PBR_16.jpg На этом примере видна разница блика. Слева у нас идеальный пластик только что с завода, обычно такой гладкости вы не встретите ни в реальном мире, ни в игровом. Справа - тот же пластик, но с присвоенным числовым значением Roughness. Далее мы коснемся того, как это будет выглядеть при применении текстурной карты Roughness. А еще присмотритесь к краям - на идеально гладком пластике четко виден эффект Френеля. На шероховатом пластике он тоже есть, но при этом он тоже размыт и не так заметен.

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

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

Методы текстурирования

Их существует два - более старый (но он все равно применяется в некоторых случаях и адаптирован для PBR), и более актуальный, с которым вы будете сталкиваться чаще. Определяются они настройками свойств материалов и их сочетанием. А их применение в работе обычно диктуется условиями и особенностями конкретного проекта.

Первый, это метод Specular/Glossiness. В работе с ним используются 3 текстурные карты, которые определяют следующие параметры - Diffuse (рассеивание света, цвет поверхности материала), Specular (отражаемость материала), Glossiness (гладкость материала).

Стоит оговориться, что такой набор карт применялся в текстурировании “до PBR поколения” и подразумевал ручную настройку каждого параметра с ориентиром на референсы и художественное видение.
В PBR такой набор текстур работает немного иначе и мы рассмотрим этот метод именно в разрезе PBR. И на деле здесь все достаточно просто - любой материал имеет конкретные значения для озвученных параметров. И в современных реалиях для их настройки существуют калибровочные таблицы.

CGitems.ru_PBR_17.png Это пример калибровочной таблицы от Quixel. Как видите, в ней есть много разных материалов, в том числе базовых. Также в ней есть три параметра - Albedo, Microsurface и Reflectivity. И каждый из них соответствует параметрам материала.
  • Albedo = diffuse (диффузия света)
  • Microsurface = glossiness (гладкость поверхности)
  • Reflectivity = specular (отражаемость света)

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

Второй метод, это Metalic/Roughness. Он работает с параметрами Base Solor (это базовый цвет материала, и он имеет характерную для метода особенность, о которой мы поговорим чуть ниже), Metalic (обозначение металл/неметалл), Roughness (уровень шероховатости материала).

Примечание: текстуры Roughness и Glossiness, это одна и та же текстура с инверсией. Шероховатость и гладкость соответственно.

Особенность этого метода заключается в том, что в нём мы задаем свойства материалов прямыми значениями, без каких либо калибровок. По сути, мы задаем значение металл/неметалл при помощи Metalic. 1 = металл, 0 = неметалл.

Стоит оговориться, что бывают ситуации, когда применяются промежуточные значения, но в этот раз мы не станем их касаться, так как наша задача понять сам принцип работы.
И вот здесь будет главное отличие этого метода - от параметра Metalic зависит то, как работает Base Color. Если ваш материал является металлом, то Base Color будет отвечать за его параметр отражаемости (по аналогии со Specular из предыдущего пайплайна). Его настройки будут отвечать за силу и интенсивность отражения света, а также за оттенок материала.

Если ваш материал является неметаллом, то Base Color будет отвечать за его параметр Diffuse - силу и цвет рассеянного света. То есть, по сути, параметры Base Color и Metalic являются созависимыми и именно их сочетание, вкупе с параметром шероховатости дает нам финальный вид объекта.

Из всего этого можно сделать такой вывод - все материалы по своей природе имеют одинаковые наборы параметров, которые мы довольно подробно рассмотрели в начале, а методы текстурирования влияют на то, как мы ими управляем. Если вы читали внимательно, то вероятно заметили, что в разделе про закон сохранения энергии примеры приводились именно на параметрах Glossiness/Diffuse.

CGitems.ru_PBR_18.jpg Marmoset Toolbag

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

Текстурные карты

Теперь самое время пройтись по текстурным картам и немного поговорить о том в чём их суть. Рассмотрим на примере Metallic/Roughness. Это будет комплект карт характерный для этого метода, часть этих карт мы получаем в результате текстурирования, часть карт мы создаем для процесса текстурирования.

От того что мы выбрали именно Metallic/Roughness не изменится суть PBR, просто мы будем разбираться на конкретном примере, с которым вы почти наверняка будете сталкиваться чаще и который более распространен в индустрии.

CGitems.ru_PBR_19.jpg Пример стандартной тестовой модели в программе Substance 3D Painter.

Карты получаемые в результате текстурирования

Справедливости ради стоит отметить, что эти карты мы можем получить в результате запекания, но это тема для отдельного разговора. По этому берем за условие, что идет стандартный процесс - запекание с High-Poly на Low-Poly и дальнейшее текстурирование в Substance 3D Painter по стандарту PBR Metalic/Roughness с экспортом готовых текстур.

Albedo

Для начала давайте условимся с определениями - в работе вы будете в равной степени встречать понятия Albedo, Diffuse color и Base Color. По большому счету всё это одно и тоже - базовый чистый цвет материала. В случае с картами давайте остановимся на понятии Albedo.

Выше, в разделе про металлы/неметаллы, мы упоминали такое понятие как Diffuse Color - это цвет материала, который отображается после рассеивания света. Как мы уже поняли - в случае с Metalic/roughness он контролируется сочетанием параметров Base Color и Metalic. Собственно, результатом этой работы и будет карта Albedo.

В работе с Albedo стоит придерживаться пары принципов - нельзя уходить в верхние или нижние значения цвета. Лучше остановиться на значениях приблизительно между 20 и 80 процентов. Также обычно в природе не бывает чистых цветов - любой цвет имеет оттенок. Это тоже стоит учитывать.

CGitems.ru_PBR_20.jpg Так выглядит карта Albedo и её отображение на объекте. Как видите, на ней отсутствует что либо, кроме цветов, при этом мы можем видеть чёткие оттенки каждого пятна, базовый цвет металла, ржавчины и.т.д. Это важная карта и от того, насколько качественно вы её проработали будет зависеть как минимум 60-70 процентов финального вида модели.

Metalic

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

CGitems.ru_PBR_21.jpg На деле с этой картой все достаточно просто - важно с самого начала правильно выставлять настройки для разных материалов и участков, сводить их с параметрами Base Color и тогда все будет отображаться корректно.

Roughness

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

CGitems.ru_PBR_22.jpg Черный цвет в ней будет обозначать более гладкие участки, белый - шероховатые. Промежуточные оттенки будут указывать разность значения шероховатости.

Как уже говорилось ранее - Roughness и Glossiness это по сути одна и таже карта, просто в инверсии, так как они в конечном итоге выполняют одинаковую функцию.

Собственно, три эти карты - результат работы с PBR Metalic/Roughness. Чаще всего вы будете получать подобный результат после текстурирования и экспорта готового результата. В статье про запекание мы упоминали, что есть еще несколько текстур помимо карты нормалей и карты АО, которые нужны для дальнейшей работы над моделью. Эти карты имеют прямое отношение к PBR текстурированию. Давайте немного поговорим о них.

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

CGitems.ru_PBR_30.jpg Уже знакомый нам список карт из Marmoset Toolbag. По нему и пойдём

Normal map

Эта карта является основной и важной, так как без неё мы не получим финальный результат, раз речь снова пошла про запекание, то её стоит коснуться ради полноты картины. Мы уже разбирали как она работает в статье Average Normal и просто напомним, что это карта направления нормалей поверхностей, которая помогает движку корректно распределять свет по поверхностям Low-Poly с учетом геометрии High-Poly. В работе с PBR она поможет нам в текстурировании модели с учетом особенностей ее поверхностей, а движок сможет корректно отобразить внешний вид модели.

CGitems.ru_PBR_23.png

World space normal (Normals object)

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

В PBR текстурировании она применяется как удобный инструмент для распределения текстур по поверхности объекта, с учетом его топологии. То-есть если у нас есть, допустим, столб, то из карты WSN можно сделать маску для текстуры направленной от дна вверх и изобразить грязь и брызги свойственные подобным объектам находящимся на земле. Либо покрутить направление и отображение текстур в генераторах, которые предлагает нам Substance 3D Painter.

CGitems.ru_PBR_28.png CGitems.ru_PBR_29.jpg Присмотритесь к направлению света. Если вы уже ознакомились с темой нормалей, то увидите что принцип здесь такой же, как в привычной нам карте нормалей объекта

Position map

Это градиентная карта, растяжка градиентов в которой берёт направление по осям модели. Она также полезна как инструмент текстурирования, так как с её помощью можно быстро задать нужное направление текстуры, которую вы накладываете на объект, так же как в случае выше.

Отличие будет заключаться в том, что эта карта не учитывает топологию объекта, только его оси. В Substance 3D Painter многие генераторы работают в том числе с этой картой, либо с её помощью можно сделать маску. Эта карта также работает с каналами RGB по точно такому же принципу - на каждом канале свое направление.

CGitems.ru_PBR_26.png CGitems.ru_PBR_27.jpg Как видите в целом тоже самое, но не совсем - присутствует только плоскость, без деталей, соответственно они не учтутся при текстурировании через эту карту

Curvature map

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

В Substance 3D Painter есть ряд инструментов непосредственно для работы с картой Curvature. Она черно-белая и суть её в том, чтобы за счет яркости пикселей показать перепады высоты поверхностей. Чем ближе пиксель к белому - тем он выше и наоборот. Серый цвет - это плоскость, среднее значение.

CGitems.ru_PBR_24.jpg Этот пример curvature взят с сайта Marmoset для большей наглядности

Thickness

Это карта толщины поверхностей. Более тонкие области создают яркие значения, а более толстые - темные. Ранее мы говорили о таких вещах как Translucency и Transparency (просвечиваемость и прозрачность) - эта карта имеет прямое отношение к ней. Она нужна в работе с материалами, которые имеют подповерхностное рассеивание света (например, человеческая кожа), за счет распределения толщин на них будет задано корректное и плавное распространение света внутри материала. Также с ее помощью можно сделать высветление альбедо по тонким участкам модели.Это более специфичная карта, и может не так часто пригождаться, особенно на простых объектах. Но в принципе, беря во внимание ее свойства, иногда ее можно применить чтобы дополнительно поработать с яркостью отдельных элементов. На примере с сайта Marmoset видно довольно четкую разницу между объектами и принцип распределения.

CGitems.ru_PBR_31.jpg

Ambient occlusion

Возможно вы уже сталкивались с этим понятием, оно довольно распространено в сфере графики для игр. По сути это “самозатенение”, или “контактное затенение” объекта. На стыках элементов, на углублениях, во всех участках куда попадает меньше рассеянного света начинает работать Ambient Occlusion. Эта текстура черно-белая и здесь все просто - темные участки это затенение, светлые - плоскость. Помимо того что она сама по себе улучшает внешний вид модели, ее также можно использовать как инструмент текстурирования. Ниже представлен пример карты AO. Это кирпич с сайта Quixel. На нем видно, что затенение будет работать на швах между кирпичами, а также на сколах и трещинах - всех участках куда по какой то причине не попадает весь свет падающий на модель. Соответственно, например, он может помочь вам распределить пыль по углублениям модели.

CGitems.ru_PBR_25.jpg

Итак. Медленно но верно мы разобрали весьма громоздкую тему и самое время подвести итоги.

Важно понимать, что сама по себе технология PBR это очень мощный и серьезный инструмент, который применяется в разных сферах компьютерной графики. Мы разобрались с тем, откуда она взялась и в чем заключаются ее основные принципы. Мы разобрались с важной темой того, какими путями происходит рендер материалов и на чем он основан. Это помогло нам лучше понять на чем держатся процессы текстурирования моделей для игр. А разбор основных карт помог нам разобраться, как начать текстурировать и как сделать этот процесс более удобным, а результат - более качественным. Это большой пласт информации и польза от него будет целиком зависеть от того, насколько хорошо вы разберетесь в аспектах PBR связанных с моделями для игр и насколько хорошо будете понимать смежные темы, такие как топология, запекание и.т.д. Все эти темы идут рука об руку и их совокупность полностью определяет финальный вид модели. Если эта статья подкинула вам больше поводов для чтения, изучения и практики, если она показала вам какие то моменты, которые вы не учитывали раньше - прекрасно, значит у вас все получится.

CGitems.ru_PBR_32.jpg
Ваша заявка отправлена!
Если во входящих на почте: нет письма, проверьте папку спам или напишите нам в телеграм