Так уже делают. Алгоритмы с разными настройками гоняются при движении и без движения. Ну вернее как, непосредственно детекция движения там есть не всегда (хотя иногда и это есть), обычно ориентируются на зафейленную репроекцию, это когда пиксель с прошлого кадра в новом кадре найти не могут. В таком случае обычно меняют силу пространственных фильтров и темпоральных. Усиливают пространственные (когда берут данные из соседних пикселей для расчета текущего, по сути размытие), ослабляют темпоральные (чтобы гоустинга меньше было). Это не полностью помогает, потому что почти любому рейтрейсовому эффекту для стабильности нужно кадров 30 истории (GI обычно сильно больше даже), поэтому когда истории нет, даже с хорошими денойзерами будет так себе выглядеть. Тормоза во время поворотов камеры обычно не из-за того что рейтрейсинг дорогой, а потому что окклюжн куллинг не работает для объектов, которые только-только появились во фрустуме, теневые каскады надо перерендеривать и т.д.
Уменьшать число сэмплов во время движения обычно не работает, потому что как я уже выше написал, вам нужно много сэмплов, чтобы это выглядело адекватно. Если при движении уменьшать их количество, то у вас на экране будет фестивать шума и гоустинга. Игроки видят обычно уже готовую отполированную игру, а в процессе разработки, пока свет до конца не поставлен, GI при движениях камеры (и особенно в катсценах) выглядит _настолько_ плохо, что вопрос "почему бы не сделать еще меньше сэмплов" отпадает сам собой.
Для примера можно взять ue5, поставить дефолтные high настройки в люмене поставить, сделать какую-нить сцену, где чисто непрямой свет и попробовать быстро полетать / поделать мини-синематики с катами. Результат скорее всего не понравится
Бывает, что компиляторы генерируют неэффективный код, это нормально. С шейдерными компиляторами это чаще происходит, потому что гпушная архитектура меняется быстрее чем цпушная, цпушные компиляторы стабильнее в среднем.
В _значимую_ разницу в кодогене между плойковским компилятором шейдеров и мелкософтовым я не очень верю если честно. Шейдера пока еще та область, где люди смотрят получившийся после генерации код, он пока еще довольно легко парсится глазами / профилировщиками, и очевидную неэффективную дичь довольно легко заметить и подправить исходник так, чтобы этой дичи не возникало. Особенно на консолях. На пк с этим сложнее, т.к. нет особо контроля над тем, как байткод в ису перегоняется, железок много разных.
Дизайн апи похож на вулкан потому что дизайн любого современного апи будет на него похож. Потому что дизайн всех современных апи похож друг на друга и плюс-минус отражает железо, под которое предназначен. nvn/gnm похожи на вулкан в той же степени, что и похожи на dx12 / metal. В тех местах, где консольные апи отличаются от пкшных, они отличаются от обоих десктопных аппи довольно сильно.
ни то ни другое не вулкан
Особо далеко не смотрел, но зашел в кп, получил 80-90 в индоре и 40-55 в аутдоре на похожих разрешениях без динамического скейлинга в зависимости от того, что на экране происходит. И это просто перемещение по городу, если перестрелку завязать, разница еще больше будет. Это конечно не 40 против 120, но разница все равно существенная.
Единственная в чём беседка опростоволосилась, это не равномерность графона. Потому что это не нормально, когда такая огромная разница в фпс-ах. Да и графон в игре тоже очень не равномерный.Это вполне нормально. Открытые локации почти всегда гораздо более требовательны. Условно, в коридоре надо нарисовать 4 стенки и 3 коробки, на улице террейн, растительность, 10 зданий, пару сотен пропсов и облака, эффективность куллинга очень низкая. Это можно выровнять повышенной детализацией в коридоре, запилив какую-нить коробку на полмиллиона треугольников (условно), но непонятно зачем, тем более что тогда эти коробки снаружи раскидать не получится.
ВК вынуждена хранить цельный нанит объект если игрок к нему подойдет вплотную
не вынуждена, у нанита статический пул памяти выделен под его работу. Если все кластеры на нужной детализации не влезают в пул, будут загружены более низкодетализированные кластеры. Цельный объект даже вплотную тоже хранить не надо, если ты вплотную находишься, то тебе нужны не все кластеры на макс детализации, а только те, которые к тебе ближе находятся.
С доводом что с инстансами модулей лучше, чем полностью уникальными мешами спорить не буду, но конкретно аргумент про видеопамять ну так себе. Система в целом концептуально похожа на виртуальные текстуры, с теми же плюсами и минусами
Изометрическая камера обеспечивает полтора объекта в кадре вообще без какого-либо куллинга. В рейтрейснутую сцену можно спокойно положить все объекты в радиусе метров 100 от персонажа и никаких проблем не будет. Катсцены которые не пререндеренные почти всегда в помещениях, а если в помещениях есть окна, то все скрыто туманом через 10 метров. Также изометрическая камера делает невозможным любой нормальный SSR (потому что отраженные лучи всегда идут либо в сторону камеры либо ортогонально камере, и пользоваться ими невозможно). В катсценах можно SSR включить, но непонятно зачем тогда вообще эту фичу делать, если она будет работать почти никогда.
Совершенно несравнимые вещи, из за вида, числа объектов в кадре, размера мира и кучи других вещей.
Изометрия меняет почти все.
Спорно. Как там правильно GG указали, в игре овердофига альфатестовой растительности, трассировка с альфатестом крайне больно бьет по производительности. При том что случай с водой в большинстве случаев вполне нормально обрабатывается через SSR. Ради одних только отражений на воде тратить ресурсы на сборку bvh для всех объектов и память на них - крайне спорное вложение времени и ресурсов. Заскаттеренную на гпу растительность добавлять в bvh штука тоже не самая простая.
Разница все-таки есть, трассировка SDF от трассировки треугольников сильно отличается по своей сути, по требованиям к памяти / вычислениям, детализацией геометрии, возможностями, артефактами и т.д. и т.п.
Честно, с юнити особо не работал, поэтому местную специфику не знаю. Вообще, если в общем говорить, а не конкретно про юнити, то зависит от целеполагания и бекграунда. Если до этого сталкивался с графическим программированием и от кода нет чувства паники - то писать в сырую шейдеры имхо лучше. Больше возможностей, больше понимания как оно будет работать и насколько тяжелый шейдер получается. Если работаете в команде, где возможно разделение труда, в том плане что есть люди с тех бекграундом которые пишут шейдера и есть люди с артовым беком, которые их используют, то ответ тот же самый.
Если с программированием опыта нет, и нет цели делать только оптимизированные по максимуму шейдера (например, прототипирование, ну или в игре контента настолько мало, что загрузить современное железо надо очень постараться), то шейдерграф отличное решение. Если потом предполагается, что художники сами должны уметь поправить шейдер, то тоже шейдерграф (хотя честно, в продакшен такое я бы не пускал, безотносительно того на чем шейдер сделан)
Но опять же я не знаю юнитевой специфики. НАпример, в том же анриле такого выбора почти нету, все материал шейдера будут в графе. Там можно произвольный hlsl код в ноду добавлять, но такого лучше по минимуму делать, потому что предполагаемые методы работы с движком это не поощеряют
В крайзисе не было pbr (_может быть_ есть в трешке, не уверен тут на 100%). Первая крупная игра с PBR это remember me, 2013 год. Наличие нормалмап и спекулярмап с глоссом еще не pbr. Да и нормалмапы и спекуляр мапы так то уже в думе были. Крайзис очень много вещей сделал первым, но ни pbr ни нормалмапы к ним не относятся
Могут. Люмен/нанит не поддерживаются, но игра не обязана их использовать. И то в целом, чисто _теоретически_ в прошлых версиях (до 5.1 точно) можно было включить и то и то на старых консолях после небольших твиков, просто работало плохо. Сейчас может уже не получится наверное, хз, давно с движком не работал
есть hlg, где регулируется. Но его в геймдеве как-то не очень активно используют, только для броадкастов, насколько мне известно
ну есть разница, тяжело работать потому что работа тяжелая, или потому что глаза выжигаются, которые у художников это чуть ли не главный орган. Просто современные пайплайны грейдинга предполагают делать основной грейдинг на HDR, но у них глаза не сменные
rgb там остается, игр со спектральным рендером пока не наблюдается особо. С физическими величинами тоже сложновато, rgb дружить с физ величинами сложно. Обычно там что-то отдаленно похожее, типа "задаем яркость в люменах/люксах белого света, но это не настоящие люксы, а что-то, что дает отдаленно похожие люксы, потому что в настоящей фотометрии работать неудобно будет".
Оффтопик: лучи добра тому, кто засунул редактирование комментариев в платную фичу
предупреждая сразу очевидный аргумент про пересветы и плохие мониторы - мониторы специальные профессиональные для hdr грейдинга за килотонны денег, консюмерские такие хрен найдешь.
И еще пример - лично слушал жалобы художников, что не получается мастерить изображение _всегда_ на HDR мониторах, потому что глаза устают, слишком ярко для офисных условий
10килонит в обычной комнате вечером выдавать на небе на постоянку как бы тоже глаза вытекут быстро
Это все верно и правильно, но окружение, в котором наблюдается изображение это тоже невероятно важно.
Стандарт HDR для кинотеатров, например, это 108 нит пиковой яркости (я про Dolby Cinema, которых пока не очень много, для SDR 48 нит стандарт кинотеатров). А есть еще, например, hlg oetf, которая вообще не фиксирует максимальную яркость. Потому что в кинотеатре ты можешь обеспечить dark surround, а в домашних условиях сложно.
В целом все сводится на мой взгляд к тому, что изображение это не проекция реальной сцены, и там не обязана быть та же яркость, потому что условия наблюдения отличаются. На картинах, написанных маслом тоже никакого hdr нет, но никто к ним претензии не кидает, что на картинах солнечных дней ничего разглядеть нельзя.
Я это не к тому, что HDR не нужен, но тема все таки сильно более комплексная, чем "давайте дадим мониторам яркость реальных сцен и все будет зашибись"
Есть подозрение, что на primary видимости с определенного момента рейтрейс может обойти растр. На гипердетализированной геометрии растр скалируется линейно от сложности сцены, лучи логарифмически. Иерархические лоды и хороший куллинг может снизить эффект (см. нанит), но оно не всегда работает как надо. Уже есть пара китайских исследователей, которые для рендера огромных плотных лесов думают использовать лучи вместо растра, по этой самой причине
Я могу слабо представить как такое возможно, если только ты не меняешь 3д игру на 2д)
Честно, мне лень придумывать примеры из воздуха, а с работы я их приводить не буду по очевидным причинам. Можешь не верить, если хочешь. Дальше пример с иерархиями в целом будет показателен.
Дык а какая разница жирный или не жирный если по итогу процессор просто будет бегать по виртуальным методам так или иначе? Минус кэш и опять же проблематично мультитредить. А значит рано или поздно это придётся оптимизировать.
Разница жирный или не жирный прямая, потому что от этого зависит сколько чего в кеш поместится. ECS компоненты размером больше кэшлайна (любая матрица) кроме потенциального префетча тоже особо ничего не выигрывают в плане кешей. Ну и я скорее хотел акцент сделать на виртуальных методах. Внезапно, динамический полиморфизм через виртуальные функции это не единственный способ делать что-то, есть девиртуализация, статический полиморфизм и т.д. Виртуальных методов уже лет 30 избегают в геймдеве по возможности, ничего кардинально нового тут нет.
Аргумент про мультитред более весомый, тут действительно сложно возразить. Но, скажем, если у вас в игре есть хорошо распараллеленный физ движок и рендер, то они и так вам все треды загрузят, и хоть вы параллельте игровую логику, хоть не параллельте, быстрее игра работать не станет, если вся логика отрабатывает за 16мс. На сетевых играх ровно так и будет например, потому что там обычно требование, чтобы логика на дедике в одном потоке работала. Есть куча проприетарных движков с хорошо распараллеленным рендером и физикой и однопоточным игромехом, которые работают не на ecs. Далеко не все игры в итоге упираются в производительность игромеха.
а дальше системы уже разберутся.Иерархия - это просто ещё один компонент на сущности (условный Parent или Child). Кому надо - прочитают их.
Системы надо в правильном порядке применять и зависимости между ними разрулить. А систем, трогающих трансформы - десятки (обычно это самый популярный компонент так то). Если резолвить по одной энтити за раз, то позиции всего в мире всегда согласованы. В ECS по умолчанию такого свойства нет, его надо обеспечивать. Когда запускать систему телепорта сущностей по мировым координатам? Другая система ведь может потом подвинуть уже телепортированную сущность. А если ее делать последней, то не получится в одном кадре, скажем, обработать грамотно ситуацию, когда у вас прицеплено к этой энтити что-то как ребенок (потому что внезапно их тоже теперь телепортить надо). И т.п. и т.п. Я не говорю что это в принципе нерешаемо, но это сложнее, чем обрабатывать это по одной энтити за раз.
Ну и например, представь систему апдейта мировых трансформов из финализированных локальных, которая не будет тыкаться в рандомные куски памяти. Ты же не можешь просто взять и пройтись по всем энтитям с parent компонентой, глубина иерархии может быть большой. Вернее можешь конечно, но в каждой такой энтити придется протыкаться по всем родителям вплоть до корня, и плакал ваш cache-friendly режим. А если пытаться это делать cache-friendly, то надо топологическую сортировку сначала делать, а это тоже не то чтобы хорошо ложится на всю концепцию
Это слишком догматичный подход (я не про ecs как таковой, а "есть только ecs а все остальное от лукавого"). Есть дофига вещей, которые плохо на ecs ложатся в принципе, но с ним носятся как с писаной торбой. ECS элементарнейшим образом разрастается на реальном проекте на сотни компонентов и сотни очень слабосвязанных джобов, дебажить которые - то еще удовольствие. От бесконечных рефакторов он тоже не спасает, если оказалось, что твое разбиение данных на компоненты больше не соответствует логике игры.
Да и это противопоставление ооп и ecs оно тоже ппц странное. Никто не заставляет делать жирных акторов с виртуальным update в ООП подходе, так или иначе все (или почти все) ecs системы объекты в итоге используют.
ECS хороший подход для немалого класса задач, но догматично говорить что все должны стать адептами ECS и настанет мир, дружба и жвачка это наивно. Посмотрите на базы данных, все реляционные системы по факту это тот же ECS вид сбоку, геймдев тут на десятки лет опоздал. Одно время подход вытеснил все остальное почти безраздельно, но со временем стало понятно, что для многих задач это не лучший вариант.
Upd:
Вот например, допустим, у вас большая, сложная и глубокая иерархия трансформов, где каждый кадр к ним надо применить набор каких-то систем. Скажем, каким-то объектам надо обновить локальный трансформ из скриптов, какие-то надо телепортировать по глобальным координатам, какие-то репарентнуть, и на половину из них должна еще и физика подействовать. Резолв всего этого через ECS - штука в целом реальная, но на пакетную обработку данных плохо ложится, и говорить, что у вас там в ecs какие-то преимущества - ну хз
теоретически можно, но практически хз. Может быть много инстансов одного домика одновременно на 10 разных дистациях (с любым модульным домиком так и будет) и получается весь лод чейн нужен одновременно в памяти. Да и в целом кумулятивно грузить весь лод чейн до минимально используемого в текущий момент проще. Плюс еще может быть так, что растеризация основной вьюхи использует один лод, рейтрейсинг другой, а шадоумапы третий. Предсказуемее и надежнее кумулятивно держать весь используемый в текущий момент лодчейн.
Потому что количество лодов зависит от того, какой процент треугольников сохраняется с каждым следующим лодом. А это напрямую влияет на занимаемую память. Допустим, у тебя каждый следующий лод сохраняет 50% треугольников. Тогда суммарная занимаемая память будет 1 / ( 1 - 0.5 ) = x2 от памяти нулевого лода. При сохранении 66% треугольников (частое явление) суммарная память будет 1 / ( 1 - 0.66 ) = x3 от памяти нулевого лода. Допустим, хочется сделать много-много лодов, чтобы переключение было незаметно. Например, каждый следующий лод будет сохранять 85% от числа треугольников предыдущего. Тогда занимаемая память будет 1 / ( 1 - 0.85 ) ~= x6 от памяти нулевого лода. Прикидки конечно очень примерные, но суть должна быть понятна. Видеопамяти и так нет нифига, нельзя еще больше требования к ней увеличивать
c bindless рендером это нерелевантно. Можно батчить в один drawindirect разную геометрию с разными материалами на одном шейдере
Пока с BAR памятью обращаются правильно (только пишут в нее последовательно блоками) - все будет хорошо. При любой попытке что-то из нее _прочитать_ будет гигантская задержка (потому что она не кэширована и находится физически на видеокарте, т.е. надо дождаться пока этот условный байт прилетит по PCI-e обратно, что невероятно долго.
Обычный способ заливать всякое барахло на видеокарту (всмысле без BAR) это взять кусок обычной системной некешированной памяти, записать в него что нужно а затем либо отдельной командой скопировать на gpu (обычно делают для мешей/текстур, которые один раз залил а потом постоянно на гпушке читаешь), либо напрямую в гпушных шейдерах читать из системной памяти (для мелких буфферов, которые каждый кадр меняются это стандартная схема, нет смысла в отдельном копировании). Оба способа предполагают запись в некешированный кусок обычной памяти. Попытка прочитать что-то оттуда тоже будет медленной, и так делать не надо, но это в десятки/сотни раз быстрее, чем чтение из BAR (потому что эта память поближе, не нужно по pci ее доставать).
Почему вообще эти медленные чтения могут происходить - обычно недосмотр, типа сделал какую-нить операцию типа += на куске памяти, помеченном как некешированный, вот тебе и просадка. Это довольно частая причина просадок перформанса в рендере
https://neolurk.org/wiki/%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D0%BF%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0_%D0%BC%D1%83%D0%B7%D1%8B%D0%BA%D0%B8_%D0%B2_%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B8