编写漫反射Shader代码
什么是光照模型
光照模型就是一个公式,使用这个公式来计算在某个点的光照效果
光照模型就是一个公式,使用这个公式来计算在某个点的光照效果
漫反射 Diffuse = 直射光颜色* max(0,Cos夹角)(光和法线的夹角)当夹角为1是光是直射,小于零则是光照射不到的地方
Shader"MyShader/Demo4"{
Properties{
_Diffuse("Diffuse",Color) = (1,1,1,1)
}
SubShader{
Pass{
Tags{"LightMode" = "ForwardBase"}//只有定义了正确的LightMode才能得到一些Unity的内置光照变量
CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
#include "Lighting.cginc"//将Light.cgine引入,相当于引入dll命名空间,包含unity的内置文件,才可以使用Unity的内置函数
//取得第一个直射光的颜色_LightColor0 Unity内置变量,在Light.cginc中定义了
#pragma vertex vert
#pragma fragment frag
fixed3 _Diffuse;
struct a2v {
float4 vertex:POSITION;//语义:把模型空间下的顶点坐标填充给vertex
float3 normal:NORMAL;//语义:吧模型空间下的法线方向填充给normal
float4 texcoord:TEXCOORD0;//语义:告诉unity把第一套纹理坐标填充给texcoord
};
//
struct v2f {
float4 position:SV_POSITION;
float3 temp:COLOR;
};
v2f vert(a2v v) {
v2f f;
f.position = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed3 normalDir = mul(v.normal, (float3x3)unity_WorldToObject);//这个矩阵用来把一个方向从世界空间转换到模型空间
//对于每个顶点来说,光的位置就是光的方向,因为光是平行光
fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//normalize() 用来把一个向量,单位化(原来方向保持不变,长度变为1)
fixed3 diffuse = _LightColor0.rgb*max(0,dot(normalDir,lightDir))*_Diffuse.rgb;//取得每个顶点漫反射的颜色值
f.temp = diffuse+ ambient;
return f;
}
fixed4 frag(v2f f) :SV_Target{
return fixed4(f.temp,1);
}
ENDCG
}
}
FallBack "VertexLit"
}
颜色叠加直接相加 一般亮度会增加
颜色融合直接相乘 亮度不会改变颜色会改变
在标准光照模型里面,我们把进入摄像机的光分为下面四个部分
自发光
高光反射
漫反射
环境光
Shader中用到的一些函数
normalize() 用来把一个向量,单位化(原来方向保持不变,长度变为1)
max() 用来取得函数中最大的一个
dot 用来取得两个向量的点积
_WorldSpaceLightPos0 取得平行光的位置
_LightColor0取得平行光的颜色
UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
UNITY_LIGHTMODEL_AMBIENT用来获取环境光
max() 用来取得函数中最大的一个
dot 用来取得两个向量的点积
_WorldSpaceLightPos0 取得平行光的位置
_LightColor0取得平行光的颜色
UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
UNITY_LIGHTMODEL_AMBIENT用来获取环境光
半兰伯特光照模型
Diffuse = 直射光颜色 *( cosθ *0.5 +0.5 ) Cos的值为-1到1,乘以0.5范围在-0.5-0.5之间再加上0.5则将范围限制在了0-1之间。
兰伯特光照模型
Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) ) cosθ = 光方向· 法线方向
Diffuse = 直射光颜色 *( cosθ *0.5 +0.5 ) Cos的值为-1到1,乘以0.5范围在-0.5-0.5之间再加上0.5则将范围限制在了0-1之间。
兰伯特光照模型
Diffuse = 直射光颜色 * max(0,cos夹角(光和法线的夹角) ) cosθ = 光方向· 法线方向