Шейдеры в Unity
Шейдеры в Unity пишутся на специальном языке, который называется ShaderLab. Язык этот не сложный и в этой статье я его попытаюсь описать.
Конечно большая часть этого урока – содержание справки Unity, но так как у многих проблемы с английским – этот урок будет полезным.
Синтаксис шейдера на языке ShaderLab
PHP код:
// Блок Shader – коневой блок // он является контейнером для описания шейдера // через пробел в кавычках указывается имя шейдера Shader "Имя_шейдера" {
// Блок параметров, которые пользователь может визуально // настраивать в инспекторе, при выборе данного шейдера // для материала. Все параметры, описанные в блоке Properties // в остальных местах шейдера должны применяться // в квадратных скобках. Properties { // Список параметров // например, следующая строка описывает параметр _Color // отображаемый в инспекторе как "Main Color" типа // Color с начальным значением (1,.5,.5,1): _Color ("Main Color", Color) = (1,.5,.5,1)
// Unity не поддерживает отображение типа Matrix4x4 // но не смотря на это его можно передавать в шейдер // программным путем. // _SpecColor ("Spec Color", Color) = (1,1,1,1) _Emission ("Emmisive Color", Color) = (0,0,0,0) _Shininess ("Shininess", Range (0.01, 1)) = 0.7 _MainTex ("Base (RGB)", 2D) = "white" {} }
// SubShader – контейнер, определяющий технику // визуализации материала. // Блоков SubShader может быть много, Unity выбирает // первый подходящий шейдер для видеокарты пользователя SubShader {
// Pass – блок, описывающий один проход визуализации // для сложных материалов таких проходов может быть несколько Pass {
// Блок Material назначает параметры материала, // которые будут использованы при расчете освещения. // например, в данном примере устанавливаются все // параметры, необходимые для полноценного вершинного // освещения. Material { Diffuse [_Color] Ambient [_Color] Shininess [_Shininess] Specular [_SpecColor] Emission [_Emission] }
// Директива Lighting On|Off определяет // использование освещения. // Для того чтобы установленные значения блока // Material имели силу – освещение должно быть включено Lighting On
// Директива SeparateSpecular определяет, стоит ли // добавлять зеркальную (бликовую) составляющую в // конце прохода. Чтобы директива имела силу – // освещения должно быть включено (Lighting On) SeparateSpecular On
// дополнительные директивы будут описвны ниже
// Блок SetTexture устанавливает текстуру и метод // ее наложения. После названия блока SetTexture // в квадратных скобках передается имя параметра, // указанного в блоке Properties. // Внутри блока может присутствовать от одной // до трех команд (Combine, Matrix и ConstantColor). // Количество текстурных слотов у разных видеокарт // разное, так что количество блоков SetTexture // должно выбираться в зависимости от того, какие // видеокарты Вы хотите поддерживать. Например, // видеокарты NVIDIA TNT2, GeForce 256, GeForce 2, // GeForce 4MX имеют 2 текстурных блока, а такие как // ATI Radeon 9500 и выше – 4 для D3D и 6-8 для OpenGL SetTexture [_MainTex] {
// Возможности команды Combine можно посмотреть // в справке, замечу, что расчет альфы и цвета // можно разделить. Формулы комбинации цветов // записываются в это случае через запятую. Combine texture * primary DOUBLE, texture * primary } } }
// Директива Fallback определяет то, как поведет себя Unity, // если ни одна из техник, определенных в блоках SubShader // не поддерживается видеокартой. // Имеется две формы записи директивы: // Fallback Off – отключает любые предупреждения о том, что // ни один из SubShader не поддерживается // Fallback "имя_шейдера" – передает все параметры (Properties) // и управление другому шейдеру. Fallback "Имя_другого_шейдера" }
Файл шейдера должен иметь кодировку ASCII.
Приведенный в качестве описания синтаксиса шейдер является аналогом материала, используемого в Blitz3d.
Как и обещал, привожу список основных директив блока Pass:
- Cull Back | Front | Off
Устанавливает тип куллинга полигонов. - ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
Устанавливает режим теста глубины. - ZWrite On | Off
Устанавливает режим записи глубины. - Fog { блок описания тумана }
Устанавливает параметры тумана. - AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
Включает альфатест. - Blend SourceBlendMode DestBlendMode
Устанавливает режим альфасмешивания. - Color Color value
Устанавливает цвет, если вершинное освещение отключено. - ColorMask RGB | A | 0 | любая комбинация R, G, B, A
Маска записи цвета. ColorMask 0 выключает рендеринг для всех цветовых каналов. - Offset OffsetFactor , OffsetUnits
Устанавливает офсет (смещение) глубины. - ColorMaterial</strong> AmbientAndDiffuse | Emission
Использует цвета вершин для расчета освещения.
Шейдерные программы
Так же существует возможность применять шейдерные программы, написанные на языке Cg для сложных материалов, в которых необходимы специфические расчеты. Для этого вместо или внутри блока Pass необходимо использовать блок CGPROGRAM
PHP код:
CGPROGRAM // директивы компиляции: #pragma vertex vert #pragma fragment frag
// Cg код
ENDCG
#pragma vertex и #pragma fragment определяют соответственно вершинную и фрагментную функции. Существует так же #pragma target, значениями которой могут быть default и 3.0. В первом случае для компиляции используются vs 1.1 и ps 2.0, во втором – vs 3.0 и ps 3.0. При компиляции для 3.0 – обе директивы #pragma vertex и #pragma fragment должны присутствовать.
Подробнее об этом ShaderPrograms
В Unity 3 появились новые возможности для реализации шейдеров – Surface Shaders. Используя эти возможности можно облегчить себе жизнь при написании шейдеров на языке Cg. Подробнее - SurfaceShaders, примеры таких шейдеров.
Конечно же я не могу охватить все возможности языка ShaderLab, надеюсь и этого хватит, чтобы понять его структуру и двигаться дальше. Удачи!
Более углубленно ShaderLab можно изучить читая справку ;)
UPD: Так же хорошей практикой будет разбор встроенных шейдеров юнити
|