1. Lambert
Diffuse Light
与视角无关
float NdotL = max( 0.0 , dot(s.Normal, lightDir)); float4 finalColor; finalColor.rgb = s.Albedo * _LightColor0 * NdotL; finalColor.a = s.Alpha; return finalColor; |
2. Half-Lambert
半条命起源
可以看清物体暗的部分的形状,因此物体显得更加扁平
float NdotL = max( 0.0 , dot(s.Normal, lightDir)); float HalfLambertDiffuse = pow(NdotL * 0.5 + 0.5 , 2.0 ); float4 finalColor; finalColor.rgb = s.Albedo * _LightColor0 * HalfLambertDiffuse * atten; finalColor.a = s.Alpha; return finalColor; |
3. Phong
表现高光效果
diffuse light and specular light
float NdotL = max( 0 , dot(s.Normal, lightDir)); float3 lightReflectDirection = reflect(-lightDir, s.Normal); float RdotV = max( 0 , dot(lightReflectDirection, viewDir)); float spec = pow(RdotV, _SpecPower/ 4 ) * _SpecularColor; float4 color; color.rgb = (s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec) * atten; color.a = s.Alpha; return color; |
4. Blinn-Phong
建立在Phong的基础上。Phong计算light reflection vector ,而Blinn计算Half Direction替之,即灯光方向和视角方向的半角向量。
好处是高光更加柔和。
float NdotL = max( 0 , dot(s.Normal, lightDir)); float3 halfVector = normalize(lightDir + viewDir); float NdotH = max( 0 , dot(s.Normal, halfVector)); float spec = pow(NdotH, _SpecPower) * _SpecularColor; float4 color; color.rgb = (s.Albedo * _LightColor0.rgb * NdotL) + (_LightColor0.rgb * _SpecularColor.rgb * spec) * atten; color.a = s.Alpha; return color; |
5. PBR
完全基于物理的
6. Banded-lighting
将连续的灯光变为离散的一段一段的
float NdotL = max( 0.0 , dot(s.Normal, lightDir)); float lightBandsMultiplier = _LightSteps / 256 ; float lightBandsAdditive = _LightSteps / 2 ; fixed bandedNdotL = (floor((NdotL * 256 + lightBandsAdditive) / _LightSteps)) * lightBandsMultiplier; float3 lightingModel = bandedNdotL * s.Albedo; float3 attenColor = atten * _LightColor0.rgb; float4 finalDiffuse = float4(lightingModel * attenColor, 1 ); return finalDiffuse; |
7. Minnaert
特别适合天鹅绒或月亮,这类多孔可渗透性或纤维状的表面,这类表面会导致大量光反向散射
float3 viewDirection = viewDir; float NdotL = max( 0 , dot(s.Normal, lightDir)); float NdotV = max( 0 , dot(s.Normal, viewDirection)); float3 minnaert = saturate(NdotL * pow(NdotL*NdotV, _Roughness)); float3 lightingModel = minnaert * s.Albedo; float3 attenColor = atten * _LightColor0.rgb; float4 finalDiffuse = float4(lightingModel * attenColor, 1 ); return finalDiffuse; |
8. Oren–Nayar
Lambert 光照模型,是一个让光线向各个角度都均匀辐射的模型。这个均匀实在太不可思议了,真实物体表面理应不是这样的。
在灯光方向不变的情况下,观察物体的角度不同,物体表面光强、颜色也会发生变化(一般粗糙物体正光光强比背光光强要强)。就是光线向各个角度并非均匀辐射。
Oren-Nayar model 这个主要来自于Michael Oren和Shree K. Nayar在SIGGRAPH94上发表的论文Generalization of Lambert’s Reflectance Model。里面通过统计的等手段总结出比较接近真实粗糙表面的数学公式
http://www1.cs.columbia.edu/CAVE/publications/pdfs/Oren_SIGGRAPH94.pdf
float roughness = _Roughness; float roughnessSqr = roughness * roughness; float3 o_n_fraction = roughnessSqr / (roughnessSqr + float3( 0.33 , 0.13 , 0.09 )); float3 oren_nayar = float3( 1 , 0 , 0 ) + float3(- 0.5 , 0.17 , 0.45 ) * o_n_fraction; float3 viewDirection = viewDir; float cos_ndotl = saturate(dot(s.Normal, lightDir)); float cos_ndotv = saturate(dot(s.Normal, viewDirection)); float oren_nayar_s = saturate(dot(lightDir, viewDirection)) - cos_ndotl * cos_ndotv; oren_nayar_s /= lerp(max(cos_ndotl, cos_ndotv), 1 , step(oren_nayar_s, 0 )); //lighting and final diffuse float attenuation = atten; float3 lightingModel = s.Albedo * cos_ndotl * (oren_nayar.x + s.Albedo * oren_nayar.y + oren_nayar.z * oren_nayar_s); float3 attenColor = attenuation * _LightColor0.rgb; float4 finalDiffuse = float4(lightingModel * attenColor, 1 ); return finalDiffuse; |