一、漫反射的说明
对于粗糙物体表面的某一点,其亮度应该和入射光线与该点的垂直程度有关,也就是入射光线与此点的夹角相关。如果我们用L表示单位长度的入射光线,用C表示到达此点的光线强度和颜色,用N表示此点的发线,那么物体表面此点的亮度Lum就可以用下面的公式来表示:
Lum = C * max(0,cos<L,N>)
<L,N>表示的是方向矢量L和N之间的夹角,其cos就是这两个方向的点乘积,在unity通过Cg的标准函数库dot(L,N)来完成。这个值对于背向光线的点来说为负,其实就是对其照明为0,因此使用标准函数库中的max(0,value)来对结果进行一些控制。计算到此为此我们叫按照这种方式对物体进行照明计算的模型叫做Lambert。
对应的代码段为#pragma surface surf Lambert。
(注意,这个Lambert可以命名为其他的名字,相应的写光照模型函数时,其命名也要改变比如Unity内置三个Lighting Model函数,
如果用#pragma surface surf Lambert命名光照模型函数的话
这三个的函数名为
half4 LightingLambert(SurfaceOutput s, half3 lightDir, half atten){}
这个函数被用于forward rendering(正向渲染),但是不需要考虑view direction(观察角度)时。
如果用#pragma surface surf BasicDiffuse命名,则后面书写这些函数时,就如下面所示
half4 LightingBasicDiffuse
half4 LightingBasicDiffuse_PrePass
二、具体漫反射代码
Shader "Custom/MyLightTest" {
Properties {
_EmissiveColor("自发光的颜色:",Color) = (1,1,1,1)
_AmbientColor("环境光的颜色:",Color) = (1,1,1,1)
_Change("改变的值:",Range(0,10)) = 2.5
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf BasicDiffuse
//对上面一行的解释
//surface - 声明的是一个表面着色器
//surf - 着色器代码的方法的名字
//Lambert - 使用的光照模型。
//规则#pragma surface surfaceFunction lightModel [optionalparams]
//surface - 声明的是一个表面着色器
//surfaceFunction - 着色器代码的方法的名字
//lightModel - 使用的光照模型。
//#pragma surface surf BasicDiffuse 自定义了光照模型为BasicDiffuse,
//下面的函数为实现这个自定义的光照模型,函数命名规则为Lightin加上自定义的自定义的光照模型名称
inline float4 LightingBasicDiffuse (SurfaceOutput s,fixed3 lightDir,fixed atten)
{
//漫反射光的公式:I = Aintensity*Acolor + Dintensity*Dcolor *N.L
//前面的Aintensity*Acolor是环境光的公式(得到场景中光源的颜色)
float difLight = max(0,dot(s.Normal,lightDir));//这里相当于漫反射公式的N.L
float4 col;
//_LightColor0.rgb(Unity提供)光源颜色
//s.Albedo为当前材质反射率(从surf函数计算后输出)
//atten表明了光线的衰减率根据DX中的衰减定义,这是固定衰减
//这里用的乘法公司 物体自身的镜面放射*场景中光源的颜色*漫反射强度*衰减率*自行修改的值
col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
col.a = s.Alpha;
return col;
}
sampler2D _MainTex;
float4 _EmissiveColor;
float4 _AmbientColor;
float _Change;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
float4 c = pow((_EmissiveColor + _AmbientColor),_Change);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}