Gamedev Андрей Верещагин
15 472

Как происходит рендер кадра в Shadow Fight 3

Обработка окружения и одежды персонажей.

В закладки
Аудио

Ведущий технический художник Banzai Games Роман Терский написал для DTF колонку, в которой рассказал о том, как происходит отрисовка кадра и устроены материалы для персонажей в мобильной игре Shadow Fight 3. Кроме того, он раскрыл небольшие хитрости в настройке окружения.

Shadow Fight 3 — игра в жанре файтинг-RPG, разработанная на базе движка Unity3d. Релиз проекта состоялся на iOS и Android в ноябре 2017 года, и с тех пор суммарное количество установок игры превысило 50 миллионов.

Для охвата столь широкой аудитории командой разработки была выполнена большая работа по оптимизации игры, и в результате проект работает при 60 кадрах в секунду на многих современных устройствах со средней производительностью.

Критики и игроки часто отмечают визуальную составляющую Shadow Fight 3. В этой статье я предлагаю вам заглянуть «под капот» игры и узнать, как нам удалось достичь такого качества.

Рендер кадра

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

Во время рендера кадра игры для каждой статической группы объектов, объединённых одним материалом, Unity запускает вызовы отрисовки (Draw Call) и накладывает их друг на друга. Каждый Draw Call требует затрат ресурсов CPU, поэтому важным этапом оптимизации является уменьшение количества этих вызовов. Нашей целью было минимизировать этот показатель до 100 вызовов на каждый кадр игры в среднем.

Процесс рендера одного кадра

Первым этапом рендеринга в Shadow Fight 3 является отрисовка динамических теней персонажей и Glow-эффектов для светящихся элементов на доспехах и оружии игроков.

Оба этих процесса имеют свои особенности и их стоит разобрать подробней.

Тени

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

Результат отрисовывается в виде альфа-текстуры, которая заменяет текстуру с рендером предыдущего кадра в динамическом материале объекта ShadowReciever. Такой подход позволяет избежать необходимости рассчитывать реальные тени и отрисовывать их на всех моделях локации, что заметно сказалось бы на общей производительности.

Область ShadowReciever

В рассматриваемом кадре на этот процесс ушло 20 вызовов отрисовки.

Glow

Процесс создания эффекта свечения на доспехах и оружии персонажей схож с процессом создания динамических теней. Вокруг модели со светящимися элементами создается куб BlurCube, на который каждый кадр проецируются Glow-эффекты, исходя из информации, хранящейся в синем канале RGB-текстуры материала этого объекта (то есть синий канал выступает в роли «маски» для проекции свечения —подробнее об этом ниже, в разделе про материалы).

Затем применяется размытие и информация сохраняется в виде альфа-текстуры, которая заменяет текстуру с результатом рендера предыдущего кадра в динамическом материале BlurCube.

BlurCube

В нашем кадре на этот процесс ушло 15 вызовов отрисовки, плюс ещё два на размытие эффекта.

Отрисовка мешей

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

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

UI

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

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

В сумме на рендер финального кадра игры потребовалось 92 вызова отрисовки.

Как устроен материал доспеха персонажа

Для создания материала доспеха персонажа используются текстуры с разрешением 512х512: Diffuse, RGB-маски, MatCap, дополнительная Diffuse-карта для теневой формы, а также небольшая шумовая текстура MorphMask, используемая для создания эффекта перехода персонажа в теневую форму.

И если с Diffuse-картой всё стандартно (это просто текстура самого доспеха), на остальных остановимся поподробней.

RGB-текстура масок

Так как RGB-текстура условно состоит из трёх цветовых каналов, заданных числами от 0 до 1 для каждого пикселя, её удобно использовать для хранения различных данных о материале в каждой конкретной точке UV-развёртки объекта.

