Глава первая

Подробный разбор простейшего шейдера

Пример простейшего шейдера:

Shader "Tutorial/Simpliest" // Shader - обязательное начало для любого шейдера, 
                             // после этого ключевого слова в
							 // кавычках пишется url-подобное имя шейдера
{
	Properties // блок свойств, которые будут отображаться во вкладке 
               //  inspector в Unity
	{
		_Color ("Color", Color) = (0.5,0.6,0.7,1)
		//Каждая строка связана с переменной и содержит следующие данные:
		// _Color - имя переменной, оно должно совпадать по написанию с 
        //          одной из переменных внутри CGPROGRAM
		// "Color" - текст, который будет отображаться в окне 
        //           Inspector перед значением переменной
		// Color - тип данных, от него зависит как будет выглядеть 
        //         блок выбора значения в Inspector, бывает
		//         5 типов данных: 
		//         Color - выглядит как выбор цвета, 
		//         Vector - как 4 текстовых поля ввода,
		//         Float - поле ввода одного числа с плавающей запятой, 
		//         2D - текстура, 
		//         CUBE - выбор кубической текстуры
		// (0.5,0.6,0.7,1) - значение переменной по умолчанию
	}
	SubShader // в одном шейдере может быть несколько этих блоков, 
              // но одновременно работать может только один
	{
		// No culling or depth
		// Это зарезервированные слова, в этом шейдере они указаны 
        // для упрощения работы GPU, благодаря им потребуется меньше 
        // вычислений для отображения шейдера, а ZTest Always говорит 
        // о том, что этот шейдер будет рисовать объект поверх всех остальных
		Cull Off 
		ZWrite Off 
		ZTest Always

		Pass // этих блоков может быть несколько внутри одного SubShader,
             // каждый Pass это отдельный проход рендера по объекту с этим 
             // шейдером, результат следующего Pass рисуется поверх предыдущего
		{
			CGPROGRAM // Зарезервированное слово, оно лишь отмечает начало 
                      //  кода самого шейдера

			#pragma vertex vert_img // использовать для вертексного шейдера 
                                     // vert_img, которая описана не нами
			#pragma fragment frag   // для фрагментного шейдера использовать 
                                     //функцию frag, описанную ниже
			
			#include "UnityCG.cginc" // позволяет нам использовать готовые функции, 
                                      // написанные командой Unity
			                          // в их числе и vert_img, код файла можно найти 
                                      // в файле:
		                              // %UNITY%\Editor\Data\CGIncludes\UnityCG.cginc

			fixed4 _Color; // fixed4 - тип переменной, именно этот тип представляет 
                           // собой структуру из 4х переменных типа fixed

			fixed4 frag (v2f_img i) : COLOR
			{
				fixed4 col = _Color;
				return col;
			}
			ENDCG // Зарезервированное слово, оно отмечает конец кода самого шейдера
		}
	}
}

Более полное описание строк "Cull Off ZWrite Off ZTest Always" можно найти по этому адресу

В приведённом выше коде без комментария осталась самая главная функция:

fixed4 frag (v2f_img i) : COLOR
{
    fixed4 col = _Color;
    return col;
}

первая строка это объявление функции, последующие это её тело, разберём суть написанного:

fixed4 - это тип данных, которые функция вернёт операцией return, для фрагментного шейдера это всегда цвет, fixed это самый маленький из типов данных(каждый элемент структуры в fixed4 занимает 11 бит, а целиком структура занимает 44 бита), используемых для представления дробных чисел, обычно fixed4 хватает для любого цвета, в редких случаях используется half4, который требует немного больше памяти(16 бит на элемент) и используется он для работы с расширенным диапазоном цветов, когда нужно получить эффекты яркого солнца или какой-то похожий эффект. float это самый большой тип данных(32 бита на элемент), используется для хранения данных развёртки, позиции в мировых координатах или для вычисления сложных функций, таких как тригонометрические функции, экспоненциирование или возведение в степень.

После fixed4 и до открывающей скобки идёт имя функции, его задаём мы, то, которое нам нравится. v2f_img - это тип данных, который является выходным от вертексного шейдера и входным для нашего фрагметного.

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

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

Полный список стандартных семантических значений можно узнать по ссылке: документация Microsoft

Дальше идёт тело функции, но оно мало чем отличается от обычной функции в C#, следует упомянуть только, что мы никак не используем данные полученные из вертексного шейдера и без каких-либо вычислений возвращаем фиксированный цвет.

Last updated