В эту субботу пройдет евент на тему ME.BECS, я расскажу как ее использовать и отвечу на ваши вопросы. Формат немного поменяем и я сначала расскажу об API и отвечу на интересующие вопросы, а затем мы сможем посмотреть на ваш проект и решить конкретные вопросы.
ME.BECS скачать можно тут:
https://github.com/chromealex/ME.BECS
Регистрация на событие тут:
https://unsafecsharp.timepad.ru/event/2594690/
#event #ecs
ME.BECS скачать можно тут:
https://github.com/chromealex/ME.BECS
Регистрация на событие тут:
https://unsafecsharp.timepad.ru/event/2594690/
#event #ecs
🔥12👍3❤1
Есть на SkinMeshRenderer галка "Update when offscreen".
Что делает скинмеш? Он на цпу (на других потоках) или на гпу (компьют скиннинг) запускает апдейт позиций вертексов на меше.
Что значит оффскрин? Это относится к SkinMeshRenderer'ам чьи баунды не попали во фрустум камеры.
Мы не можем запустить рендер до скиннинга.
Мы не можем запустить скиннинг ДО куллинга.
А куллинг мы не можем запустить ДО окончания просчета игровой логики (вдруг у вас в LateUpdate камера куда-то перемещается).
В итоге:
Если вы галочку оставите - у вас могут просчитываться скинмеши, которые не видно сейчас. И из-за этого может дольше рендериться кадр.
Если вы галочку уберете - у вас может дольше рендериться кадр из-за того, что скиннинг не параллельно с игровой логикой шёл.
Автор: @shiko_q
Пост: https://news.1rj.ru/str/unity_cg/49798
#rendering #skinnedmeshrender
Что делает скинмеш? Он на цпу (на других потоках) или на гпу (компьют скиннинг) запускает апдейт позиций вертексов на меше.
Что значит оффскрин? Это относится к SkinMeshRenderer'ам чьи баунды не попали во фрустум камеры.
Мы не можем запустить рендер до скиннинга.
Мы не можем запустить скиннинг ДО куллинга.
А куллинг мы не можем запустить ДО окончания просчета игровой логики (вдруг у вас в LateUpdate камера куда-то перемещается).
В итоге:
Если вы галочку оставите - у вас могут просчитываться скинмеши, которые не видно сейчас. И из-за этого может дольше рендериться кадр.
Если вы галочку уберете - у вас может дольше рендериться кадр из-за того, что скиннинг не параллельно с игровой логикой шёл.
Автор: @shiko_q
Пост: https://news.1rj.ru/str/unity_cg/49798
#rendering #skinnedmeshrender
🔥16👍1
Итак, пришло время сказать что я думаю о будущем и юнити.
Что сделали юнити?
Глобально они хотят вылезти из задницы, в которую сами себя засунули. Это напоминает наш релиз Mushroom Wars 2, когда мы хотели выпустить стим-версию, платную, без внутренних платежей, рекламы и прочего ф2п говна. Но вскоре поняли, что выжить можно только в ф2п. Поэтому приоритет резко стал мобильным и бесплатным.
По сути юнити сейчас находится в большом минусе, они потратили кучу денег, чтобы стать монополистом на рынке, а теперь им приходится платить по счетам, чтобы хоть как-то вернуться в ноль.
Изначальная политика юнити была криком о помощи, нежели чем реальной возможностью поправить свои дела. То есть они ожидали, что их политика не сильно понравится, но они не ожидали что этим решением они убьют рынок ф2п.
Я уже много раз писал почему это убивает ф2п рынок, думаю, что вы и сами понимаете это, если нет - го в комменты.
Что делать дальше?
На самом деле ничего. В реальности если ваша компания вылезает за рамки 1млн - вам нужно добавить 4% к расходам магазина (ну представьте, что apple стали брать не 30%, а 34%). Больно? Да. Сильно? Ну нет. Вы же не откажитесь от рынка ios, только потому что комиссия увеличилась на 4%?
Но есть и обратная сторона. Особенно для тех компаний, которые закупались в ноль, то есть тратили условно 1млн, получали обратно этот же 1млн, но при этом платили комиссию стору. То есть глобально вы привлекаете юзеров, которые когда-нибудь что-нибудь да заплатят.
Возвращаясь к теме поста…
На самом деле мы имеем такую реальность:
1. Юнити - скорее всего (на 99%) подписки останутся, то есть при достижении каких-то ревенью, вы должны будете платить 4% от гросса. Чем это плохо? Глобально это вы к 30% комиссии стора добавляете еще 4%. Много это или мало - каждый решает сам с точки зрения бизнеса. Возможно, что будет отдельное решение для топовых студий, но что-то я сильно сомневаюсь.
2. UE - даже если забыть про проблемы с размером билда, что там не сильно парятся насчет мобилок в принципе (глобально для мидкора можно и пережить) - с вас хотят 5% гросс, что собственно чуть больше, чем хочет юнити, при этом имея лучший бэкграунд для мобильной разработки. Понимают ли это эпики? Думаю, что да. Будут ли они с этим что-то делать? Думаю, что нет. У них другие приоритеты, и если вы думаете, что в UE все намного лучше, то вы просто забыли историю.
3. Годот - движок, который сделан программистами для программистов. Там есть редактор, да. Удобный? Нет. Много вопросов в принципе к архитектуре, которые вряд ли будут решены. До юнити годот настолько далеко, что это только год минимум надо потратить только на редактор (это если самим движком не заниматься). В целом из плюсов только шарп и плюсы, но прикрутить шарп вообще не проблема сейчас к любому движку. Для простых проектов пойдет, для более сложных - ну скорее нет.
4. Cocos - тут все просто. Движок, который не умеет в плюсы, ну или хотя бы в шарп - не движок, а какая-то хрень для веб-разработчиков. Я сам когда-то писал на js (ts тогда не было), поэтому я понимаю, что возвращаться на js/ts - это деградация.
5. Остальные движки. В реальности они не готовы к продакшену, совсем. У некоторых есть неплохие редакторы (flax, stride), плохая поддержка, т.к. на них просто забили (собственно, зачем конкурировать с юнити?).
Что будем делать мы?
Для текущих проектов - очевидно, что юнити. Для следующих проектов - не знаю. Думаю, что юнити глобально выйдут в плюс и все будет у них хорошо. Мы еще раз вернемся к этому вопросу в следующем году и посмотрим что успели сделать другие движки, но пока остаемся на юнити.
Это все мое личное мнение на происходящее, которое не имеет отношения к мнению компаний Azur Games, Jet Whales и Zillion Whales.
#unity #future
Что сделали юнити?
Глобально они хотят вылезти из задницы, в которую сами себя засунули. Это напоминает наш релиз Mushroom Wars 2, когда мы хотели выпустить стим-версию, платную, без внутренних платежей, рекламы и прочего ф2п говна. Но вскоре поняли, что выжить можно только в ф2п. Поэтому приоритет резко стал мобильным и бесплатным.
По сути юнити сейчас находится в большом минусе, они потратили кучу денег, чтобы стать монополистом на рынке, а теперь им приходится платить по счетам, чтобы хоть как-то вернуться в ноль.
Изначальная политика юнити была криком о помощи, нежели чем реальной возможностью поправить свои дела. То есть они ожидали, что их политика не сильно понравится, но они не ожидали что этим решением они убьют рынок ф2п.
Я уже много раз писал почему это убивает ф2п рынок, думаю, что вы и сами понимаете это, если нет - го в комменты.
Что делать дальше?
На самом деле ничего. В реальности если ваша компания вылезает за рамки 1млн - вам нужно добавить 4% к расходам магазина (ну представьте, что apple стали брать не 30%, а 34%). Больно? Да. Сильно? Ну нет. Вы же не откажитесь от рынка ios, только потому что комиссия увеличилась на 4%?
Но есть и обратная сторона. Особенно для тех компаний, которые закупались в ноль, то есть тратили условно 1млн, получали обратно этот же 1млн, но при этом платили комиссию стору. То есть глобально вы привлекаете юзеров, которые когда-нибудь что-нибудь да заплатят.
Возвращаясь к теме поста…
На самом деле мы имеем такую реальность:
1. Юнити - скорее всего (на 99%) подписки останутся, то есть при достижении каких-то ревенью, вы должны будете платить 4% от гросса. Чем это плохо? Глобально это вы к 30% комиссии стора добавляете еще 4%. Много это или мало - каждый решает сам с точки зрения бизнеса. Возможно, что будет отдельное решение для топовых студий, но что-то я сильно сомневаюсь.
2. UE - даже если забыть про проблемы с размером билда, что там не сильно парятся насчет мобилок в принципе (глобально для мидкора можно и пережить) - с вас хотят 5% гросс, что собственно чуть больше, чем хочет юнити, при этом имея лучший бэкграунд для мобильной разработки. Понимают ли это эпики? Думаю, что да. Будут ли они с этим что-то делать? Думаю, что нет. У них другие приоритеты, и если вы думаете, что в UE все намного лучше, то вы просто забыли историю.
3. Годот - движок, который сделан программистами для программистов. Там есть редактор, да. Удобный? Нет. Много вопросов в принципе к архитектуре, которые вряд ли будут решены. До юнити годот настолько далеко, что это только год минимум надо потратить только на редактор (это если самим движком не заниматься). В целом из плюсов только шарп и плюсы, но прикрутить шарп вообще не проблема сейчас к любому движку. Для простых проектов пойдет, для более сложных - ну скорее нет.
4. Cocos - тут все просто. Движок, который не умеет в плюсы, ну или хотя бы в шарп - не движок, а какая-то хрень для веб-разработчиков. Я сам когда-то писал на js (ts тогда не было), поэтому я понимаю, что возвращаться на js/ts - это деградация.
5. Остальные движки. В реальности они не готовы к продакшену, совсем. У некоторых есть неплохие редакторы (flax, stride), плохая поддержка, т.к. на них просто забили (собственно, зачем конкурировать с юнити?).
Что будем делать мы?
Для текущих проектов - очевидно, что юнити. Для следующих проектов - не знаю. Думаю, что юнити глобально выйдут в плюс и все будет у них хорошо. Мы еще раз вернемся к этому вопросу в следующем году и посмотрим что успели сделать другие движки, но пока остаемся на юнити.
Это все мое личное мнение на происходящее, которое не имеет отношения к мнению компаний Azur Games, Jet Whales и Zillion Whales.
#unity #future
👍44❤7🥰2🤨2👏1👌1
Напоминаю, что сегодня в 16:00 по мск будем разбирать ME.BECS. Кто еще не регался - велкам:
https://news.1rj.ru/str/unsafecsharp/192
#event
https://news.1rj.ru/str/unsafecsharp/192
#event
Telegram
Unity: Всё, что вы не знали о разработке
В эту субботу пройдет евент на тему ME.BECS, я расскажу как ее использовать и отвечу на ваши вопросы. Формат немного поменяем и я сначала расскажу об API и отвечу на интересующие вопросы, а затем мы сможем посмотреть на ваш проект и решить конкретные вопросы.…
🔥5🤡1
Всем привет! Мне очень нужен ваш фидбэк для моего личного сайта. Можете написать все что считаете нужным:
https://docs.google.com/forms/d/e/1FAIpQLScgfoG3ayzhQcBnQM6IY-QnTzMk0-uIyKwks02x7lzEClnChQ/viewform?usp=sharing
Всем огромное спасибо;)
#feedback
https://docs.google.com/forms/d/e/1FAIpQLScgfoG3ayzhQcBnQM6IY-QnTzMk0-uIyKwks02x7lzEClnChQ/viewform?usp=sharing
Всем огромное спасибо;)
#feedback
🦄7🤡5👍2🥰1
Итак, я завел сайтик, где буду размещать все события, а также вести блог (сейчас там можно найти все темы, которые есть в этом канале, но в более удобном виде).
Канал в ТГ остается и я буду делать посты тут тоже.
Регайтесь на событие, которое пройдет в эту субботу в 4 часа по мск:
https://www.unsafecsharp.com/events/ugui-Рассказываю-про-uiwindows
#event
Канал в ТГ остается и я буду делать посты тут тоже.
Регайтесь на событие, которое пройдет в эту субботу в 4 часа по мск:
https://www.unsafecsharp.com/events/ugui-Рассказываю-про-uiwindows
#event
🔥22❤2
xmm vs ymm
Написал немного про векторизацию:
https://www.unsafecsharp.com/blog/xmm-vs-ymm
#burst #vectorization #performance
Написал немного про векторизацию:
https://www.unsafecsharp.com/blog/xmm-vs-ymm
#burst #vectorization #performance
🔥9👍2
Напоминаю, что сегодня в 4 часа по мск будем обсуждать UI.Windows:
https://www.unsafecsharp.com/events/ugui-Рассказываю-про-uiwindows
#event
https://www.unsafecsharp.com/events/ugui-Рассказываю-про-uiwindows
#event
@unsafecsharp
uGUI: Рассказываю про UI.Windows - @unsafecsharp
🔥12👍2❤1
Вместе с https://ragon.io/ и @edmand46 ME.BECS теперь очень дружит, реализован транспорт, можно из коробки использовать тестовый транспорт, Photon или Ragon.
#ecs #becs #network
#ecs #becs #network
ragon.io
Ragon | Ragon
Network solution for unity
🔥24👍9
Есть CPU, есть GPU.
GPU - это графический ускоритель, т.е. дополнительное устройство для ускорения определенных операций, а именно - рендеринга.
Между ними существует промежуточный буфер. Буфер команд, очередь если точнее.
CPU наполняет этот буфер. а GPU забирает из него и удаляет команду, которую забрал.
Если CPU заполняет буфер быстрее, чем GPU потребляет, то рано или поздно он упрется в максимальный размер буфера. В таком случае мы говорим, что у нас GPU bound, т.к. центральный процессор простаивает по вине GPU.
И наоборот - если GPU слишком быстро потребляет команды, а CPU не успевает наполнять буфер - то простаивает GPU и у нас CPU bound.
(это, разумеется, не все причины почему у нас может возникнуть баунд).
Любое сообщение CPU и GPU - это команда.
В понимании графического ускорителя не существует такого понятия как drawcall и setpass call. Об этом ниже.
Есть "состояние пайплайна" - "state" и команды отрисовки (нарисуй просто, нарисуй с буфером индексов, нарисуй индирект, нарисуй инстансингом, итд).
(Причём на разных графических API есть разная "детализация" этого состояния).
Итай, стейт - это обобщение для: шейдерные программы для разных этапов конвейера (вертексный, фрагментный, итд), значения всяких ресурсов, значения хардварных переключателей, и пр.
В старых API - DX11 и OpenGL / GL ES - стейт один на весь GPU. В новых - можно их на CPU собирать, кэшировать и экономить на сборке.
Допустим, говорим про GL.
Там ты стейт собираешь как колоду карт, по очереди, отдельными командами, каждый кадр заново:
- Вот текстурка в этот слот.
- Вот буфер в этот слот.
- Вот шейдерная программа для вертексов
...
- Вызов команды отрисовки.
Можно воспринимать этот вызов отрисовки как нажатие кнопки на блендере. Нажал - и всё применилось.
При этом разные команды для изменения состояния GPU - имеют разную "стоимость".
Стоимость эта применяется дважды - сначала CPU надо её выполнить - т.е. подготовить для неё данные, провалидировать и поместить команду и данные в буфер.
Затем, при считывании, драйвер GPU должен взять эту команду и применить её в свой стейт.
Дроуколл - это термин программистов, обобщение, для вызова отрисовки + набор команд на изменение стейта, которые надо доприменять после прошлого дроуколла.
- | тут-старый-дроуколл |
-блабла
-блаблабла
-отрисовка.
Вот эти три команды - дроуколл.
Чтобы минимизировать оверхед на вот эти мотыляния стейта туда-сюда, программисты пытаются "батчить" команды. Ведь после вызова команды отрисовки, драйвер не сбрасывает стейт. И если есть команды, которые можно выполнить с одним и тем же стейтом - мы можем здорово сэкономить.
Такая пачка команд называется "батч".
А самый первый и самый длинный, долгий, тяжелый дроуколл, когда у нас выставляется весь стейт - это SetPass Call.
"Идеальный" батч можно посмотреть рендердоком на партикл системе (которая шурикен). Там один сетпассколл и много дроуколлов из одной команды отрисовки.
Обычно у нас таких идеальных батчей больше нет нигде :))
Даже в том же SRP батчере у нас в дроуколл'е приходится мапить небольшие участки буферов, вертексные-индексные буферы, текстуры.
Но это всё равно изрядно дешевле, чем каждый drawcall выстраивать стейт с нуля.
p.s. и на десерт :)
Современные драйверы умеют анализировать загрузку GPU и могут выполнять несколько разных дроуколлов одновременно. Важный фактор - чтобы они не зависели друг от друга. Так, к примеру, GPU может считать вертексный шейдер одного меша в одном дк и фрагментный другого в другом.
Автор: @shiko_q
Источник: https://news.1rj.ru/str/unity_cg/52328
#cpu #gpu #rendering
GPU - это графический ускоритель, т.е. дополнительное устройство для ускорения определенных операций, а именно - рендеринга.
Между ними существует промежуточный буфер. Буфер команд, очередь если точнее.
CPU наполняет этот буфер. а GPU забирает из него и удаляет команду, которую забрал.
Если CPU заполняет буфер быстрее, чем GPU потребляет, то рано или поздно он упрется в максимальный размер буфера. В таком случае мы говорим, что у нас GPU bound, т.к. центральный процессор простаивает по вине GPU.
И наоборот - если GPU слишком быстро потребляет команды, а CPU не успевает наполнять буфер - то простаивает GPU и у нас CPU bound.
(это, разумеется, не все причины почему у нас может возникнуть баунд).
Любое сообщение CPU и GPU - это команда.
В понимании графического ускорителя не существует такого понятия как drawcall и setpass call. Об этом ниже.
Есть "состояние пайплайна" - "state" и команды отрисовки (нарисуй просто, нарисуй с буфером индексов, нарисуй индирект, нарисуй инстансингом, итд).
(Причём на разных графических API есть разная "детализация" этого состояния).
Итай, стейт - это обобщение для: шейдерные программы для разных этапов конвейера (вертексный, фрагментный, итд), значения всяких ресурсов, значения хардварных переключателей, и пр.
В старых API - DX11 и OpenGL / GL ES - стейт один на весь GPU. В новых - можно их на CPU собирать, кэшировать и экономить на сборке.
Допустим, говорим про GL.
Там ты стейт собираешь как колоду карт, по очереди, отдельными командами, каждый кадр заново:
- Вот текстурка в этот слот.
- Вот буфер в этот слот.
- Вот шейдерная программа для вертексов
...
- Вызов команды отрисовки.
Можно воспринимать этот вызов отрисовки как нажатие кнопки на блендере. Нажал - и всё применилось.
При этом разные команды для изменения состояния GPU - имеют разную "стоимость".
Стоимость эта применяется дважды - сначала CPU надо её выполнить - т.е. подготовить для неё данные, провалидировать и поместить команду и данные в буфер.
Затем, при считывании, драйвер GPU должен взять эту команду и применить её в свой стейт.
Дроуколл - это термин программистов, обобщение, для вызова отрисовки + набор команд на изменение стейта, которые надо доприменять после прошлого дроуколла.
- | тут-старый-дроуколл |
-блабла
-блаблабла
-отрисовка.
Вот эти три команды - дроуколл.
Чтобы минимизировать оверхед на вот эти мотыляния стейта туда-сюда, программисты пытаются "батчить" команды. Ведь после вызова команды отрисовки, драйвер не сбрасывает стейт. И если есть команды, которые можно выполнить с одним и тем же стейтом - мы можем здорово сэкономить.
Такая пачка команд называется "батч".
А самый первый и самый длинный, долгий, тяжелый дроуколл, когда у нас выставляется весь стейт - это SetPass Call.
"Идеальный" батч можно посмотреть рендердоком на партикл системе (которая шурикен). Там один сетпассколл и много дроуколлов из одной команды отрисовки.
Обычно у нас таких идеальных батчей больше нет нигде :))
Даже в том же SRP батчере у нас в дроуколл'е приходится мапить небольшие участки буферов, вертексные-индексные буферы, текстуры.
Но это всё равно изрядно дешевле, чем каждый drawcall выстраивать стейт с нуля.
p.s. и на десерт :)
Современные драйверы умеют анализировать загрузку GPU и могут выполнять несколько разных дроуколлов одновременно. Важный фактор - чтобы они не зависели друг от друга. Так, к примеру, GPU может считать вертексный шейдер одного меша в одном дк и фрагментный другого в другом.
Автор: @shiko_q
Источник: https://news.1rj.ru/str/unity_cg/52328
#cpu #gpu #rendering
🔥53👍10❤4🤯4👏1
Всем привет! Мы добрались до релиза открытой беты с одной из наших игр. Буду рад, если вы посмотрите наш проект.
Скоро будет еще анонс другого проекта;)
🌲 Wild Forest 🌲 Сезон 0 Открытая Бета уже доступна! 🚀
🎮 Погрузитесь в эпические сражения в самой захватывающей бете года.
Исследуйте и сражайтесь⚔️ в мире 🌲Wild Forest🌲 на Android и iOS!
🌐 Просто посетите playwildforest.io, чтобы начать играть прямо сейчас!
Ваш прогресс во время открытой беты будет преобразован в эксклюзивные награды NFT. 🏆
Готовы начать свое путешествие?🔥 БЕСПЛАТНЫЙ ПРЕМИУМ БАТЛ ПАСС уже ждет вас, инструкции внутри игры.
#wildforest #game #release
Скоро будет еще анонс другого проекта;)
🌲 Wild Forest 🌲 Сезон 0 Открытая Бета уже доступна! 🚀
🎮 Погрузитесь в эпические сражения в самой захватывающей бете года.
Исследуйте и сражайтесь⚔️ в мире 🌲Wild Forest🌲 на Android и iOS!
🌐 Просто посетите playwildforest.io, чтобы начать играть прямо сейчас!
Ваш прогресс во время открытой беты будет преобразован в эксклюзивные награды NFT. 🏆
Готовы начать свое путешествие?🔥 БЕСПЛАТНЫЙ ПРЕМИУМ БАТЛ ПАСС уже ждет вас, инструкции внутри игры.
#wildforest #game #release
🥴18🔥12👍4🤷2😎1
Большинство ПК рендерят IMR - Immediate Mode Rendering.
Что и как подали на вход - так и отрендерили, в том же порядке. Стандартный графический апи - примитив, растеризация, шейдинг фрагмента.
В рендере примитивов важно соблюсти порядок - какой примитив отрисовать, какой примитив был перекрыт и его можно вообще не шейдить. Для этого, изначально, есть разные варианты - например - алгоритм художника или сортировка.
Но наиболее эффективный - это использовать хардварный Z-Buffer, он же буфер глубины.
(Вот именно за этим он и нужен в первую очередь, а не чтоб пенку у острова рисовать, блин.)
Нюанс IMR в том, что при каждой отрисовке фрагмента, ты должен взять и подать из глобальной памяти (VRAM) глубину и стенсиль для этого фрагмента.
VRAM хоть и быстра, но это не кэш, фетч из неё, по ритму жизни обычных инструкций (типа сложения-умножения на гпу) может занимать месяцы если не годы.
Любой чих-пых на шине (это мостик между памятью и кэшем на гпу) стоит энергии, сиречь электричества. Где электричество, там теплопотери, нагрев и необходимость всю эту радость охлаждать.
При разработке гпу для мобильных девайсов, инженеры не захотели решать вопрос с креплением вентилятора и весом аккумуляторных батарей и пошли странным, но весьма эффективным путём - родили TBDR.
TBDR - Tile-Based Deferred Rendering.
Все инструкции что ведут до SV_Position + разбиение по примитивам выделяются в отдельную часть шейдера и выполняются здесь и сейчас.
А затем нужно выполнить для позиций примитивов биннинг (Qualcomm) или же тайлинг (Mali, PowerVR). Разница между ними не так уж велика.
Весь бэкбуфер разделен, хардварно, на небольшие участки. Ты мог иногда видеть артефакты биннинга, когда у тебя на экране есть крупные (относительно) прямоугольники, в которых изображение норм, а есть прямоугольники, где не норм, так вот это оно.
Работу эту выполняется отдельный хардварный модуль - тайлер. У него тоже есть предел нагрузки и если у тебя много геометрии, или она распределена так, чтобы покрывать множество бинов - ты вполне можешь достичь предела его способностей (у меня были такие кейсы в практике).
Вся геометрия после геометрического этапа распределяется по этим участкам-бинам и отправляется в системную память. И только потом по каждому отдельному бину/тайлу начинаются операции по растеризации-интерполяции-фрагментному-шейдингу.
Вся геометрия - в смысле вообще вся. Т.е. у тебя сначала все вертексные шейдеры ВСЕХ твоих дроуколлов выполняются (точнее, позиционная часть вертексных шейдеров) и только потом все остальные вычисления, в т.ч. шейдинг фрагментов
Интерполяционная часть вертексного шейдера, сама интерполяция и шейдинг идут уже по бинам. Будто твой бин - это отдельная, маленькая рендертекстура. Для каждого бина мы подтягиваем геометрические данные (позиции как минимум) из системной памяти, выполняем интерполяционную часть и переходим к дальнейшим шагам гпу пайплайна.
Синхронизация - смена рендертаргета. Т.е. в рамках одного таргета - всё так. Меняем таргет - всё по новой.
Цель сих манипуляций в том, что на гпу есть специальный кэш - тайловая память, где обычно и лежат данные глубины и стенсиля. Кэш маленький, зато свой. Размером под тайлик.
Когда мы растеризацию-интерполяцию делаем, мы в кэш этот глубину и стенсиль per-fragment и складываем, и с ней же сравниваем. И там же цвет пикселя лежит для операций блендинга.
После резолва текстуры - результат (т.е. те данные что ты в начале пометил как нужные для резолва, как правило - цвет, реже - глубина + стенсиль) отправляются в системную память. Если резолв не требуется - едут в бэкбуфер и далее - на экран девайса.
На этот же принцип (бины/тайлы, кэш на гпу) опирается рендерпасс апи в вулкане, чтобы делать деферред рендеринг и не гонять промежуточные данные между гпу и шареной мобильной памятью.
p.s. подробнее тут:
https://developer.samsung.com/galaxy-gamedev/resources/articles/gpu-framebuffer.html
https://developer.apple.com/documentation/metal/tailor_your_apps_for_apple_gpus_and_tile-based_deferred_rendering
Пост: https://news.1rj.ru/str/unity_cg/57772
Автор: @shiko_q
#rendering #graphics
Что и как подали на вход - так и отрендерили, в том же порядке. Стандартный графический апи - примитив, растеризация, шейдинг фрагмента.
В рендере примитивов важно соблюсти порядок - какой примитив отрисовать, какой примитив был перекрыт и его можно вообще не шейдить. Для этого, изначально, есть разные варианты - например - алгоритм художника или сортировка.
Но наиболее эффективный - это использовать хардварный Z-Buffer, он же буфер глубины.
Нюанс IMR в том, что при каждой отрисовке фрагмента, ты должен взять и подать из глобальной памяти (VRAM) глубину и стенсиль для этого фрагмента.
VRAM хоть и быстра, но это не кэш, фетч из неё, по ритму жизни обычных инструкций (типа сложения-умножения на гпу) может занимать месяцы если не годы.
Любой чих-пых на шине (это мостик между памятью и кэшем на гпу) стоит энергии, сиречь электричества. Где электричество, там теплопотери, нагрев и необходимость всю эту радость охлаждать.
При разработке гпу для мобильных девайсов, инженеры не захотели решать вопрос с креплением вентилятора и весом аккумуляторных батарей и пошли странным, но весьма эффективным путём - родили TBDR.
TBDR - Tile-Based Deferred Rendering.
Все инструкции что ведут до SV_Position + разбиение по примитивам выделяются в отдельную часть шейдера и выполняются здесь и сейчас.
А затем нужно выполнить для позиций примитивов биннинг (Qualcomm) или же тайлинг (Mali, PowerVR). Разница между ними не так уж велика.
Весь бэкбуфер разделен, хардварно, на небольшие участки. Ты мог иногда видеть артефакты биннинга, когда у тебя на экране есть крупные (относительно) прямоугольники, в которых изображение норм, а есть прямоугольники, где не норм, так вот это оно.
Работу эту выполняется отдельный хардварный модуль - тайлер. У него тоже есть предел нагрузки и если у тебя много геометрии, или она распределена так, чтобы покрывать множество бинов - ты вполне можешь достичь предела его способностей (у меня были такие кейсы в практике).
Вся геометрия после геометрического этапа распределяется по этим участкам-бинам и отправляется в системную память. И только потом по каждому отдельному бину/тайлу начинаются операции по растеризации-интерполяции-фрагментному-шейдингу.
Вся геометрия - в смысле вообще вся. Т.е. у тебя сначала все вертексные шейдеры ВСЕХ твоих дроуколлов выполняются (точнее, позиционная часть вертексных шейдеров) и только потом все остальные вычисления, в т.ч. шейдинг фрагментов
Интерполяционная часть вертексного шейдера, сама интерполяция и шейдинг идут уже по бинам. Будто твой бин - это отдельная, маленькая рендертекстура. Для каждого бина мы подтягиваем геометрические данные (позиции как минимум) из системной памяти, выполняем интерполяционную часть и переходим к дальнейшим шагам гпу пайплайна.
Синхронизация - смена рендертаргета. Т.е. в рамках одного таргета - всё так. Меняем таргет - всё по новой.
Цель сих манипуляций в том, что на гпу есть специальный кэш - тайловая память, где обычно и лежат данные глубины и стенсиля. Кэш маленький, зато свой. Размером под тайлик.
Когда мы растеризацию-интерполяцию делаем, мы в кэш этот глубину и стенсиль per-fragment и складываем, и с ней же сравниваем. И там же цвет пикселя лежит для операций блендинга.
После резолва текстуры - результат (т.е. те данные что ты в начале пометил как нужные для резолва, как правило - цвет, реже - глубина + стенсиль) отправляются в системную память. Если резолв не требуется - едут в бэкбуфер и далее - на экран девайса.
На этот же принцип (бины/тайлы, кэш на гпу) опирается рендерпасс апи в вулкане, чтобы делать деферред рендеринг и не гонять промежуточные данные между гпу и шареной мобильной памятью.
p.s. подробнее тут:
https://developer.samsung.com/galaxy-gamedev/resources/articles/gpu-framebuffer.html
https://developer.apple.com/documentation/metal/tailor_your_apps_for_apple_gpus_and_tile-based_deferred_rendering
Пост: https://news.1rj.ru/str/unity_cg/57772
Автор: @shiko_q
#rendering #graphics
Samsung Developer
GPU Framebuffer Memory: Understanding Tiling | Samsung Developer
The world runs on you.
🔥24🤔11👍9❤5🤯5❤🔥1👏1
Поговорим про RenderBufferLoadAction и RenderBufferStoreAction
В обычном растер пайплайне на гпу, пожалуй самым важным и обязательным условием является установка рендертагрета.
Это так называемый бэкбуфер, куда будет записан (или не записан) результат работы всех этих вертекс-фрагмент (и прочих) операций.
Есть условная команда "установить рендертаргет".
При установке, тебе нужно задать несколько параметров:
- Color буфер (их может быть и несколько)
- Depth/stencil буфер (это один буфер, глубина и стенсиль просто лежат в разных битах)
- Нужно ли чистить буферы и если да - то каким значением (типа цвет - черный, белый, итд, глубина - 0, 1, или иное, аналогично для стенсиля).
- Вьюпорт
- Scissor rect (обычно никто его не трогает, ограниченно полезный лишь на пк)
- Load/Store действия.
Вот про них мы и поговорим.
Каковы последствия, если неправильно проставил?
Либо получишь некорректный результат на экране (с артефактами, например), либо удвоишь нагрузку на шину и получишь просадку производительности на ровном месте.
Load:
Отрендерил ты кубик в экран, но этот кубик рисуется же не на пустом месте - он рисуется на участке текстуры. А что делать с теми пикселями, которые были до кубика в этой текстуре?
Допустим, у тебя кубик полупрозрачный, а текстура не пустая - там картинка какая-то.
Чтобы альфабленд сработал - тебе нужны данные пикселей этой текстуры, где у тебя пиксели кубика нарисуются, чтобы их сблендить и результат получить. Для этого и нужен LoadAction.Load
Поэтому ЕСЛИ текстура не пустая И либо у тебя альфабленд, либо ты не все пиксели перерисуешь (типа будут участки не затронутые ни одним мешем - такого не бывает при блите, конечно, но вдруг у тебя не фуллскрин блит) - то тебе нужен
LoadAction.Load.
Иначе - DontCare + обязательно после установки таргета сделать cmd.ClearRenderTarget. Иначе магия может не сработать.
Store:
Обычно тебе нужно сохранять результат рендера в текстуру, иначе как бы, нафига рендер нужен, правда?
Но не всегда.
Скажем, тебе обычно не нужна глубина и стенсиль. Т.е. они тебе нужны на то время, пока ты рендеришь всякие кубики, партиклы. Но в это время глубина-и-стенсиль лежат в тайловой памяти на гпу и прекрасно выполняют свою функцию сравнения. А вот после окончания рендера тебе, допустим, только цвет и нужен. Значит для глубины можно поставить StoreAction.DontCare.
Для шедоумапы, к примеру, тебе цвет не нужен. Значит там - StoreAction.DontCare, а глубина - нужна. Там - Store.
Отдельный геморрой это MSAA. И если он включен, то с ним StoreAction'ы работают чуть иначе и менее очевидно. Но это уже другая история.
Вот так это чудо можно дебажить:
https://docs.unity3d.com/ScriptReference/Rendering.LoadStoreActionDebugModeSettings.html
Либо через рендердок
Автор: @shiko_q
Источник: https://news.1rj.ru/str/unity_cg/62577
#rendering #graphics
В обычном растер пайплайне на гпу, пожалуй самым важным и обязательным условием является установка рендертагрета.
Это так называемый бэкбуфер, куда будет записан (или не записан) результат работы всех этих вертекс-фрагмент (и прочих) операций.
Есть условная команда "установить рендертаргет".
При установке, тебе нужно задать несколько параметров:
- Color буфер (их может быть и несколько)
- Depth/stencil буфер (это один буфер, глубина и стенсиль просто лежат в разных битах)
- Нужно ли чистить буферы и если да - то каким значением (типа цвет - черный, белый, итд, глубина - 0, 1, или иное, аналогично для стенсиля).
- Вьюпорт
- Scissor rect (обычно никто его не трогает, ограниченно полезный лишь на пк)
- Load/Store действия.
Вот про них мы и поговорим.
Каковы последствия, если неправильно проставил?
Либо получишь некорректный результат на экране (с артефактами, например), либо удвоишь нагрузку на шину и получишь просадку производительности на ровном месте.
Load:
Отрендерил ты кубик в экран, но этот кубик рисуется же не на пустом месте - он рисуется на участке текстуры. А что делать с теми пикселями, которые были до кубика в этой текстуре?
Допустим, у тебя кубик полупрозрачный, а текстура не пустая - там картинка какая-то.
Чтобы альфабленд сработал - тебе нужны данные пикселей этой текстуры, где у тебя пиксели кубика нарисуются, чтобы их сблендить и результат получить. Для этого и нужен LoadAction.Load
Поэтому ЕСЛИ текстура не пустая И либо у тебя альфабленд, либо ты не все пиксели перерисуешь (типа будут участки не затронутые ни одним мешем - такого не бывает при блите, конечно, но вдруг у тебя не фуллскрин блит) - то тебе нужен
LoadAction.Load.
Иначе - DontCare + обязательно после установки таргета сделать cmd.ClearRenderTarget. Иначе магия может не сработать.
Store:
Обычно тебе нужно сохранять результат рендера в текстуру, иначе как бы, нафига рендер нужен, правда?
Но не всегда.
Скажем, тебе обычно не нужна глубина и стенсиль. Т.е. они тебе нужны на то время, пока ты рендеришь всякие кубики, партиклы. Но в это время глубина-и-стенсиль лежат в тайловой памяти на гпу и прекрасно выполняют свою функцию сравнения. А вот после окончания рендера тебе, допустим, только цвет и нужен. Значит для глубины можно поставить StoreAction.DontCare.
Для шедоумапы, к примеру, тебе цвет не нужен. Значит там - StoreAction.DontCare, а глубина - нужна. Там - Store.
Отдельный геморрой это MSAA. И если он включен, то с ним StoreAction'ы работают чуть иначе и менее очевидно. Но это уже другая история.
Вот так это чудо можно дебажить:
https://docs.unity3d.com/ScriptReference/Rendering.LoadStoreActionDebugModeSettings.html
Либо через рендердок
Автор: @shiko_q
Источник: https://news.1rj.ru/str/unity_cg/62577
#rendering #graphics
🔥19👍5
Между работой и работой решил написать небольшой пост :)
Почти закончил с поиском пути.
В этот раз я подошел основательно:
Во-первых, я соединил несколько подходов в один: тут и A* и FF, да и придумал как это все соединить, чтобы было производительно;
Во-вторых, это все под burst ессно и будет частью ME.BECS;
В-третьих, помимо самого поиска пути я сделал NavAgentов, которые умеют в steering и базовый rvo.
Скоро напишу больше подробностей, сейчас много работы.
stay tuned
Почти закончил с поиском пути.
В этот раз я подошел основательно:
Во-первых, я соединил несколько подходов в один: тут и A* и FF, да и придумал как это все соединить, чтобы было производительно;
Во-вторых, это все под burst ессно и будет частью ME.BECS;
В-третьих, помимо самого поиска пути я сделал NavAgentов, которые умеют в steering и базовый rvo.
Скоро напишу больше подробностей, сейчас много работы.
stay tuned
🔥75👍15❤2👏2❤🔥1🤯1👨💻1