// Upgrade NOTE: replaced ‘_Object2World’ with ‘unity_ObjectToWorld’
shader"unityshader/specular vertex"{
properties{
_Diffuse(“Diffuse”,color)=(1,1,1,1)
_Specular(“Specular”,color)=(1,1,1,1)
_Gloss(“Gloss”,range(8.0,256))=20
//设置属性在材质面板中
}
SubShader{
Pass{
Tags {“LightModel”=“ForwardBase”}//设定该标签可以使用unity的内置光照
CGPROGRAM
#pragma vertex vert//定义顶点着色器的名字
#pragma fragment frag//定义片元着色器的名字
#include "UnityLightingCommon.cginc"//引入unity的内置文件
#include "UnityCG.cginc"//引入unity的内置文件
fixed4 _Diffuse;//设定材质面板中的属性类型相应的变量
fixed4 _Specular;//设定材质面板中的属性类型相应的变量
float _Gloss;//设定材质面板中的属性类型相应的变量
struct a2v{
float4 vertex:POSITION;//存储模型顶点
float3 normal:NORMAL;//存储模型顶点法线
};//定义顶点着色器的结构体
struct v2f {
float4 pos:SV_POSITION;
//sv_position语义告诉unity,pos里面包含了顶点在裁减空间中的位置信息
float3 worldNormal:TEXCOORD0;//表示第一组顶点法线纹理坐标
float3 worldPos:TEXCOORD1;//表示第一组世界纹理坐标
};//定义片元着色器的结构体
v2f vert(a2v v){//在a2v的结构中把模型顶点坐标填充到输入参数v中
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//用v.vertex来访问模型空间的顶点坐标,转换顶点坐标到裁减空间
o.worldNormal=UnityObjectToWorldNormal(v.normal);
//转换模型法线坐标到世界空间,并归一化
o.worldPos =mul(unity_ObjectToWorld,v.vertex).xyz;
//转换模型顶点坐标到世界空间
return o;
}
fixed4 frag(v2f i):SV_Target{
//sv——Target是hlsl中的一个系统语义,它告诉渲染器把用户输出的颜色存储到一个渲染目标
fixed3 ambient =UNITY_LIGHTMODEL_AMBIENT.xyz;
//环境光
fixed3 worldNormal=normalize(i.worldNormal);
//法线方向
fixed3 worldLightDir=normalize(UnityWorldSpaceLightDir(i.worldPos));
//光源方向
fixed3 diffuse=_LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));
//漫反射
fixed3 viewDir=normalize(UnityWorldSpaceViewDir(i.worldPos));
//视角方向
fixed3 halfDir=normalize(worldLightDir+viewDir);
//高光反射
fixed3 specular =_LightColor0.rgb*_Specular.rgb*pow(saturate(dot(worldNormal,halfDir)),_Gloss);
return fixed4(ambient + diffuse+ specular,1.0);
//最终输出的颜色
}
ENDCG
//注意,由于使用unityCG.cgnic内置函数得到的方向没有归一化,所以要使用normalize函数来对结果进行归一化
//然后再进行光照模型的计算(这里指的是specular)
}
}
Fallback "Specular"
//需要把这个unityshader的回调shader设置为内置的Specular
}