光照模型:
一个公式,用来计算在某个点的光照效果
标准光照模型下进入摄像机的光:
自发光
高光反射
漫反射(Diffuse): 直射光颜色 * max(0,cos(光和法线的夹角))
逐顶点实现漫反射:
Shader "Custom/Shader01"{
SubShader{
Pass{
//定义LightMode以得到unity的内置光照变量
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
//unity内置文件引入,要使用unity的内置变量
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
struct a2v{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f{
float4 position : SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(a2v v){
v2f f;
//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
f.position = mul(UNITY_MATRIX_MVP,v.vertex);
//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
fixed3 normalDir = normalize(mul(v.normal, (float3x3) _World2Object));
//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0);//取得漫反射颜色
f.color = diffuse;
return f;
}
fixed4 frag(v2f f) : SV_Target{
return fixed4(f.color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
漫反射效果:
添加环境光和自身的颜色
Shader "Custom/Shader01"{
Properties{
_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
}
SubShader{
Pass{
//定义LightMode以得到unity的内置光照变量
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
//unity内置文件引入,要使用unity的内置变量
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
struct a2v{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f{
float4 position : SV_POSITION;
fixed3 color : COLOR;
};
v2f vert(a2v v){
v2f f;
//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
f.position = mul(UNITY_MATRIX_MVP,v.vertex);
//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
fixed3 normalDir = normalize(mul(v.normal, (float3x3) _World2Object));
//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
//取得漫反射颜色
fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
//UNITY_LIGHTMODEL_AMBIENT 获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
f.color = diffuse + ambient;
return f;
}
fixed4 frag(v2f f) : SV_Target{
return fixed4(f.color,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
逐像素实现漫反射:
Shader "Custom/Shader02"{
Properties{
_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
}
SubShader{
Pass{
//定义LightMode以得到unity的内置光照变量
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
//unity内置文件引入,要使用unity的内置变量
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
struct a2v{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f{
float4 position : SV_POSITION;
fixed3 worldNormalDir : COLOR0;
};
v2f vert(a2v v){
v2f f;
f.position = mul(UNITY_MATRIX_MVP, v.vertex);
f.worldNormalDir = normalize(mul(v.normal, (float3x3) unity_WorldToObject));
return f;
}
fixed4 frag(v2f f) : SV_Target{
fixed3 normalDir = f.worldNormalDir;
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed3 tempColor = diffuse + ambient;
return fixed4(tempColor,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
与之前的逐顶点进行对比,颜色过渡平滑,效果更好
半兰伯特光照模型:
之前的漫反射也叫兰伯特光照模型,通过公式我们可以看到cos的值是-1到1的,当小于1时为0,这时物体的背面是几乎是黑色的,会影响游戏的体验
我们将cos值*0.5+0.5,这时值的范围变为0到1
fixed3 diffuse = _LightColor0.rgb * (dot(normalDir, lightDir)*0.5 + 0.5) * _Color.rgb;