Lambert (蘭伯特)光照模型
是光源照射到物體表面后,向四面八方反射,產生的漫反射效果。這是一種理想的漫反射光照模型。如下圖:這個是頂點函數處理后的該光照模型,因此看起來像素不夠平滑。
漫反射
是投射在粗糙表面上的光向各個方向反射的現象。當一束平行的入射光線射到粗糙的表面時,表面會把光線向着四面八方反射,所以入射線雖然互相平行,由於各點的法線方向不一致,造成反射光線向不同的方向無規則地反射,這種反射稱之為“漫反射”或“漫射”。這種反射的光稱為漫射光。
Lambert光照模型計算方法
漫反射光的強度近似地服從於Lambert定律,即漫反射光的光強僅與入射光的方向和反射點處表面法向夾角的余弦成正比。
原理公式:diffuse = I*cosθ;
diffuse:反射光線的的光強;
I:入射光線的光強,方向如上圖所示;
cosθ:入射光線和該頂點法線的余弦,如上圖所示;cosθ = L*N;
所以,最后的數學表達式為:diffuse = I*(L*N);
Shader程序
1 /******************************************* 2 Lambert(蘭伯特)光照模型 3 1. 理想的漫反射; 4 2. 計算都在頂點着色器,因此像素不會平滑過渡; 5 *******************************************/ 6 Shader "JQM/Lambert" 7 { 8 Properties 9 { 10 _Color("Color", color) = (1.0,1.0,1.0,1.0) 11 } 12 SubShader{ 13 Pass{ 14 15 Tags { "LightMode" = "ForwardBase"} 16 17 CGPROGRAM 18 #pragma vertex vert 19 #pragma fragment frag 20 21 //使用自定義變量 22 uniform float4 _Color; 23 24 //使用Unity定義的變量 25 uniform float4 _LightColor0; 26 27 struct vertexInput{ 28 float4 vertex:POSITION; 29 float3 normal:NORMAL; 30 }; 31 32 struct vertexOutput{ 33 float4 pos:SV_POSITION; 34 float4 col:COLOR; 35 }; 36 37 //頂點程序 38 vertexOutput vert(vertexInput v) 39 { 40 vertexOutput o; 41 42 float3 normalDirection = normalize( mul(float4(v.normal,0.0),_World2Object).xyz);//將模型空間的法線轉到世界空間 43 float3 lightDirection; 44 float atten = 1.0; 45 46 lightDirection = normalize(_WorldSpaceLightPos0.xyz);//燈光方向 47 float3 diffuseReflection = atten * _LightColor0.xyz * max(0.0, dot(normalDirection,lightDirection));//計算蘭伯特漫反射 48 float3 lightFinal = diffuseReflection + UNITY_LIGHTMODEL_AMBIENT.xyz;//與環境光結合 49 50 o.col = float4(lightFinal*_Color.rgb,1.0); 51 o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 52 return o; 53 } 54 55 //片段程序 56 float4 frag(vertexOutput i):COLOR 57 { 58 return i.col; 59 } 60 61 ENDCG 62 } 63 } 64 65 }
效果圖
物體在空間中 受到 光源 環境光 和 自身材質(顏色,貼圖) 的綜合因素的影響,形成的效果。