В нашем случае в каналах RGB-текстуры (маски) содержится информация для следующих процессов.

  • Red (красный канал) указывает на то, какие элементы материала будут менять свой цвет, в случае если в бою участвуют противники в одинаковых доспехах (мы пользуемся этой системой, чтобы игрок не путал своего персонажа с оппонентом; определённые части доспеха, заданные в канале Red, перекрашивается для оппонента в альтернативный цвет, который был задан художником отдельно).
  • Green (зелёный канал) призван указать, к каким элементам доспеха применяется текстура MatCap для придания эффекта металлической поверхности, а также силу воздействия этого эффекта (чем светлее, тем сильнее металлический блеск).
  • Blue (синий канал) содержит в себе информацию, к каким деталям будет применен Glow, создающий эффект светящейся поверхности.

MatCap

С целью создания эффекта отражения для металлических элементов доспеха и оружия персонажей для каждой локации создается уникальная MatCap-текстура с разрешением 512х512, за основу которой берется обработанный скриншот локации со всеми особенностями ее структуры и освещения.

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

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

Теневая форма

При переходе персонажа в теневую форму Diffuse-текстура материала заменяется дополнительной, созданной специально для теневой формы.

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

Освещение локаций

Всё освещение и тени на локации запечены в lightmap-текстуры с разрешением 2048х2048, что позволяет исключить необходимость рассчитывать освещение в реальном времени и существенно увеличивает производительность.

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

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

В качестве альтернативы для каждой локации мы храним отдельный, уникальный градиент shadowing map: по сути, это текстура с разрешением 1024х1, представляющая из себя градиент, основанный на скриншоте локации и передающий степень затенения в каждой ее части.

Карта shadowing map

При перемещении персонажа по арене цвет его доспеха после применения направленного освещения домножается на цвет градиента, соответствующий его текущему положению на локации. Таким образом, в затененных местах применяемое освещение слабее, чем на открытых.

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

Динамические эффекты арен

Немаловажную роль в «оживлении» локаций Shadow Fight 3 играют FX-эффекты и динамические объекты, такие как флаги, шевелящаяся листва на деревьях, колышущаяся трава и так далее.

FX

Большая часть FX-эффектов (огонь, дождь, солнечные лучи и прочие) в SF3 выполнены по принципу применения анимированного материала к статическим низкополигональным моделям. Однако есть и эффекты, построенные на системе частиц.

Динамические объекты

На локациях SF3 есть два типа динамических объектов: физические — приводимые в движение посредством симуляции ткани и применения к ним импульса, имитирующего порывы ветра, а также 3D-модели с вертексной анимацией. Для таких объектов создается зацикленный анимационный трек, приводящий в движение вертексы 3D-модели.

Вертексная анимация листвы
Симуляция ткани на флагах

Отражения

Локации в SF3 построены по принципу театральной сцены. Подобно зрителям в театре, камера в игре направлена лишь в одном направлении и никогда его не меняет. Объекты окружения также выполнены по принципу театральных декораций: их существует ровно столько, сколько игрок может увидеть. По бокам и за камерой ничего нет, а все модели имеют геометрию лишь в тех местах, которые могут попасть в зону видимости камеры.

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

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

В случае, если отражаемый объект находится на достаточном отдалении и детализация отходит на второй план, вместо дубликата устанавливается Plane с текстурой на основе отзеркалированного по оси Z скриншота отражаемой поверхности. Такой подход не только повышает производительность игры, но и даёт очень реалистичный результат.

Вопрос оптимизации рендера под мобильные устройства сейчас актуален как никогда. То, что вы увидели в данной статье, — это проработанные нами решения конкретно под проект Shadow Fight 3. В настоящее время компания Banzai Games начала разрабатывать две новых игры, в которых мы постараемся сделать графику ещё лучше, применив как текущие наработки, так и добавив что-то новое.

Надеюсь, вам было интересно! Если у вас есть комментарии и дополнительные вопросы, пожалуйста, задавайте их в комментариях к статье.

