Попалась мне статья - https://developer.nvidia.com/content/transparency-or-translucency-rendering про оптимизацию блендинга.
Кратко суть - рендерим в front-to-back с "перевернутой" blendFunction. Таким образом в работе блендинга - read/modify/write наступает момент "накопления" непрозрачности и этап modify начинает выдавать одни нули, те видимые изменения прекращаются.
Важный момент, что авторы предлагают каким-то магическим образом использовать тут Z и stencil буфера.
С этим и проблема - если подход Z чем-то похож на Depth Peeling и требует обратного чтения фреймбуфера (те не совсем понятно почему получается быстрее), то каким образом предлагается передавать альфу в стенсил – вот этот момент я совсем понять не могу.
Если ли у кого секретные знания про похожие техники оптимизации филрейта?
Kashey
> то каким образом предлагается передавать альфу в стенсил – вот этот момент я
> совсем понять не могу.
Думаю, используется типа как с маской стенсил и альфатест при DS ( в стенсил буфере отмечаются фрагменты где накоплено )
Можно ещё поиграться с StencilRef из шейдера
Таким образом нельзя передать конкретное значение прозрачности – только количество "записей" в пиксель.
Kashey
Нужно понимать вот что:
Когда ты отсортировал примитивы для блендинга - буфер глубины тебе не нужен. Т.е. если выводить такие примитивы по порядку - картинка будет нормальной. Кроме того, для under blending-а у тебя в альфакомпоненте будет хранится непрозрачность, по которой ты сможешь определить, что все, рисовать в этот пиксель уже не надо.
Теперь как сэкономить филлрейт с помощью буфера глубины (согласно NVidia):
1. Рисуешь примитив с включенным тестом, но отключенной записью в глубину.
2. Отключаешь отрисовку в колор буфер, включаешь тест глубины и запись в глубину. Затем рисуешь фуллскрин квад на near plane. В фрагментном шейдере дискардишь пиксели непрозрачность которых меньше некого трешхолда. Таким образом после этого шага у тебя все пиксели, имеющие почти 100% непрозрачность у тебя нарисуются, и в буфере глубины будет записано значение near plane. Это значит что в дальнейшем любой рендер в эти пиксели не пройдет early depth test.
3. Повторить все с шага 1 для следующего полупрозрачного примитива.
Ну вопрос тут сколько не про блендинг и его правильность, сколько именно про возможность получить early*, но с поддержкой полупрозрачных элементов. Хотя бы антиалисинга.
Перед пунктом 2, наверное, перегоняешь framebuffer в текстуру, чтобы делать из нее лукапы. Как-то уже это намекает что экономии особо не получается, даже наоборот можно еще сильнее потерять в филрейте.
Kashey
> Ну вопрос тут сколько не про блендинг и его правильность, сколько именно про
> возможность получить early*, но с поддержкой полупрозрачных элементов. Хотя бы
> антиалисинга.
early работает. Если ты только discard-ишь пиксели early не ломается. MSAA к сожалению ломается.
> Перед пунктом 2, наверное, перегоняешь framebuffer в текстуру, чтобы делать из нее лукапы.
Обрати внимание, что тебе лукап нужен только из Color буфера, а ты в этот буфер не пишешь. Поэтому тебе в render target-е не нужна color текстура, только буфер глубины. Соответственно перегонять ничего не надо. Достаточно менять рендер таргет.
> Как-то уже это намекает что экономии особо не получается, даже наоборот можно еще сильнее потерять в филрейте.
Вообще тот under blending, который описан у NVidia - сомнительная техника. Имеет смысл её использовать только в очень специфичных случаях. Например у тебя много частиц дыма, у этих частиц дыма альфа скажем 75%, частицы большие и получается большой overdraw. Тогда возможно можно будет что-нибудь выгадать за счет этой техники... но опять же, можем резко упереться в CPU за счет постоянного дерганья стейтов конвеера. Резюмируя: синтетически - данная техника может дать профит, на практике - я сильно затрудняюсь сказать где оно может дать профит.
Получается относительно выгодное решение для сглаженных элементов можно получить только через стенсил, например считая что каждый пиксель мы можем "залить" только два раза.
А жаль.
Если ты только discard-ишь пиксели early не ломается.
o_0 - Точно? Я думал discard тем и плох, что с ним early depth test не выполняется. Если это не так, то почему тогда все не любят discard?
Bave
> o_0 - Точно? Я думал discard тем и плох, что с ним early depth test не
> выполняется. Если это не так, то почему тогда все не любят discard?
Да, был не прав, discard таки ломает earlyZ. Т.е. на этапе рендера скринквада на nearplane будет вычитана вся lookup текстура... Мде. Тогда и я уже не пойму почему в вышеописанном пейпере:
Read frame buffer and discard pixels with a transmittance value lower than some threshold.
This can offer huge savings in pixel/ROP bound regimes, as the shaders won’t get invoked for pixels that have reached minimum transmittance, but in order to make sure we hit the fast path when culling pixels in this fashion, we must ensure EarlyZ is used when performing depth testing.
Don’t use ‘discard’ or ‘clip’ with depth writes enabled, but you may use them with depth writes disabled.
Технически уже сам блендинг дает достаточно сильный пенальти, чтобы не плакать об выключении early-Z.
Да и выключается он вроде для тайловых архитектур, а не стримовых.
MrShoor
> Да, был не прав, discard таки ломает earlyZ
Почему, кстати? Все время забываю.
-Eugene-
> Почему, кстати? Все время забываю.
Потому что тест глубины (по крайней мере до DX11) был совмещен с записью, т.е. был не делим. Соотвественно если discard-ишь пиксель - то он не должен записаться в буфер глубины.
Kashey
> Технически уже сам блендинг дает достаточно сильный пенальти, чтобы не плакать
> об выключении early-Z.
Хз. На моей практике блендинг не давал особо сильный пенальти. Пенальти давал филлрейт, т.к. для блендинга (тех же частиц) мы не пишем в буфер глубины, и рисуем их все, и как результат имеем дикий овердрав. Я как-то проверял для частиц, что будет если рендер не менять, а отключить только блендинг, выйгрыш был мизерный. А вот early Z при правильном использовании дает значительный прирост FPS.
> Да и выключается он вроде для тайловых архитектур, а не стримовых.
Для тайловых архитектур там вообще все печально становится. Ломание early Z заставляет мержить данные тайла.
MrShoor
В тайловых архитектурах блендинг вырубает все оптимизации так же как discard. Так что если у тебя блендинг уже включен - дискард даже поможет. Особенно с тех пор как Альфа-тест оторвали.
PS: Задача рассматривается в рамках GL ES. И не про консоли.
MrShoor
> Хз. На моей практике блендинг не давал особо сильный пенальти.
Видать ты не работал по-настоящему с блендингом ...
Тема в архиве.