Shader "Tutorial/Texture"{ Properties {_MainTex("Texture",2D) ="white" {} // В предыдущей части в качестве свойства был цвет, // а теперь текстура, в Inspector будет предложено // выбрать одну. Здесь "white" это значение по умолчанию, // означает, что будет создана текстура белого цвета. } SubShader { Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM#pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc"sampler2D _MainTex; // sampler2D - это тип переменной который надо ставить когда // мы хотим работать с текстурой, заметьте, что имя переменной // _MainTex совпадает с именем свойства в блоке Properties, // это обязательно для корректной работы.fixed4frag(v2f_img i) : COLOR { // Следующая строка позволяет нам получить цвет пикселя в точке // с которой мы работаем в этой итерации, если помните, то ранее // было сказано, что фрагментный шейдер работает с каждым видимым // пикселем объекта. // tex2D - это готовая функция для получения значения цвета, // первый параметр (_MainTex) это из какой текстуры мы хотим // получить цвет, а второй (i.uv) это UV координаты в которых // мы хотим узнать цвет.fixed4 col =tex2D(_MainTex,i.uv); col =1- col; // Инверсия цвета, цвет в шейдере представлен 4-мя компонентами // RedGreenBlueAlpha - КрасныйЗелёныйСинийНепрозрачность, // причём значение каждого компонента в диапазоне от 0 до 1return col; } ENDCG } }}
col =1- col;
В записанной выше строке есть скрытая работа, как уже было сказано ранее, fixed4 это структура состоящая из 4х элементов типа fixed, более того мы можем обратиться к каждому элементу по отдельности, вот так: col.r, или col.g, или col.b, или col.a, более того, можно обращаться к паре или тройке элементов: col.rgb или col.ba.
У цветового rgba есть синоним из мира геометрии xyzw, они абсолютно эквивалентны и, даже если вы работаете с цветами, к ним можно обращаться через xyzw, но чтобы не создавать двусмысленности xyzw лучше использовать с координатами. Вернёмся к вопросу о скрытой работе.
col =1- col;
На самом деле означает, что будет сделано следующее:
Следующий шейдер берёт соответствующие пиксели двух картинок и интерполирует цвет этих пикселей между собой формируя таким образом результирующую картинку.
Shader "Tutorial/ImageMerger"{ Properties { // В этом шейдере нам понадобится две текстуры и одна // переменная для указания степени смешивания_FirstTex("First Texture",2D) ="white" {}_SecondTex("Second Texture",2D) ="white" {}_LerpFactor("Lerp Factor",Range(0,1)) =0.5 // Это свойство можно было объявить иначе // _LerpFactor("Lerp Factor", Float) = 0.5 // но слайдер удобнее для пользователя, чем поле ввода } SubShader { Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM#pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc"sampler2D _FirstTex;sampler2D _SecondTex;float _LerpFactor;fixed4frag(v2f_img i) : COLOR {fixed4 firstColor =tex2D(_FirstTex,i.uv);fixed4 secondColor =tex2D(_SecondTex,i.uv); firstColor =lerp(firstColor, secondColor, _LerpFactor);return firstColor; } ENDCG } }}
lerp - это готовая функция, которая принимает две переменные, которые надо между собой интерполировать и одну переменную, которая укажет степень их интерполяции. Чтобы понять работу этой функции, представьте себе две точки на бумаге и проведите отрезок от первой точки ко второй, а _LerpFactor скажет где на этом отрезке поставить третью точку, которая и будет результатом функции, если _LerpFactor = 0, то результат будет совпадать с первой точкой _LerpFactor = 1, результат совпадёт со второй, а _LerpFactor = 0.5 укажет точно на середину отрезка.
Наложение одной текстуры поверх другой
Ещё один шейдер исключительно для примера того, что можно сделать. Он берёт одну картинку, а поверх неё накладывает другую так, чтобы были едва видны очертания накладываемой картинки. По схожему принципу работает фильтр Overlay в фотошопе.
Shader "Tutorial/NoiseOverlay"{ Properties {_MainTex("Main Texture",2D) ="white" {}_NoiseTex("Noise Texture",2D) ="white" {}_NoiseStrength("Noise Strength",Range(0,1)) =0.5 } SubShader { Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM#pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc"sampler2D _MainTex;sampler2D _NoiseTex;float _NoiseStrength;fixed4frag(v2f_img i) : COLOR { half4 base =tex2D(_MainTex,i.uv);half4 overlay =tex2D(_NoiseTex,i.uv);float4 effect =lerp(1-2* (1- base) * (1- overlay), (2* base) * overlay,step(base,0.5f)); // step(a, x) = 0 если x < a // step(a, x) = 1 если x >= a returnlerp(base, effect, (overlay.w* _NoiseStrength)); } ENDCG } }}