渐变纹理的原理:从一张渐变纹理上根据反射光线的强度去采集颜色
Shader "ShaderPath/GradientShader"//shader的选择路径
{
Properties//该Shader可控的属性
{
_GradientTex ("GradientTex", 2D) = "white" {}//渐变贴图
_DiffuseColor ("DiffuseColor",Color) = (1,1,1,1)//漫反射的主色调
_SpecularColor ("SpecularColor",Color) = (1,1,1,1)//高光反射的主色调
_Gloss ("Gloss",Range(1,100)) = 2 //光泽度(反光度) 控制高光区域的大小
}
SubShader//子着色器
{
// 以下均为默认值,详情可查看以往博客
Cull Back ZWrite On ZTest LEqual
Pass
{
Tags {"LightMode"="ForwardBase"} //定义该Pass在Unity光照流水线中的角色
//与ENDCG相照应,将CG代码包裹
CGPROGRAM
//顶点函数定义
#pragma vertex vert
//片元函数定义
#pragma fragment frag
//引入必要的Unity库 如下面的UnityObjectToClipPos 就是库中函数
#include "UnityCG.cginc"
//引入光照库 _LightColor0需要用
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;//每个顶点结构体必须有的
float3 normal : NORMAL;//定义法线
float4 texcoord : TEXCOORD0;//存储第一组纹理的坐标信息
};
struct v2f
{
float3 lightDir : TEXCOORD0;
float3 viewDir : TEXCOORD1;
float3 normal : TEXCOORD2;
float4 uv : TEXCOORD3;//用于存储纹理信息
float4 pos : SV_POSITION;//每个片元结构体必须有的
};
sampler2D _GradientTex;
float4 _GradientTex_ST;//图片的(平铺和偏移系数)如果要使图片的Tilling和Offset生效就必须定义
fixed4 _DiffuseColor;
fixed4 _SpecularColor;
float _Gloss;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);//把顶点从模型空间转换到剪裁空间
o.uv.xy = TRANSFORM_TEX(v.texcoord, _GradientTex);//使图片对应的_ST生效,这里就是_GradientTex_ST
//要区分UnityWorldSpaceLightDir()传入一个float3的世界坐标 和 WorldSpaceLightDir()传入一个float4的模型的顶点坐标
//UnityWorldSpaceViewDir()传入一个float3的世界坐标 WorldSpaceViewDir()传入一个float4的模型的顶点坐标
o.lightDir = WorldSpaceLightDir(v.vertex);//获取世界坐标下的光线方向
o.viewDir = WorldSpaceViewDir(v.vertex);//获取世界坐标下的观察方向
o.normal = normalize(UnityObjectToWorldNormal(v.normal));//将模型的法线转到世界坐标
return o;
}
fixed4 frag (v2f i) : SV_Target//返回一个RGBA到模型上
{
//可以理解后面的是用在顶点着色器
fixed3 lightDir = normalize(i.lightDir);//归一化
fixed3 viewDir = normalize(i.viewDir);//归一化
//半罗伯特反射
fixed halfLambert = (1+dot(lightDir,i.normal))/2;
//fixed2(halfLambert+i.uv.x,0) x的值必须如上,具体解释看下面,y的值任意,因为图片的颜色值不随y的变化而变化
fixed3 gradient = tex2D(_GradientTex,fixed2(halfLambert+i.uv.x,0)).rgb * _DiffuseColor;//采样_GradientTex里的颜色信息
fixed3 diffuse = _LightColor0 * gradient;
//对比之前的漫反射及漫反射的原理,可以理解成根据光照强度在渐变纹理上采集对应的颜色值并反映到物体上
//漫反射的定义如图
//fixed3 diffuse = _LightColor0.rgb * _DiffuseColor * (1+dot(lightDir,i.worldNormal))/2;
//Blinn-Phong模型高光
fixed3 halfView = normalize(lightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _SpecularColor * pow(saturate(dot(i.normal,halfView)),_Gloss);
return fixed4(diffuse + specular,1);
}
ENDCG
}
}
}
渐变图片可以使用下面三张,产生效果如Gif
如果你把
fixed3 gradient = tex2D(_GradientTex,fixed2(halfLambert+i.uv.x,0)).rgb * _DiffuseColor;//采样_GradientTex里的颜色信息
改成如下
fixed3 gradient = tex2D(_GradientTex,fixed2(halfLambert+(i.uv.x-_Time.y) ,0)).rgb * _DiffuseColor;
你就会得到一张会动的贴图!虽然没什么卵用,但是看上去厉害了不少