快捷搜索:  汽车  科技

unity有几种光照模式(Unity中的光照模型)

unity有几种光照模式(Unity中的光照模型)Half-Lambert光照模型最初是由 Valve 开发用在初代半条命中的技术。用来皮面物体后部变形而且看上去不立体。这是一个极其宽容的光照模型,也正因如此,此模型完全不具有物理特性。floatLambertDiffuse = NdotL * SurfaceColor;float3 SurfaceColor; //objects colorfloat3 LightColor; //lights color * intensityfloatLightAttenuation; //value of light at point (shadow/falloff)floatNdotL = max(0.0 dot(normalDirection lightDirection));

unity有几种光照模式(Unity中的光照模型)(1)

一篇多年前翻译的技术文章,算是上一篇 shader 文章的补充。

光照模型是用来决定模型表面光线的方法/算法。有许多利用着色器(shader)计算光照的方法。美术人员和程序员基于模型的真实程度/风格化程度/导入表现力来选择使用光照模型。下面我们会提到几个光照和着色模型。

Lambert

Lambertian反射率,或者扩散光,是应用中最普遍的光照模型之一,但让不是最最普遍的。

这个光照模型独立出现,也就是说表面的亮度不会随着视点角度而改变。这是一个非常简单的模型,可以使用下面的伪代码(pseudocode)实现:

float3 SurfaceColor; //objects color

float3 LightColor; //lights color * intensity

floatLightAttenuation; //value of light at point (shadow/falloff)


floatNdotL = max(0.0 dot(normalDirection lightDirection));

floatLambertDiffuse = NdotL * SurfaceColor;

float3 finalColor = LambertDiffuse * LightAttenuation * LightColor;

unity有几种光照模式(Unity中的光照模型)(2)

unity有几种光照模式(Unity中的光照模型)(3)

Half-Lambert(扩散包裹 Diffuse Wrap)

Half-Lambert光照模型最初是由 Valve 开发用在初代半条命中的技术。用来皮面物体后部变形而且看上去不立体。这是一个极其宽容的光照模型,也正因如此,此模型完全不具有物理特性。

Half-Lambert光照模型的关键在于,Lambert扩散除以2,然后加上0.5然后再二次方。一种常见的插入方式,称作扩散包裹(diffuse wrap),不是使用0.5,而是你可以使用0.51之间的所有数值,基于这样的理念运作。比如说,不用:

pow(NdotL * 0.5 0.5 2)

而还可以使用:

pow(NdotL * wrapValue (1-wrapValue) 2)

包裹数值可以是介于 0.51之间的所有值。

下面是 Half-Lambert光照模型的一个插入方式:

float3 SurfaceColor; //objects color

float3 LightColor; //lights color * intensity

floatLightAttenuation; //value of light at point (shadow/falloff)


floatNdotL = max(0.0 dot(normalDirection lightDirection));

floatHalfLambertDiffuse = pow(NdotL *0.5 0.5 2.0) * SurfaceColor;

float3 finalColor = HalfLambertDiffuse * LightAttenuation * LightColor;

unity有几种光照模式(Unity中的光照模型)(4)

unity有几种光照模式(Unity中的光照模型)(5)

Phong 光照

Phong着色模型通常用来产生镜面效果。此函数基于这样的假设:表面反射的光是粗糙表面的漫反射和光滑表面的镜面反射的集合。

下面是 Phong模型的一个常见插入方式:

float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);

float3 lightReflectDirection = reflect( -lightDirection normalDirection );

floatNdotL = max(0 dot( normalDirection lightDirection ));

floatRdotV = max(0 dot( lightReflectDirection viewDirection ));

//Specular calculations

float3 specularity = pow(RdotV _SpecularGloss/4)*_SpecularPower *_SpecularColor.rgb ;

float3 lightingModel = NdotL * diffuseColor specularity;

floatattenuation = LIGHT_ATTENUATION(i);