#мобайл #unity #опыт #long
{ "author_name": "Андрей Верещагин", "author_type": "editor", "tags": ["long","unity","\u043e\u043f\u044b\u0442","\u043c\u043e\u0431\u0430\u0439\u043b"], "comments": 42, "likes": 170, "favorites": 119, "is_advertisement": false, "subsite_label": "gamedev", "id": 37601, "is_wide": false, "is_ugc": false, "date": "Thu, 24 Jan 2019 19:12:53 +0300" }
{ "id": 37601, "author_id": 22254, "diff_limit": 1000, "urls": {"diff":"\/comments\/37601\/get","add":"\/comments\/37601\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/37601"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954 }

42 комментария 42 комм.

Популярные

По порядку

Написать комментарий...
38

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

Ответить
2

dtf вроде и был про это изначально, жаль в сторону повело

Ответить
–2

Да ладно, одно другому не мешает. К тому же, каждый скандал или хайповые темы - это всегда на заметку маркетологам и пиарщикам. Плюс тема для шуток)

Ответить
5

Спасибо за статью. Очень круто, что разработчикам удалось добиться ~100 draw calls на кадр

Ответить
2

Непонятно правда, почему оружие для правой/левой руки, судя по гифке, рисуется разными draw call'ами. Голову в закрытом шлеме можно и не рисовать. Деревья тремя draw call'ами тоже странно. Хотя были, видать, причины.

Ответить
3

на дроуколы бьет сама юнити когда объекты спорят по zorder с другими объектами.
Оба топора перекрываются скиннед мешем персонажа поэтому вынесены в отдельные дроуколы. Голову в шлеме можно не рендерить только если шлем закрытый, для этого тех артистам придется помнить про эту настройку и не забывать её расставлять, слишком большое усложнение ради 1го не особо тяжелого дроукола.

Ответить
0

Деревья вроде статичные, они в static batching должны попадать. Про разбивку из-за перекрытия или z-order'а первый раз слышу. И в документации об этом не слова. А то как-то даже свой батчер писал.

Ответить
0

А еще скорее всего у топоров динамический батчинг не отрабатывает потому что в них больше 180 вертексов

Ответить
–1

добиться 100 draw calls

на игре с 1 шейдером и 1 материалом/текстурой

У них в сцене объектов меньше, чем draw calls. У них точно 100 разных материалов?

Ответить
7

ты можешь из 2х материалов и одного куба сделать 100 дроуколов просто расположив объекты один за другим.К тому же если у тебя объект не подходит под параметры батчинга то каждый его инстанс будет отдельным запросом отрисовки. В гифке пример как 2 материала и один куб превратились в 6 запросов на отрисовку

Ответить
1

В статике всё лучше. Вообще, если сильно заморочиться, то каждого персонажа можно в draw call уложить с оружием и бронёй. Вчалале текстуры отрендерить в одну, uv перемапить, меши оружий запихнуть в skinned и на всё общий шейдер с настройками.

Ответить
3

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

Ответить
0

А чем принципиально хуже использовать лайтпробы для шейдинга, вместо теневого градиента ?

Ответить
6

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

Ответить
0

Кстати, а субуго в теории - можно ли подобным образом использовать лайтмапу?
Что бы шейдить динамические объекты без лайтпроб не только в одной плоскости (как в SF3) ?

Ответить
3

Я как то проводил такие эксперименты. Можно шейдить не в одной плоскости, если по особому упаковать данные в текстуру. Можно вообще 3д карту освещения в одну текстуру запихнуть, но распаковка данных ложится на плечи видеокарты что ничего хорошего не даёт в итоге.

Лайтмап юнитёвский юзать не выйдет придется свой использовать.

