一些光照模型


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;


 折疊源碼
fixed diff = max( 0 , dot(s.Normal, lightDir));
 
fixed4 c;
c.rgb = s.Albedo * _LightColor0 * diff * atten;
c.a = s.Alpha;
return   c;



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;



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM