У юнити ещё огромный технический долг в плане графики, всё ещё плохо работает dx12, по сути не давая какой-то значительной разницы с dx11, нельзя кастомные per draw буфферы пропихивать и т.д. В этом году, например, в 6.1 презентовали Variable Rate Shading, хотя он был реализован в dx шесть лет назад.
Короче, отставание на годы от индустрии, а в некотрых моментах и десятилетие.
Отличие современных грфических api (Vulkan, Dx12) от старых в асинхронности, которая позволяет поддерживать гораздо большую и более равномерную загрузку на gpu. На моменте с асинхронностью и получается проблема, надо серьёзно перелапачивать исходный код движка. Без этого, с кучей GPU Fence (точек синхронизации), на синхронном cpu коде, dx12 будет работать также медленно, как и 11.
Интересный факт: в оригинальных фолычах не было изометрии, потому что движок её не поддерживал. Там максимально удалённая камера с минимальным фовом. В итоге перспектива есть, но маленькая. Однако её было достаточно, чтобы ноги персонажей скользили по полу.
Стоит добавить, что не обязательно каждый раз горадить какие-то перегруженные математические конструкции, чтобы просто отбросить какое-то значение. Достаточно использовать тернарный оператор. Если брать пример из статьи, то его можно применить так: Texture2D res = normal.y > 0.5 ? textureA : textureB;
color = res.Sample(sampler, uv); Он не вызывает бранчинг или смену контекста, по скольку расчитываются все части выражения. Оператор bool ? a : b работает везде. Пожалуйста, дорогие разработчики, используйте его, и не городите костыли.
У меня спустя время добавились аргументы, почему этот подход с расчётом позиции оптимальнее, чем разчёт позиции на процессере. Дело в использование шины памяти, это самое узкое горлышко почти для всего, связанного с графикой. В стандартной системе частиц, положение каждой вершины каждый кадр напрямую обновляется процессором, то есть нам надо каждый кадр высылать новый массив вершин частиц (где в каждой вершине хранится как минимум float3 позиция, float2 uv, half lifetime + массив индексов вершин, с помощью которого образуются треугольники). Когда мы имеем дело с шейдером, мы можем один раз загрузить меш в VRAM, и обнавлять только специфическую информацию (например, матрица трансформов или прогресс анимации, если она контролирется скриптом). То есть, даже в ситуации с идеально быстрым CPU, мы будем страдать от больших издержек связанных с передачей информации. И, как показывает практика, эти издержки больше, чем стоимость исполнения шейдера.
Как я понимаю, этот код работает попиксельно для каждого пикселя сообщения, и смещает его в bitmap'е. Выглядит как действительно большое колличесто операций, при худшем сценарии, когда сообщение занимает почти весь экран.
В телеграмме, мне кажется, не так много операций на процессоре, как в юнити, где надо постоянно обсчитывать физику, плюс каждый кадр проверяется каждый monobehavior и исполняется его код в update. Но из относящегося чисто к графике, каждый кадр надо рассчитвать: матрицы преобразования из 3д в экранное 2д, затем Particle System повершинно рассчитывает положение для частиц в 3д (гравитация, вращение, энерция, размер(это всё разные функции)), цвет, uv, применяет матрицы преобразования и делает draw call после расчёта всех вершин. Колличество итераций той функции из телеграмма здесь заменяется сложностью каждой. Ну и на практике, уже при 10к частиц на среднем телефоне могут быть серьёзные просадки, и вам нужно оставаться в пределах пары тысяч, чтобы везде шло плавно. Это не так много, вы вполне можете упереться в этот лимит.
На больших платформах, для сравнения, на среднем цп 300к частиц в пустой сцене подарят почти кинематографический эскпириенс в 40 кадров. В то время как уже довольно старенькая gtx 1080 обрабатывает 5 миллионов частиц в VFX graph в 47 кадров. (см видео https://www.youtube.com/watch?v=0deXRHX9C08&ab_channel=Brackeys )
Так что разница есть, и в зависимости от сложности поведения частиц она может быть довольно разительной. И на мобильных устройствах приходиться использовать любые ухищрения, чтобы повысить fps.
Естественно, любой шейдер повышает нагрузку на гпу, по скольку на нём и исполняется. Здесь скорее дело в эффективности. На экране 1000 частиц, у каждой по 4 вершины, для каждой вершины нужно сделать расчёт положения. У процессоров нет столько ядер, чтобы параллельно их обработать. А видеокарта может.
Конечно может быть такая ситуация, что у вас распределён бюджет на кадр. Цель 60 фпс, значит один кадр видеокарта и процессор не должны обрабатывать дольше 16 милисекунд(по отдельности, грубо говоря). И так вышло, что видекарта уже занята все 16 милисекунд, тогда конечно нет выбора, исполняем на цп. Просто на цп это займёт больше времени, вот и всё.
Специально для тебя выкладываю на гитхаб билд с пустой сценой и двумя системами частиц, которые выполняют одинаковые действия (двигаются, меняют цвет и размер, используют одну текстуру и т.д.). Менять активную систему можно по пробелу.
Диваны, конечно, плоские, но само помещение выглядит объёмным. Параллакс это смещение близкого объекта относительно дальнего, и тут я никого не обманываю, дальняя стена двигается медленнее боковых, перспектива создаётся.
А если для игрока не принципиально или невозможно близко подойти к окну и рассмотреть, то плоскость дивина относительно стены будет незаметна.
У юнити ещё огромный технический долг в плане графики, всё ещё плохо работает dx12, по сути не давая какой-то значительной разницы с dx11, нельзя кастомные per draw буфферы пропихивать и т.д. В этом году, например, в 6.1 презентовали Variable Rate Shading, хотя он был реализован в dx шесть лет назад.
Короче, отставание на годы от индустрии, а в некотрых моментах и десятилетие.
Отличие современных грфических api (Vulkan, Dx12) от старых в асинхронности, которая позволяет поддерживать гораздо большую и более равномерную загрузку на gpu. На моменте с асинхронностью и получается проблема, надо серьёзно перелапачивать исходный код движка. Без этого, с кучей GPU Fence (точек синхронизации), на синхронном cpu коде, dx12 будет работать также медленно, как и 11.
Интересный факт: в оригинальных фолычах не было изометрии, потому что движок её не поддерживал. Там максимально удалённая камера с минимальным фовом. В итоге перспектива есть, но маленькая. Однако её было достаточно, чтобы ноги персонажей скользили по полу.
Стоит добавить, что не обязательно каждый раз горадить какие-то перегруженные математические конструкции, чтобы просто отбросить какое-то значение. Достаточно использовать тернарный оператор. Если брать пример из статьи, то его можно применить так:
Texture2D res = normal.y > 0.5 ? textureA : textureB;
color = res.Sample(sampler, uv);
Он не вызывает бранчинг или смену контекста, по скольку расчитываются все части выражения.
Оператор bool ? a : b работает везде. Пожалуйста, дорогие разработчики, используйте его, и не городите костыли.
У меня спустя время добавились аргументы, почему этот подход с расчётом позиции оптимальнее, чем разчёт позиции на процессере. Дело в использование шины памяти, это самое узкое горлышко почти для всего, связанного с графикой. В стандартной системе частиц, положение каждой вершины каждый кадр напрямую обновляется процессором, то есть нам надо каждый кадр высылать новый массив вершин частиц (где в каждой вершине хранится как минимум float3 позиция, float2 uv, half lifetime + массив индексов вершин, с помощью которого образуются треугольники). Когда мы имеем дело с шейдером, мы можем один раз загрузить меш в VRAM, и обнавлять только специфическую информацию (например, матрица трансформов или прогресс анимации, если она контролирется скриптом). То есть, даже в ситуации с идеально быстрым CPU, мы будем страдать от больших издержек связанных с передачей информации. И, как показывает практика, эти издержки больше, чем стоимость исполнения шейдера.
Как я понимаю, этот код работает попиксельно для каждого пикселя сообщения, и смещает его в bitmap'е. Выглядит как действительно большое колличесто операций, при худшем сценарии, когда сообщение занимает почти весь экран.
В телеграмме, мне кажется, не так много операций на процессоре, как в юнити, где надо постоянно обсчитывать физику, плюс каждый кадр проверяется каждый monobehavior и исполняется его код в update. Но из относящегося чисто к графике, каждый кадр надо рассчитвать: матрицы преобразования из 3д в экранное 2д, затем Particle System повершинно рассчитывает положение для частиц в 3д (гравитация, вращение, энерция, размер(это всё разные функции)), цвет, uv, применяет матрицы преобразования и делает draw call после расчёта всех вершин. Колличество итераций той функции из телеграмма здесь заменяется сложностью каждой. Ну и на практике, уже при 10к частиц на среднем телефоне могут быть серьёзные просадки, и вам нужно оставаться в пределах пары тысяч, чтобы везде шло плавно. Это не так много, вы вполне можете упереться в этот лимит.
На больших платформах, для сравнения, на среднем цп 300к частиц в пустой сцене подарят почти кинематографический эскпириенс в 40 кадров. В то время как уже довольно старенькая gtx 1080 обрабатывает 5 миллионов частиц в VFX graph в 47 кадров. (см видео https://www.youtube.com/watch?v=0deXRHX9C08&ab_channel=Brackeys )
Так что разница есть, и в зависимости от сложности поведения частиц она может быть довольно разительной. И на мобильных устройствах приходиться использовать любые ухищрения, чтобы повысить fps.
Естественно, любой шейдер повышает нагрузку на гпу, по скольку на нём и исполняется. Здесь скорее дело в эффективности. На экране 1000 частиц, у каждой по 4 вершины, для каждой вершины нужно сделать расчёт положения. У процессоров нет столько ядер, чтобы параллельно их обработать. А видеокарта может.
Конечно может быть такая ситуация, что у вас распределён бюджет на кадр. Цель 60 фпс, значит один кадр видеокарта и процессор не должны обрабатывать дольше 16 милисекунд(по отдельности, грубо говоря). И так вышло, что видекарта уже занята все 16 милисекунд, тогда конечно нет выбора, исполняем на цп. Просто на цп это займёт больше времени, вот и всё.
Специально для тебя выкладываю на гитхаб билд с пустой сценой и двумя системами частиц, которые выполняют одинаковые действия (двигаются, меняют цвет и размер, используют одну текстуру и т.д.). Менять активную систему можно по пробелу.
Диваны, конечно, плоские, но само помещение выглядит объёмным. Параллакс это смещение близкого объекта относительно дальнего, и тут я никого не обманываю, дальняя стена двигается медленнее боковых, перспектива создаётся.
А если для игрока не принципиально или невозможно близко подойти к окну и рассмотреть, то плоскость дивина относительно стены будет незаметна.