Shader "Custom/05-frament Vertex"
{
Properties
{
_Diffuse("DiffuseColor",Color)=(1,1,1,1)
}
SubShader
{
pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#include "Lighting.cginc" //引入灯 的库
#pragma fragment frag
#pragma vertex vert
float4 _Diffuse; //使用属性 需要在这里再声明
struct a2v
{
float4 vertex:POSITION;
float3 normal:NORMAL;
};
struct v2f
{
float3 NormalDir:COLOR;
float4 position:SV_POSITION;
};
v2f vert(a2v v)
{
v2f f;
f.position=mul(UNITY_MATRIX_MVP,v.vertex);
f.NormalDir= mul(v.normal,(float3x3)_World2Object);
//从模型坐标转到世界坐标
return f;
}
//逐像素 光照
float4 frag(v2f f):SV_TARGET
{
float3 LightDir=normalize(_WorldSpaceLightPos0.xyz);
float3 NormalDir=normalize(f.NormalDir);
float3 Ambient=UNITY_LIGHTMODEL_AMBIENT.rgb;
float3 diffuse=_LightColor0.rgb*max(0,dot(NormalDir,LightDir))*_Diffuse.rgb;
float3 newColor=Ambient+diffuse;//环境光+漫反射
return float4(newColor,1);
}
ENDCG
}
}
Fallback "VertexLit"
}
漫反射光照计算公式: 直线光颜色*cos夹角(光与法线的夹角);
向量 积 叉积 计算公式: axb = |a|*|b|*sinθ
点积:a.b=|a|*|b|*cosθ ;
cosθ=光方向*法线方向。
当夹角>90° 时,就是背光,cos>90°都是小于0的(90°~270°)
公式又可以推出 diffuse=直线光颜色*max(0,cos(直线光方向,法线方向));
只有定义了正确的LightMode才能得到一些Unity的内置光照 #include Lighting.cginc; Tags={"LightMode"="ForwardBase"}向前的光计算方式。
环境光可以通过 UNITY_LIGHTMODE_AMBIENT 获取。它在Unity Window下的Lighting中Ambient Source 就是环境光源的意思。
物体的光照计算可以是 它的漫反射加上 环境光
上面的光照计算也叫兰伯特光照模型
缺点就是 >90的地方 都是黑的看不到模式的细节
float3 LightDir=normalize(_WorldSpaceLightPos0.xyz);
float3 NormalDir=normalize(f.NormalDir);
float3 Ambient=UNITY_LIGHTMODEL_AMBIENT.rgb;
float3 diffuse=_LightColor0.rgb*max(0,dot(NormalDir,LightDir))*_Diffuse.rgb;
放在frag中对每个像素着色
在Vert中对每个定点着色
当定点法线 位于迎光面的时候,它的法线跟光的夹角是最小的时候,取得的值最大。
改善方法就是用半兰伯特光照模型
diffuse=直射光颜色*cosθ*0.5 +0.5;