Рубрика развивается при поддержке
Gamedev
Netless
4307

FPS камера в SRP

На официальном YouTube канале Unity вышло видео демонстрирующее гибкость SRP на примере FPS камеры, которая не обрезает пересекающуюся геометрию игрока и сцены.

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

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

Пример демонстрирует отказ от дополнительной камеры, которая занимается отрисовкой только FPS оружия (рук игрока) и достижение того же результата путём настройки рендерера.

Может показаться, что речь идёт о чём-то страшном, но это не так. В примере используется LWRP.

Всего 3 простых шага:

  • Создать кастомный forward renderer
  • В Pipeline asset присвоить созданный в предыдущем шаге рендерер
  • В кастомном рендерере убрать слой оружия из Default Layer Mask и переопределить этот слой как Render Object в Renderer Features

Таким образом мы получаем возможность контролировать порядок отрисовки слоя и можем выбрать нужный нам проход визуализации (render pass).

Так же не забываем про frame debuger, который позволяет увидеть как рисуется сцена и отладить рендерер.

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

Зачем?

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

Во-вторых: реализация через стакинг камер не работает в srp.

Демо

Скачать файлы с видео можно здесь

Где же ручки?

На случай если кто не понял как именно сделать ручки поверх уровня, кратко на примере демо из поста:

Делаем два первых шага из статьи, потом отключаем слой рук в default layer mask, создаём два render object в features, присвоив им слой рук. Далее первому переопределяем глубину с условием greater, второму ничего не переопределяем и оставляем как есть.

Результат:

Музыка специально под улыбчивое настроение Дмитрия Широбакина :)

Материал опубликован пользователем.
Нажмите кнопку «Написать», чтобы поделиться мнением или рассказать о своём проекте.

Написать
{ "author_name": "Netless", "author_type": "self", "tags": [], "comments": 24, "likes": 46, "favorites": 87, "is_advertisement": false, "subsite_label": "gamedev", "id": 67568, "is_wide": false, "is_ugc": true, "date": "Tue, 03 Sep 2019 09:24:46 +0300", "is_special": false }
0
{ "id": 67568, "author_id": 116280, "diff_limit": 1000, "urls": {"diff":"\/comments\/67568\/get","add":"\/comments\/67568\/add","edit":"\/comments\/edit","remove":"\/admin\/comments\/remove","pin":"\/admin\/comments\/pin","get4edit":"\/comments\/get4edit","complain":"\/comments\/complain","load_more":"\/comments\/loading\/67568"}, "attach_limit": 2, "max_comment_text_length": 5000, "subsite_id": 64954, "last_count_and_date": null }
24 комментария
Популярные
По порядку
Написать комментарий...
2

Все это конечно замечательно, но как быть с разным FOV для рук и окружения? Основное преимущество, которое дают две камеры, это разные углы обзора: руки всегда в фиксированном (60-70), а окружение в том которое нужно (настройки которые выставляет пользователь + разные соотношения сторон экрана)

Ответить
0

1) Нажимаем на чекбокс Camera
2) Двигаем слайдер FOV
3) ...
4) Profit!!!

Ответить
0

Увы так не сработает. С изменением FOV для камеры пойдет второй пас рендера, с другим FOV. В таком случае весь смысл "оптимизации" пропадает.

Ответить
0

С изменением FOV для камеры пойдет второй пас рендера, с другим FOV

Вы это где такое увидели?

Ответить
0

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

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

Ответить
0

Скажите пожалуйста, как вы себе представляете рендер нормалей, глубины, теней, света и всего остального за один проход, но с двумя разными FOV?

В смысле? А с чего у нас должно что-либо меняться в работе светотени при изменении фова? Вы когда растягиваете\сужаете кончики глаз (как китаец) видите какие-либо изменения работы света\теней\отражений в реальной жизни?

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

Ответить
0

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

Ответить
1

Я как программист-шейдерист возмущен что Вы говорите на каком-то мордорском шейдерском, я не знаю что такое SRP и не посмотрев видео - не узнаю, зачем так делать?

Ответить
0

видео демонстрирующее гибкость SRP на примере FPS камеры,

которая не обрезает пересекающуюся геометрию игрока и сцены

Я конечно не специалист-шейдерист, но видео совсем про другое. Просто показывают как одной камерой рендерить, а не двумя :)

Ответить
0

Прочитайте официальное описание видео на ютьюб :)

Ответить
0

Мда... :)

Ответить
0

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

Ответить
0

Готово. Наслаждайтесь :)

Ответить
0

Сообщение удалено

Ответить
0

Я почему-то думал, что за все эти годы отрисовка "рук" на самом верхнем "слое" это какой-то стандарт, типа максимально оптимизированный и пердусмотренный без какой-либо второй камеры.

Ответить
0

Почему вы так думали?

Ответить
0

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

Ответить
0

Насколько мне известно, нет какого то одного расово верного решения. Погуглите, изучите вопрос, поймёте, что всё не так просто

Ответить
0

На мой дилетантский взгляд, проблема с вариантом с камерой была отнюдь не в ФПС - а в отсутствии взаимодействия с окружением - блики, тени, отражения - вот это всё. Проблема эта при чем на чистом С++ решается на раз, без костыля в виде отдельного рендер-таргета.

Ответить
0

Блики, тени, отражения прекрасно рендерились на дополнительной камере. Проблема была как раз в том, что после одного цикла просчёта и отрисовки графики, движок начинал по новой для следующей камеры.
А с помощью решения методом из статьи всё происходит в едином органичном потоке.
Есть конечно уникумы, которые всё равно делают отдельную render texture, рендерят в неё картинку из второй камеры и накладывают с помощью постпроцессинг шейдера... Но это уже не касается этой статьи.

Ответить
0

Для первого таргета мы отрендерили тени, отражение и наложили... Но там нет модели оружия - придется компоновать карты отражений и теней из двух таргетов ?

Ответить
0

Нет. Вообще, если говорить про built-in render pipeline, то у разработчика нет никаких возможностей врезаться в процесс рендеринга (постпроцессинг не считается). В этом пайплайне создавалась дополнительная камера, которая находилась в том же месте где и основная, но в отличии от основной, дополнительная рендерила один слой, в котором были руки. Все процессы просчёта света, теней, отражений и т.д. выполнялись как обычно, но в момент отрисовки, все пиксели, в которых небыло рук, рендерились как прозрачные. Иными словами, все вычисления кроме растеризации выполнялись как обычно. Не уверен, что это правильно так говорить, но мб будет понятнее. Собственно из-за всего этого и считалось, что использование нескольких камер одновременно имеет большой оверхед.

Далее уже юнити под капотом объединяла результаты работы в единую картину и выводила пользователю в окно.

Но это про старый пайплайн, а в статье рассказывается как сделать это же в новом.

Ответить
0

Тогда вообще прирост мизерный, если минимум 3 из 4-х рендеров (тени, отражение, преломление) остались как и были - ну разве что навесить на оружие и руки супермегапупер шейдера и полигонов свыше 100К.

Ответить

Прямой эфир

[ { "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": "Article Branding", "provider": "adfox", "adaptive": [ "desktop" ], "adfox": { "ownerId": 228129, "params": { "p1": "cfovz", "p2": "glug" } } }, { "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, "disable": true, "label": "Native Partner Desktop", "provider": "adfox", "adaptive": [ "desktop", "tablet" ], "adfox": { "ownerId": 228129, "params": { "pp": "g", "ps": "clmf", "p2": "fmyb" } } }, { "id": 11, "disable": true, "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" } } } ]