Lambert光照模型(漫反射):
粗糙的物体表面向各个方向等强度的反射光,这种等同地向各个方向散射的现象称为光的漫反射
漫反射符合兰伯特定律:反射光线的强度与表面法线和光源方向之间的夹角成正比。这是一种理想的漫反射模型,也被称为兰伯特光照模型
![](https://img2018.cnblogs.com/i-beta/1726280/202001/1726280-20200120150335554-1911875045.png)
![](https://img2018.cnblogs.com/i-beta/1726280/202001/1726280-20200120154734338-2001624724.png)
如图,光源方向与法线的夹角为0时,光强度最大;光源方向与法线的夹角角度为90度时,光强度为0 ---->> 辐射度与 cosΘ成正比
光源方向 * 法线 = |光源方向| * |法线| * cosΘ
将光源方向和法线归一化, 光源方向 * 法线 = 1 * 1 * cosΘ
逐顶点漫反射:
Shader "Custom/VertexDiffuse" { Properties { _Diffuse("Diffuse", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _Diffuse; struct v2f { float4 vertex : SV_POSITION; fixed3 color : COLOR; }; v2f vert (appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);//相同空间内点积才有效,因为光源是在世界空间内,所以法线需要转到世界空间 fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//世界空间内光源方向 //_LightColor0世界空间内的光源颜色,在Lighting.cginc中;saturate函数返回0~1之间的值 fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate((dot(worldNormal, worldLight))); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光 o.color = diffuse + ambient; return o; } fixed4 frag (v2f i) : SV_Target { return fixed4(i.color, 1); } ENDCG } } }
逐片元漫反射:
Shader "Custom/FragDiffuse" { Properties { _Diffuse("Diffuse", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _Diffuse; struct v2f { float4 vertex : SV_POSITION; fixed3 worldNormal : TEXCOORD0; }; v2f vert (appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); o.worldNormal = worldNormal; return o; } fixed4 frag (v2f i) : SV_Target { fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光 fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldLightDir, i.worldNormal)); fixed3 color = ambient + diffuse; return fixed4(color, 1); } ENDCG } } }
半兰伯特模型:
使用Lambert漫反射光照模型有一个缺点:背光面明暗一样,看起来想一个平面一样,失去了模型细节。于是一种改善的技术提了出来:半兰伯特(Half Lambert)光照模型
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * (dot(worldLightDir, worldNormal) * 0.5 + 0.5);