逐顶点/像素材质的阴影表现很单调。是因为使用了saturate函数将dot(wordNormal,wordLight)的值截取到[0,1],相比之下半兰伯特阴影表现较为柔和。
因为半兰伯特在计算中没有舍弃掉[0,1]以外的值,而通过dot(wordNormal,wordLight)*x+y的方式计算,其中x,y一般都为0.5。但是修改过几次后发现,x值越小,对比度越小;x值越大,对比度就越强烈。而y可以控制整体的亮度,y值越大越亮。
以下为半兰伯特代码
Shader "ZJQSAMA/HalfLambertMat"
{
Properties
{
_Diffuse ("Diffuse", Color) = (1,1,1,1)
//声明属性不打分号
}
SubShader
{
Pass
{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
//#pragma multi_compile_fog
#include "Lighting.cginc"
float4 _Diffuse;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
//fixed3 color : COLOR;
float3 worldNormal : TEXCOORD0;
};
v2f vert (a2v v)
{
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);//模型空间转到裁剪空间
o.worldNormal =mul(v.normal,(float3x3)unity_WorldToObject);//模型空间的法线转换到世界空间
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //通过unity内置变量得到环境光ambient
fixed3 worldNormal = normalize(i.worldNormal);//得到之前计算好的世界空间法线
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);//得到场景光源方向(只有一盏灯且为平行光时候适用)
fixed3 halfLambert = dot(worldNormal,worldLightDir)*0.55+0.35;//半兰伯特计算
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;
fixed3 color = ambient+diffuse;
return fixed4(color,1.0);
}
ENDCG
//ENDCG写在PASS中
}
}
FallBack "Diffuse"
}