Replecement shader

Шейдеры и все-все-все.

Replecement shader

Сообщение kripto289 20 июл 2016, 01:19

Пытаюсь разобраться с replacement shader на камере.
Кто-нибудь в курсе как это работает? Так и не разобрался. Буду очень рад простому примеру.
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Replecement shader

Сообщение waruiyume 20 июл 2016, 01:46

Страницу справки починили http://docs.unity3d.com/Manual/SL-Shade ... ement.html (собственно ничего не добавишь).
В прошлый раз когда я тута заходил там было пусто.
Очень наглядный демо проект юнитеков https://www.assetstore.unity3d.com/en/#!/content/5145(искать его пришлось с собаками, комментах пишут, что он не 100% рабочий, но думаю, что копипастить из него можно и сейчас.)

Ещё один пример, в нём с помощью Replecement shader создаётся маска для объектов, в шейдере которых указан определённый тег.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Replecement shader

Сообщение kripto289 20 июл 2016, 09:19

waruiyume писал(а):Страницу справки починили http://docs.unity3d.com/Manual/SL-Shade ... ement.html (собственно ничего не добавишь).
В прошлый раз когда я тута заходил там было пусто.
Очень наглядный демо проект юнитеков https://www.assetstore.unity3d.com/en/#!/content/5145(искать его пришлось с собаками, комментах пишут, что он не 100% рабочий, но думаю, что копипастить из него можно и сейчас.)

Ещё один пример, в нём с помощью Replecement shader создаётся маска для объектов, в шейдере которых указан определённый тег.

Справка это первое что я открываю.
Мне не понятен сам процесс. Вот например что есть эта строка? " maskCamera.RenderWithShader(maskShader, "RenderType");"
Выбираются все объекты с RenderType? Wat? Какой смысл от такого свойства, если все шейдера имеют RenderType? Как рендирить только определённые сабшейдеры? Например с тегом "renderType"="blabla"?
За ссылки спасибо, буду разбираться.
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Replecement shader

Сообщение waruiyume 20 июл 2016, 12:56

Дык, там же ниже есть пример.
Допустим, у Вас на сцене есть объекты с "RenderType"="Opaque" и "RenderType"="blabla"
При отрисовке с заменой, сабшейдеры объектов на сцене "заменяются" сабшейдерами из шейдера который передаётся в первом параметре. Во втором параметре, фактически, указывается переменная, которая должна совпасть в сабшейдере на сцене и сабшейдере эффекта.
Синтаксис:
Используется glsl
Shader "EffectShader" {
     SubShader {
         Tags { "RenderType"="Opaque" }
         Pass {
             //рисовать с красной заливкой
         }
     }
     SubShader {
         Tags { "RenderType"="blabla" }
         Pass {
             //рисовать кислотный трип
         }
     }
 ...
 }
 
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Replecement shader

Сообщение kripto289 20 июл 2016, 14:38

waruiyume писал(а):Дык, там же ниже есть пример.
Допустим, у Вас на сцене есть объекты с "RenderType"="Opaque" и "RenderType"="blabla"
При отрисовке с заменой, сабшейдеры объектов на сцене "заменяются" сабшейдерами из шейдера который передаётся в первом параметре. Во втором параметре, фактически, указывается переменная, которая должна совпасть в сабшейдере на сцене и сабшейдере эффекта.
Синтаксис:
Используется glsl
Shader "EffectShader" {
     SubShader {
         Tags { "RenderType"="Opaque" }
         Pass {
             //рисовать с красной заливкой
         }
     }
     SubShader {
         Tags { "RenderType"="blabla" }
         Pass {
             //рисовать кислотный трип
         }
     }
 ...
 }
 

Во втором параметре renderWithShader как раз совпадает "RenderType" с обоими сабшейдерами выше. Судя по справке выше, он заменит первое вхождение. А если я хочу заменить только 2-ой сабшейдер? Что мне писать?
У меня не было бы проблем, если бы все писали "renderWithShader(shader, "blabla")", тогда ясно что он заменяет. Ну или так "renderWithShader(shader, "RenderType=blabla")",

Вообще мне кажется я не той дорогой иду. У меня есть некий объект с шейдером (у которого определённый тег, блабла например), и мне надо что бы камера с RenderTarget не отрисовывала этот объект. Юзать слои не могу, так как их нельзя создать в рантайме. Получится ли у меня с заменой шейдера игнорить отрисовку, если я пропишу аддитивный шейдер с 0 альфой?
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Replecement shader

Сообщение waruiyume 20 июл 2016, 14:49

Получится ли у меня с заменой шейдера игнорить отрисовку, если я пропишу аддитивный шейдер с 0 альфой?

Нет, такое сделать не получится, поскольку, будут отрисованы только заменённые, т.е. Вам придётся дублировать все используемые шейдеры, что, явно, крайне затруднительно.
В смысле, нельзя создавать рантайм, всегда же есть 32 слоя, и ни больше ни меньше сделать слоёв не получится?

Может просто задефайнить в шейдере участок который будет делать discard или возвращать цвет с нулевой альфой, и включать ключевое слово при надобности?

А вообще, не проще вырубить рендерер?
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Replecement shader

Сообщение kripto289 20 июл 2016, 16:03

waruiyume писал(а):
Получится ли у меня с заменой шейдера игнорить отрисовку, если я пропишу аддитивный шейдер с 0 альфой?

Нет, такое сделать не получится, поскольку, будут отрисованы только заменённые, т.е. Вам придётся дублировать все используемые шейдеры, что, явно, крайне затруднительно.
В смысле, нельзя создавать рантайм, всегда же есть 32 слоя, и ни больше ни меньше сделать слоёв не получится?

