Мы знаем, что if в шейдере - плохо. На самом деле бывает плохо, а бывает и нормально. Тут зависит от условия и что мы в нем делаем. Но я предпочитаю не полагаться на компилятор, а просто не использовать if-конструкции.

Давайте разберем простой пример:

half4 color = ...;
if (color.a < _Threshold) {
     color = float4(1, 0, 0, 1);
}

Если альфа у нас меньше чем какое-то значение, то закрасим красным цветом, если больше - оставим цвет как был.

Реальный код может быть сложнее, могут быть вложенные if-конструкции и т.д.

По сути это не важно, т.к. решение будет схожим. Для простоты заменим результат работы условия на XXX, т.к. нам не важно что там будет - функция, еще одно условие или какие-то другие хитрые вычисления:

if (color.a < _Threshold) {
    color = XXX;
}

Теперь разберемся с условием, давайте перенесем все в одну сторону:

color.a - _Threshold < 0

Теперь наша задача записать все в одну строку:

color = lerp(XXX, color, color.a - _Threshold);

Т.е. мы возьмем XXX, если значение будет ноль и оставим color, если значение будет единица.

Теперь нам нужно избавиться от этой "плавности", одним из способов это сделать - добавить 0.5 и выполнить round (можно еще +0.5 и floor):

color = lerp(XXX, color, round((color.a - _Threshold) + 0.5));

Таким образом мы избавились от условия, чего и добивались :)


Читать далее  

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

Читать далее  

Если вам нужен сильный full-screen blur эффект, можно использовать буффер из нужной камеры и шейдер с tex2Dlod для чтения текстуры маленького размера, тем самым будет казаться, что размытие достигается шейдером, хотя на самом деле этот эффект будет от текстуры низкого разрешения + фильтрации. 

На практике мы такое используем для фона в UI, чтобы сильно "размывать" задний фон.

Читать далее  

Если у вас в проекте есть много Skinnedmesh-анимаций (например, у вас в лесу бегает много животных), то их анимацию можно запечь в текстуру, откуда читать шейдером. Такие анимации будут работать довольно с абсолютной погрешностью, но для объектов окружения этого может быть вполне достаточно. Такое решение намного производительнее, т.к. Работает с одной текстурой и укладывается в один DrawCall.

Читать далее