Если же хочется просто проекционное затенение то это гораздо проще. + Есть хак небольшой. Операция домножения цвета на тень попиксельная, но можно попробовать её сделать повертекстной что добавит прироста производительности. К сожалению сэмплировать текстуру в вертексном блоке позволяет только OpenGl ES 3 и выше. Так что можно написать 2 шейдера и в случае если повертексное сэмплирование текстуры не работает то фолбэчить к попиксельному.

Ниже кинул пример проекционного затенения. Лайтмап - это проекция теней на плоскость xz.

Ответить
1

Шейдер сферы приводит координаты вертексов к координатам лайтмапы, сэмплирует её и записывает цвет в вертекс, позднее в пиксельном блоке происходит домножение на вертексный цвет.

Ответить
0

Огонь!

Ответить
0

Спасибо за инфу, да, совсем за был за батчинг.

Ответить
2

В лайтпробах сложная математика, они нужны когда интенсивность света разная с разных направлений. А тут одна выборка и одно умножение. И выглядит нормально.

Ответить
1

А вообще по самой игре как, кто играет здесь в этот файтинг? Есть такие кто мобильные игры не любит, но про эту игру что то сказать интересное сможет или это по сути такой же плати много и играй более менее

Ответить
1

Я играл на старте, когда она ещё только вышла. Там было пару глав буквально. Игра расчитана больше на дроч/донат, чем на скилл.
Потому что в какой-то момент ты так или иначе проходишь достаточно боёв, а следующий уже показывается как "НЕВОЗМОЖНЫЙ!". И чтобы его пройти, нужно либо играть как боженька, не пропуская ни одного удара (который тебя просто заваншотит) и в течение получаса нудно тыкая оппонента (потому что твой дамаг будет ничтожен, ты будешь снимать по паре процентов хп ему), либо переигрывать предыдущие мисии или вроде того, собирая ресурсы (я уже слабо помню, что там было, но смысл такой) для апгрейда своего оружия.
При этом тебе может подфартить и ты выбьешь, например, легендарное оружие намного сильнее текущего и ближайшие 3-4 боя пролетишь, т.к. будешь складывать оппонентов в 2-3 удара.

Ответить
2

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

Ответить
–1

статья не про это

Ответить
0

И что? Человек вопрос задал. Или мы теперь если "статья не про это", то будем игнорить всех? Тогда процентов 80 комментариев нужно удалить с сайта.

Ответить
–1

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

Ответить
0

Как я тебя понимаю, играл в третью, но после какого-то момента, у меня прям сгорело очень сильно, когда тебе просто дают врагов, которые тебя превосходят во многом. Отдельная песня ещё есть про ранкед, когда тебя дают врага на 1000 очков сильнее и тд, в один из таких боя я со злости ударил телефон об стену и ушатал тач пад на нём) После этого в подобные игры не играю)

Ответить
–1

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

Ответить
2

Хорошая статья.

Ответить
2

Nekki games are great but the greatest thing in your all games is music

Ответить
2

Потрясающе, вы молодцы.

Ответить
1

Будет здорово, если напишите более подробную о создании эффектов на сцене горящей деревни.
И еще на гифке у вас UI рисуется в один ДК. Это на самом деле так? Потому что в uGUI Text и Image не батчатся. Если использовали не uGUI, то тогда что?

Ответить
2

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

Ответить
1

Очень интересная статья, спасибо. Хотелось бы уточнить, почему нельзя было программно обьединить все отдельные части персонажа в одну skinned mesh и рендерить его как один обьект? Ортографической камере так же будет проще рендерить тени. Это в незначительной мере нагрузит CPU но разгрузит GPU, что для андроид девайсов весьма критично. Можно даже по отдельной маске дискардить отрисовку прикрытых пикселей. + при таком подходе можно было бы использовать лайт пробы для персонажей, тем самым перекрыть затенение по вертикали (это добавит лишь 2 draw calls, так как будет использоваться лишь для двух персонажей). Так же хотелось бы узнать, почему применяется симуляция ткани и вертексная анимация, а не заранее отрендеринная анимация на статичном плейне (можно даже с подмешиванием цвета для флажков и тд.). Что касается теней - очень хорошая идея, обязательно возьму на заметку.

Ответить
1

По поводу объединения всех частей персонажа в одну skinned mesh, выше Иван Кийко написал, на мой взгляд, очень правильно: сохранение нескольких DC в этом случае не стоит затраченного на написание такого функционала времени. По поводу заранее отрендеренной анимации на плейнах, этот вариант не очень подходящий, так как камера, во время движения по сцене, берет небольшой угол и это может выглядеть не достаточно реалистично (в случае симуляции ткани для флагов). Однако, это неплохая идея в качестве замены вертексной анимации :)

Ответить

Комментарий удален

Комментарий удален

Комментарий удален

0

Олды из некки тут?

Blue (синий канал) содержит в себе информацию, к каким деталям будет применен Glow, создающий эффект светящейся поверхности.

Синий канал же использовался для маски цвета кожи?

Ответить
0

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

Ответить
0

Молодцы! Даже что то из моих поделок осталось, греет душу.

Ответить
0

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

Ответить
0

Хорошая статья и игра выглядит хорошо, но на деле это донатный кусок с прокачкой лутбоксами.

Ответить
0

2-я часть топовая, 3-я донатная помойка

Ответить
0

Привет у меня есть вопрос.Когда будет возможность вступить в клан в новом обновление shadow fight 3 можно ли будет сражаться с одноклановцами через испытание?

Ответить
0

Прямой эфир

[ { "id": 1, "label": "100%×150_Branding_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox_method": "createAdaptive", "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfl" } } }, { "id": 2, "label": "1200х400", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfn" } } }, { "id": 3, "label": "240х200 _ТГБ_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fizc" } } }, { "id": 4, "label": "240х200_mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "flbq" } } }, { "id": 5, "label": "300x500_desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "ezfk" } } }, { "id": 6, "label": "1180х250_Interpool_баннер над комментариями_Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "ffyh" } } }, { "id": 7, "label": "Article Footer 100%_desktop_mobile", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjxb" } } }, { "id": 8, "label": "Fullscreen Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjoh" } } }, { "id": 9, "label": "Fullscreen Mobile", "provider": "adfox", "adaptive": [ "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fjog" } } }, { "id": 10, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "label": "Native Partner Mobile", "provider": "adfox", "adaptive": [ "phone" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyc" } } }, { "id": 12, "label": "Кнопка в шапке", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fdhx" } } }, { "id": 13, "label": "DM InPage Video PartnerCode", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox_method": "createAdaptive", "adfox": { "ownerId": 228129, "params": { "pp": "h", "ps": "clmf", "p2": "flvn" } } }, { "id": 14, "label": "Yandex context video banner", "provider": "yandex", "yandex": { "block_id": "VI-250597-0", "render_to": "inpage_VI-250597-0-1134314964", "adfox_url": "//ads.adfox.ru/228129/getCode?pp=h&ps=clmf&p2=fpjw&puid1=&puid2=&puid3=&puid4=&puid8=&puid9=&puid10=&puid21=&puid22=&puid31=&puid32=&puid33=&fmt=1&dl={REFERER}&pr=" } }, { "id": 15, "label": "Плашка на главной", "provider": "adfox", "adaptive": [ "desktop", "tablet", "phone" ], "adfox": { "ownerId": 228129, "params": { "p1": "byudo", "p2": "ftjf" } } }, { "id": 17, "label": "Stratum Desktop", "provider": "adfox", "adaptive": [ "desktop" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvb" } } }, { "id": 18, "label": "Stratum Mobile", "provider": "adfox", "adaptive": [ "tablet", "phone" ], "auto_reload": true, "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fzvc" } } } ]
Узнавайте новости о мостах
Санкт-Петербурга первыми
Подписаться на push-уведомления