Может просто задефайнить в шейдере участок который будет делать discard или возвращать цвет с нулевой альфой, и включать ключевое слово при надобности?

А вообще, не проще вырубить рендерер?

Расскажу суть.
У меня есть шейдер с искажениями. Он должен работать как на ПК, так и на мобилках.
Примерно такой констуркции
Subshader {
GrabPass{}
Pass{}
}

Дефайнами я не могу закрыть секцию grabpass. (которая глючит на мобилках). Lod не пойдёт (у меня куча разных шейдеров, как их все выбрать? по какому признаку?)
Опустим этот момент. Я делаю костыль - я создаю второй шейдер без grabpass. Вместо текстуры из бэкбуфера я рендерю в renderTarget и передаю как текстуру в шейдер.
Возникает проблема, ибо камера захватывает объект. Выходит рекурсивная картинка.
Для игнорирования я не могу использовать слои. Код переносимый, а слои перенести нельзя. Более того, если не объекте висит несколько материалов среди которых мой, то слой закроет отрисовку всех остальных материалов. (тот же эффект льда на скинед поверхности например, уже не создать).
Слои кстати можно создавать только в редакторе, и я даже не представляю как они переносятся в другой проект с другим кол-вом слоёв. Там ведь сравнение слоёв побитовое и всё полетит к чертям?
Последний раз редактировалось kripto289 20 июл 2016, 16:56, всего редактировалось 2 раз(а).
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Replecement shader

Сообщение waruiyume 20 июл 2016, 16:24

Слои кстати можно создавать только в редакторе

Слои нельзя создавать в принципе, ни в редакторе, ни в рантайме, можно только назначить им имя. Если у слоя не имени это не значит, что слой не существует.

Ну, так не используйте GrabPass, разве нельзя отрендерить с цену в OnPrerender в текстуру, предварительно выключив ненужные рендереры?
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Replecement shader

Сообщение kripto289 20 июл 2016, 16:50

waruiyume писал(а):
Слои кстати можно создавать только в редакторе

Слои нельзя создавать в принципе, ни в редакторе, ни в рантайме, можно только назначить им имя. Если у слоя не имени это не значит, что слой не существует.

Ну, так не используйте GrabPass, разве нельзя отрендерить с цену в OnPrerender в текстуру, предварительно выключив ненужные рендереры?

Как выключить рендеры не юзая слои? Так?

public void OnPreRender ()
{
this.renderer.enabled = false;
}
public void OnPostRender ()
{
this.renderer.enabled = true;
}
Но ведь объект не будет рендириться вообще. А если висит 2 материала, то мне надо рендирить объект только с 1 материалом. Как вариант, если не юзать несколько материалов на меше, пойдёт.
Заменой шейдера сами сказали что не выйдет. Я не работал с камерами и постэффектами, пока это для меня тёмный лес.

Можно ли такое провернуть стенсил буфером:?
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Replecement shader

Сообщение waruiyume 20 июл 2016, 17:05

Так:
Синтаксис:
  1. void OnPreRender ()//Вызывается только для камеры 
  2.    ВыключитьТоЧтоНеНужно(); 
  3.    ОтрендеритьКамеруВтекстуру(); 
  4.    ВключитьНенужноеОбратно(); 

В этом случае фокус в дефайнами должен сработать, GrabPass же не будет использоваться.

Можно ли такое провернуть стенсил буфером:?

По идеи можно, нужно в самом начале нарисовать прямоугольник на весь экран, который бы изменял значение буфера. Правда, я не уверен, что на всех платформах это будет работать одинаково.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Replecement shader

Сообщение kripto289 20 июл 2016, 17:33

waruiyume писал(а):Так:
Синтаксис:
  1. void OnPreRender ()//Вызывается только для камеры 
  2.    ВыключитьТоЧтоНеНужно(); 
  3.    ОтрендеритьКамеруВтекстуру(); 
  4.    ВключитьНенужноеОбратно(); 

В этом случае фокус в дефайнами должен сработать, GrabPass же не будет использоваться.

Можно ли такое провернуть стенсил буфером:?

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

О точно, вообще не подумал что я могу не только объект вырубать, а но и манипулировать его материалами и дефайнами. Спасибо!

Дабы не засорять темы, ещё вопрос. В юньке нет способа получить в рантайме все объекты с определённым шейдером без манипуляций с именем? Например по тегу или ещё как-то? (это что бы повесить скрипт на те объекты, у которых есть подобный шейдер).
И ещё, зачем вообще нужны ключи для шейдерных тегов? Replacement шейдер всё равно игнорирует значения ключей.
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт

Re: Replecement shader

Сообщение waruiyume 20 июл 2016, 18:11

Найдите все рендереры Object.FindObjectsOfType, а потом отсейте по шейдеру из используемых материалов.

Replacement шейдер всё равно игнорирует значения ключей.

Вы чего-то путаете.
У вас нет доступа для просмотра вложений в этом сообщении.
Аватара пользователя
waruiyume
Адепт
 
Сообщения: 6143
Зарегистрирован: 30 окт 2010, 05:03
Откуда: Ростов на Дону

Re: Replecement shader

Сообщение kripto289 20 июл 2016, 21:24

waruiyume писал(а):Найдите все рендереры Object.FindObjectsOfType, а потом отсейте по шейдеру из используемых материалов.

Replacement шейдер всё равно игнорирует значения ключей.

Вы чего-то путаете.

Всё я разобрался как это работает. Теперь понятно как юнити рендирит forward base и всякие другие проходы.
Спасибо за помощь!
Аватара пользователя
kripto289
UNIверсал
 
Сообщения: 476
Зарегистрирован: 30 сен 2013, 03:30
Откуда: Екатеринбург
  • Сайт


Вернуться в Shader Lab

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6