1. 漫反射物体在环境光下反射的光强 = 环境光强*材质对环境光的反射系数
2. 漫反射物体在入射光下反射光强 = 光源强度*材质对环境光的反射系数*cos入射光与法线夹角
参考:https://www.cnblogs.com/luxishi/p/6422852.html 漫反射和Lambert模型
求光源下物体漫反射颜色使用的是公式 2
物体在点光源下漫反射颜色 = 入射光颜色*漫反射系数(材质的漫反射颜色)*max(0, cos(法线与入射光夹角) )
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "MyShader/Chapter6-DiffuseVertexLevel"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Diffuse("Diffuse", color) = (1, 1, 1, 1)
}
SubShader
{
/*设定着色器是不透明的*/
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
Tags{ "LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
//使用unity内置变量
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct a2v
{
float4 vertex : POSITION;//POSITION 模型顶点坐标
float3 normal : Normal;
};
//使用该结构体定义顶点着色器的输出,顶点着色器中必须包含一个语义是SV_POSITION的变量,
//否则渲染器无法得到顶点的裁剪空间坐标,也就无法将顶点渲染到屏幕
struct v2f
{
float4 pos : SV_POSITION;//SV_POSITION裁剪空间顶点坐标
fixed3 color : COLOR;
};
sampler2D _MainTex;
fixed4 _Diffuse;
v2f vert (a2v v)
{
v2f o;
//Transform the vertex from object space to projection space,顶点位置从模型空间转为裁剪空间
o.pos = UnityObjectToClipPos(v.vertex);
//Get ambient term,使用unity内置变量获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
//Transform the normal from object space to world space,得到顶点世界空间法线
fixed3 worldNormal = normalize(mul(v.normal, unity_WorldToObject));
//Get the light direction in world space,获取世界空间光照方向
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
//Compute diffuse term, 漫反射 = ( 入射光颜色和强度Clight*材质漫反射系数Mdiffuse )*max(0, n*l)
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot( worldNormal , worldLight ) );
o.color = ambient + diffuse;
return o;
}
//片元着色器的输入其实是顶点着色器的输出进行插值后的结果,
//个人理解:对于上面的顶点着色器的输出,是一个顶点的裁剪空间坐标以及该顶点的颜色,
//因此插值后获取到该片元的裁剪坐标以及颜色,最终输出到屏幕
fixed4 frag (v2f i) : SV_Target
{
return fixed4( i.color, 1.0 );
}
ENDCG
}
}
}
Shader "MyShader/Chapter6-DiffusePixelLevel"
{
//逐像素光照
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Diffuse("Diffuse", color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _Diffuse;
struct a2v
{
float4 vertex : POSITION;
float3 normal : Normal;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal : TEXCOORD0;
};
sampler2D _MainTex;
v2f vert (a2v v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldLight = normalize( _WorldSpaceLightPos0.xyz );
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(i.worldNormal, worldLight));
return fixed4(ambient + diffuse, 1.0);
}
ENDCG
}
}
}
参考:unity shader编程精要