float3 attenColor = attenuation * _LightColor0.rgb;
float4 finalDiffuse = float4(lightingModel* attenColor 1);

unity有几种光照模式(Unity中的光照模型)(6)

unity有几种光照模式(Unity中的光照模型)(7)

Band-Lighting

这不太像是一个光照模型,而更像是一个光照扭曲,来给你看你如何在标准光照模型上使用简单的数学操作。这种方法通过打断光照的方向然后将其变成一条一条的光带。这种方法可以变成其他任何光照模型,只要用 banded NdotL替换NdotL,正如下方所示的:

floatNdotL = max(0.0 dot( normalDirection lightDirection ));


floatlightBandsMultiplier = _LightSteps/256;

floatlightBandsAdditive = _LightSteps/2;

fixedbandedNdotL = (floor((NdotL*256 lightBandsAdditive)/_LightSteps))* lightBandsMultiplier;


float3 lightingModel = bandedNdotL * diffuseColor;

floatattenuation = LIGHT_ATTENUATION(i);

float3 attenColor = attenuation * _LightColor0.rgb;

float4 finalDiffuse = float4(lightingModel * attenColor 1);

returnfinalDiffuse;

unity有几种光照模式(Unity中的光照模型)(8)

unity有几种光照模式(Unity中的光照模型)(9)

Minnaert 光照

Minnaert光照模型最初设计用来复制月亮的着色,所以经常被称作月球着色器(shader)。Minnnaert很适合用来模拟多孔和纤维表面,比如月亮和丝绒。这些表面可以在背散射(back-scatter)中造成很多光线。这在纤维垂直于表面时特别明显,比如丝绒,地毯等。

这种模拟提供的结果和 Oren-Nayar十分接近,同样也经常被称作丝绒或月球着色器(shader)。

下面是 Minnaert光照的一个近似例子:

float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);

floatNdotL = max(0 dot( normalDirection lightDirection ));

floatNdotV = max(0 dot( normalDirection viewDirection ));


float3 minnaert = saturate(NdotL * pow(NdotL*NdotV _Roughness));

float3 lightingModel = minnaert * diffuseColor;

floatattenuation = LIGHT_ATTENUATION(i);

float3 attenColor = attenuation * _LightColor0.rgb;
float4 finalDiffuse = float4(lightingModel * attenColor 1);

UNITY_APPLY_FOG(i.fogCoord finalDiffuse);


returnfinalDiffuse;

unity有几种光照模式(Unity中的光照模型)(10)

unity有几种光照模式(Unity中的光照模型)(11)

Oren-Nayer Lighting

Oren-Nayer反射率模型是一个反射模型,用在漫反射或粗糙表面上。此模型是一个简单的办法来近似模拟光线在粗糙但仍然具有lambertian特性的表面上的效果。

下面是一个简单的 Oren-Nayer插入方式。

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;

floatcos_ndotl = saturate(dot(normalDirection lightDirection));

floatcos_ndotv = saturate(dot(normalDirection viewDirection));

floatoren_nayar_s = saturate(dot(lightDirection viewDirection)) - cos_ndotl * cos_ndotv;

oren_nayar_s /= lerp(max(cos_ndotl cos_ndotv) 1 step(oren_nayar_s 0));

//lighting and final diffuse

floatattenuation = LIGHT_ATTENUATION(i);

float3 lightingModel = diffuseColor * cos_ndotl * (oren_nayar.x diffuseColor * oren_nayar.y oren_nayar.z * oren_nayar_s);
float3 attenColor = attenuation * _LightColor0.rgb;
float4 finalDiffuse = float4(lightingModel * attenColor 1);

unity有几种光照模式(Unity中的光照模型)(12)

unity有几种光照模式(Unity中的光照模型)(13)

原帖地址:

https://www.jordanstevenstechart.com/lighting-models

unity有几种光照模式(Unity中的光照模型)(14)

unity有几种光照模式(Unity中的光照模型)(15)

猜您喜欢: