Войти
ПрограммированиеФорумГрафика

IF в шейдерах

Страницы: 1 2 3 Следующая »
#0
20:17, 18 апр. 2021

Что-то слышал про то, что if-else конструкции в шейдерах это плохо.

Это так?
Как правильно написать такой код в шейдере?

  fixed4 c;
  
  if (IN.worldPos.y < _Y2)
    c = _Color2;
  else if (IN.worldPos.y > _Y1)
    c = _Color1;
  else
  {
    c = lerp(_Color1, _Color2, (IN.worldPos.y - _Y1) / (_Y2 - _Y1));
  }


#1
20:27, 18 апр. 2021

Vogd2
> Что-то слышал
10 лет назад слышал?

#2
20:40, 18 апр. 2021

Суслик, не хочешь прочитать лекцию ?

#3
(Правка: 20:52) 20:41, 18 апр. 2021

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

Обычно условные переходы заменяются на lerp/step конструкции. В твоем случае это будет что-то монструозное типа:

fixed k1 = step(_Y2, IN.worldPos.y);
fixed k2 = step(IN.worldPos.y, _Y1) * step(0.9, k1);
fixed k3 = step(0.9, k1 + k2);

fixed4 c = _Color2 * k1 + _Color1 * k2 + lerp(_Color1, _Color2, (IN.worldPos.y - _Y1) / (_Y2 - _Y1)) * k3;

#4
(Правка: 21:20) 21:12, 18 апр. 2021

основная проблема динамического ветвления-отсутствие инструментов для оценки результатов его работы, в итоге всё сводится к синтетическим сравнениям что быстрее 100к с динамическим ветвлением или 100к без него?
что дороже динамическое ветвление или чтение текстуры?
что дороже динамическое ветвление или растеризация?
....
есть некоторый обьём докладов но они сумбурны и неоднозначны :(

просто if() мало...https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-if

#5
21:41, 18 апр. 2021

> Как правильно написать такой код в шейдере?

c = lerp(_Color1, _Color2, clamp((IN.worldPos.y - _Y1) / (_Y2 - _Y1), 0, 1));

#6
23:56, 18 апр. 2021

Vogd2
Что значит "плохо"? Медленно?
Во первых для подобной конструкции (присвоение значения вектору) о времени вообще заботится нет смысла ибо оно тут пренебрежимо мало.
Во вторых это утверждение (условия в шейдере это плохо) имело смысл много лет назад. В те времена сначала все ветки выполнялись, а уже потом выбирался результат сообразно условию. Но это уже давно не так. Так что не парь себе мозги.

#7
6:14, 19 апр. 2021

Vogd2
> Что-то слышал про то, что if-else конструкции в шейдерах это плохо.
такие if-ы это плохо не только в шейдерах, а в любом коде. только не потому что ты думаешь, а потому что они создают видимость ветвления в коде, в котором ветвления на самом деле нет. то, что тебе нужно, делается через saturate или через clamp, как написал phridrich — это и читать проще и ошибиться сложнее, и бренч в этом случае не имеет смысла.

#8
(Правка: 6:34) 6:19, 19 апр. 2021

Battle Angel Alita
> 10 лет назад слышал?
прямо сегодня твои дрова нвидии могут тихонечко перекомпилить несколько копий твоего шейдера, инлайня, например, bool-константы, когда им вздумается. потом ты смотришь на fps счётчик в своём коде и заявляешь — вау, это работает быстрее, чем на амд/консолях. а потом с продакшена тебе приходят статы, что иногда upload шейдера занимает 100ms в первый раз, потому что управление передаётся драйверу нвидии, которое в это время в одном realtime потоке втихую генерит копию твоего шейдера с заинлайненной константой. разумеется, это даже никак не отобразится на твоём профайлере, потому что 100мс вообще не в твоём потоке съедено. и, разумеется, ты это даже воспроизвести не сможешь, потому что это происходит только при первой загрузке, а потом шейдеры берутся из неведомого кеша.

поэтому если ты где-то уверен, что branch тебе не понадобится, имеет смысл лишний раз подумать, нужен ли тебе для этого именно if.

#9
7:12, 19 апр. 2021

Понял, спасибо!

#10
8:57, 19 апр. 2021

Suslik
> инлайня, например, bool-константы

можно пример таких кейсов с дизассемблером кода?

#11
9:04, 19 апр. 2021

innuendo
> можно пример таких кейсов с дизассемблером кода?
ты ни на каком этапе не увидишь код, который исполняет твоя видюха (я не знаю, как его смотреть на PC), потому что эта перекомпиляция выполняется драйвером при загрузке уже скомпиленного шейдера (имеется в виду скомпиленный d3d шейдер или spirv). есть всего три косвенных показателя, по которым это можно установить
1) на нвидии бренчи с uniform bool'ами не имеют цены в рантайме. она не то что низкая, её нет вообще. на любой AMD видюхе эта цена не велика, но её вполне можно измерить.
2) первая загрузка нового шейдера занимает на порядок больше времени, чем последующие. причём время крадётся драйвером нвидии вообще в другом процессе.
3) мы оказались вовсе не единственными разработчиками, по которым это ударило: https://www.reddit.com/r/DestinyTechSupport/comments/jtyqj9/havin… _nvidia_card/ .

#12
(Правка: 9:12) 9:11, 19 апр. 2021

Suslik
> я не знаю, как его смотреть на PC

Shader Analyzer на AMD?

> мы оказались вовсе не единственными разработчиками, по которым это ударило:

думаешь, я не сталкивался с этим ?

это старая больная тема uber vs bool switching

#13
9:16, 19 апр. 2021

Suslik
> дрова нвидии
innuendo
> Shader Analyzer на AMD?

#14
10:00, 19 апр. 2021

Suslik
> причём время крадётся драйвером нвидии вообще в другом процессе.
Они еще используют свой кэш шейдеров который никак не отключить. У меня были проблемы, когда я менял только константу, шейдер не менялся, пока не перезапустишь приложение.

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумГрафика