Shader"XiaoSen/Last" // “面板上的名字/shader名字”,第一个名字可以用于分类,如不同平台,不同效果等的区分
{
//属性可以没有
Properties
{
//变量名 面板显示的名字 类型 默认值
//_Diffuse("DiffuseColor",Color) = (1,1,1,1) //颜色
_Color("MainColor",Color) = (1,1,1,1)
_MainTexture("Main Tex",2D) = "white"{} //贴图
_Specular("SpecularColor",Color) = (1,1,1,1)
_Gloss("Gloss",Range(10,200)) = 20 //范围值
_Alpha("Alpha",Range(0,1)) = 1
_Normalmap("NormalMap",2D) = "bump"{} //法线贴图 不能使用颜色,bump使用模型自带法线 切线空间 所有的计算空间要保持一致
_BumpScale("BumpScale",Float) = 1//凹凸参数
}
//Tags{ "Queue" = "Transparent" "IngnoreProjector" = "True" "RenderType" = "Transparent" }//对所有pass块都起作用 透明渲染队列
//SubShader至少有一个
SubShader{
pass
{
Tags{ "LoghtMode" = "ForwardBase" }//pass 内的只对内部起作用 1,定义光照模式
Cull off//剔除, off:双面渲染 back: 反面剔除 front :正面剔除 (如面片)
ZWrite Off //深度写模式 是否此物体的像素深度会被记录 默认记录 off:不记录 ,通常用于半透明物体
Blend SrcAlpha OneMinusSrcAlpha //alpha混合模式
Fog{Fog Block}//雾效
CGPROGRAM //CG程序入口
//顶点函数 声明一个顶点函数#pragma固定格式
//顶点坐标是基于模型的中心
//吧顶点坐标从模型空间转换到剪裁空间(游戏环境到视野相机屏幕上)
#pragma vertex vert
//片元函数 返回模型对应的屏幕上的每一个像素的颜色值
#pragma fragment frag
#include "Lighting.cginc" //引入unity自带类库 2,得到unity内置光照变量
//变量声明 d名字要对应上方属性变量名
// fixed4 _Diffuse;
float _Alpha;//透明度
fixed4 _Color;
sampler2D _MainTexture;
fixed4 _Specular;
float4 _MainTexture_ST;//获取属性值 名字固定,前边是纹理属性名,后边是固定,前两个值代表tilling。后两个代表offset
half _Gloss;
sampler2D _Normalmap;
float4 _Normalmap_ST;//
float _BumpScale;
//结构体,可作参数使用
struct a2v {
float4 vertex:POSITION;//通过语义告诉系统参数是干嘛的比如 POSITION 告诉系统我需要顶点坐标
//切线空间的确定是通过模型空间的法线和切线确定的
float3 normal:NORMAL;//法线 模型空间
float4 tangent:TANGENT;//切线tangent.w是用来确定切线空间的坐标轴方向的
float4 textCoord:TEXCOORD0;
};
struct v2f {
float4 svPos:SV_POSITION;//SV_POSITION解释返回值,意思是返回值是裁剪空间下的顶点坐标
//float3 worldNormal:TEXCOORD0;//文理坐标
float3 lightDir:TEXCOORD0;//切线空间下的平行光的方向
float4 worldVertex:TEXCOORD1;
float4 uv: TEXCOORD2; //获取顶点的纹理坐标//xy获取顶点的纹理坐标 zw存储法线贴图的文理坐标
};
//光照模型:是一个公式 使用它来计算在某个点的光照效果
//标准光照模型 自发光 高光反射 漫反射 可以放到顶点函数也可以放到片元函数
//高光反射 = 直射光颜色*pow(max(cos夹角, 0), 高光参数) 夹角:反射光方向和视野方向的夹角 参数一般 >= 10, 值越大高光范围也就越小
//顶点函数
v2f vert(a2v v) {
v2f f;
f.svPos = UnityObjectToClipPos(v.vertex);//矩阵函数
//f.worldNormal = UnityObjectToWorldNormal(v.normal);
f.worldVertex = mul(v.vertex, unity_WorldToObject);
f.uv.xy = v.textCoord.xy* _MainTexture_ST.xy + _MainTexture_ST.zw;//*缩放倍数xy--Tiling +添加offset偏移0-1周期取值
f.uv.zw = v.textCoord.xy*_Normalmap_ST.xy + _Normalmap_ST.zw;
TANGENT_SPACE_ROTATION;//返回一个矩阵 rotation,用来把模型空间下的方向转换切线空间下
fixed3 lightDir = normalize(WorldSpaceLightDir(f.worldVertex));
// ObjSpaceLightDir(v.vertex);//得到模型空间下的平行光的方向
f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
//fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));//反射光的方向
return f;
}
//片元函数
//从法线贴图里面去的的法线方向是在切线空间下的,所以把所以与法线有关的计算放到切线空间内
fixed4 frag(v2f f) :SV_Target
{
fixed4 normalColor = tex2D(_Normalmap,f.uv.zw);
//fixed3 tangentNormal = normalColor.xyz * 2 - 1;//自己计算
fixed3 tangentNormal = UnpackNormal(normalColor);//系统自带的方式
tangentNormal.xy = tangentNormal.xy * _BumpScale;//
//fixed3 normalDir = normalize(f.worldNormal);
fixed3 lightDir = normalize(f.lightDir);
fixed3 texColor = tex2D(_MainTexture, f.uv.xy)*_Color.rgb;// tex2D获取纹理颜色
//半兰伯特模型
float halfLambert = dot(tangentNormal, lightDir)*0.5 + 0.5;//值域范围0-1
fixed3 diffuse = _LightColor0.rgb*halfLambert*texColor;//_LightColor0.rgb 取得第一个直射光的颜色
//兰伯特模型
//fixed3 diffuse = _LightColor0.rgb*max(dot(normalDir, lightDir), 0)*_Diffuse.rgb; //取得第一个直射光的颜色 漫反射的颜色 max取最大值 dot 点乘函数
fixed3 color = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;//将环境光和纹理图进行融合 UNITY_LIGHTMODEL_AMBIENT.rgb:取得系统环境光
return fixed4(color, _Alpha);
}
ENDCG //CG程序结束
}
}
FallBack "VertexLit" //预备方案
}
这是一个带凹凸,自调色兰伯特光照模型的shader,可以调节透明度等,记录一下最近所学,不妨使用