Как лучше всего разбить шейдерную логику на компоненты, которые можно смешивать и сопоставлять - PullRequest
0 голосов
/ 11 июня 2018

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

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

С материалами, в которых можно использовать только один шейдер, каков наилучший метод для "объединения" в цепочку нескольких шейдеров, подобных этой?Из всего, что я прочитал, подход де-факто заключается в том, чтобы в основном написать шейдер для каждой комбинации функций, который выглядит как кошмар обслуживания, если у вас много разных, разрозненных шейдеров, которые появляются в разных перестановках.

1 Ответ

0 голосов
/ 12 июня 2018

Вы можете сделать это ... вроде

Вот в чем дело: у любого данного объекта может быть только 1 материал 1 , а у любого данного материала может быть только 1 шейдер.

Итак, вы можете выбрать следующие параметры:

  • Несколько материалов (использование значений шейдеров для настройки свойств)
  • Несколько материалов (использование нескольких разных шейдеров)
  • Теги SubShader

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

Например, у меня есть этот шейдер (в проекте, над которым я не работал некоторое время):

Shader "Custom/Wallhack" 
{
    Properties 
    {
        _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
        _WireColor("WireColor", Color) = (1,0,0,1)
        _Color("Color", Color) = (1,1,1,1)
        _HighlightColor("HighlightColor", Color) = (1,0,0,1)
        _HighlightSize("Highlight Size", float) = 4
    }
    SubShader 
    {
        Tags { "Queue"="Transparent" "Wallhack"="1" }
    }
    SubShader 
    {
        Tags { "Queue"="Transparent" "Wallhack"="2" }
    }
    SubShader 
    {
        Tags { "Queue"="Transparent" "Wallhack"="3" }
    }
}

Просто предположим, что у этих подшейдеров есть записи Pass с методами geom, vert или frag, а также некоторые другие теги опущены.Включение всего этого сделало бы пример слишком длинным.В этом случае:

  • "Wallhack"="1" - это стандартный путь рендеринга (не виден за стенами)
  • "Wallhack"="2" - контур выделения (для выделения мыши)
  • "Wallhack"="3" - это полный каркасный контур, видимый через другую геометрию

Ничего не делая, единственный проход, который рендерится, является первым (материал имеет тег, установленный в 1).Но вызывая render.material.SetOverrideTag("WallHack","3"); для компонента Renderer объекта, он вместо этого рендерится с каркасной частью шейдера.

Примечание: Я не знаюкакие виды рендеринга накладных тегов subhader вызвали, но я думаю, что это не очень хорошо (ломает пакет, клонирует материал и т. д.).Я давно с этим не связывался.

1 Ну, вроде как.Некоторые объекты имеют подсетки, которые могут иметь свои собственные материалы, но в целом: 1 сетка, 1 материал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...