Введение

Объяснение основных принципов исполнения шейдеров и ссылка на скачивание проекта к уроку

Перед прохождением урока скачайте проект(создан в Unity 5.3.3).

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

Любой 3D объект состоит из массива вершин, каждая вершина обладает следующими данными: позиция, нормаль, координаты развёртки и иногда цвет. Помимо этих данных почти всегда на объект накладывается текстура или совмещается несколько текстур.+

Всё описанное выше это входные данные. Чтобы превратить их в картинку на экране нужно пройти два этапа:

1) Обработать каждую вершину(как минимум преобразовать её мировую координату в экранную, путём умножения мировой координаты на матрицу вида камеры)

2) Обработать каждый видимый пиксель объекта.

Представить себе работу шейдера можно следующим псевдокодом:

for(int i=0; i < vertices.length; i++)
{
    vertex_shader(vertices[i]);
}
for(int j=0; j < pixels.length; j++)
{
    fragment_shader(pixel[i]);
}

Шейдеры, написанные для Unity, можно разделить грубо на две части. Одна часть surface, а вторая vertex/fragment. Surface шейдеры созданы для упрощения написания шейдеров и скрывают некоторые рутинные шаги. И в конечном итоге любой surface шейдер интерпретируется в vertex/fragment. vertex/fragment шейдер обязательно содержит две функции, одну vertex(вертексный или вершинный) шейдер, а вторую fragment(фрагментный или пиксельный) шейдер. Бывает так, что шейдер содержит описание только фрагментного шейдера, на самом деле он использует оба, но в качестве вертексного задаётся типичный вертексный шейдер, написанный командой Unity.+

Любой шейдер имеет примерно следующую структуру:

Shader "Shader\Name"                         
{
    Properties 
    {
    В этом блоке описываются все свойства, которые будут отображены в окне 
    инспектора свойств юнити
    }
    SubShader
    {
    А этот блок может дублироваться для обеспечения совместимости, или экономии 
    ресурсов при рисовании    дальних объектов, но при рендере картинки только 
    один из этих блоков будет работать. На этом моменте не стоит заострять внимания, 
    просто стоит знать, что этих блоков может быть несколько, но обычно одного 
    хватает для большинства задач.
        Pass
        {
        Этот блок описывает один проход рендера, их может быть несколько, но 
        надо учитывать, что каждый проход рисуется поверх предыдущего и если 
        последующие проходы не будут прозрачными, то они полностью зарисуют 
        все предыдущие. И некоторые данные будут сохранять свои изменения между
        проходами, например позиция вершин.
        }
    }
}

Last updated