[Unity Shader]光照模型對物體的假設


什么是光照模型

光照模型就是模擬光在物體間的傳遞過程,以確保物體可見表面每一點的亮度和顏色。

當光照射到一個物體表面時,光可能被吸收、反射或折射。反射和折射的光使物體可見。如果入射光全部被吸收,物體將不可見,稱物體為黑體。

一個物體表面呈現的顏色是有物體表面向視線方向輻射的光能中各種波長的分布所確定的。

如果物體是不透明的,則物體表面呈現的顏色僅有其反射光決定,通常把反射光考慮成環境反射光漫反射光鏡面反射光三個分量的組合。

 


 

環境反射光(Ambient Light)

環境反射光是由於鄰近物體所造成的光多次反射所產生的。光是從來自四面八方的,如從牆壁、地板以及天花伴等反射回來的光,是一種分布光源。

通常將這種光產生的效應簡化為在各個方向都有均勻的光亮度Ia

一個物體只有環境光照明時,其表面上各個點的明暗程度完全一樣。其光亮度表示為:

  I= Ia * Ka

  • Ie:物體的環境光反射光亮度;
  • Ia:環境光亮度;
  • Ka:物體表面的環境光反射系數( 0 ≤ K≤ 1)
//環境光直接獲取
//UNITY_LIGHTMODEL_AMBIENT是Unity自帶的宏定義常量
float3 ambientLighting = float3(UNITY_LIGHTMODEL_AMBIENT) * float3(_Color);

//_Color是Shader中添加的一個Property屬性
Properties {
  _Color ("Diffuse Material Color", Color) = (1,1,1,1)
}

  


 

漫反射光(DIffuse Light)

漫反射光是由特定的光源在物體表面反射光中那些向空間各方向均勻反射出去的光。這種光的反射強度與觀察點的位置是無關的,它的光強度與入射光方向和反射點處於的表面法線間的夾角余弦成正比。

假設物體表面在P點的法線為N,從P點指向光源的向量為L,兩者夾角為θ。點P處漫反射光亮度為:

  Id = Ip * K* COSθ

  • Id:表面漫反射光亮度;
  • IP:入射光的光亮度;
  • Kd:漫反射系數(決定與表面材料及入射光波長) ( 0 ≤ Kd ≤ 1);
  • θ:入射光線與法線間的夾角,0 ≤ θ ≤ PI / 2;

 

//計算的漫反射光
float3 diffuseReflection = float3(_LightColor0) * float3(_Color)* max(0.0, dot(normalDirection, lightDirection));	

 

鏡面反射光(Specular Light)

鏡面反射光是朝一個方向的反射光。

對於理想鏡面,入射到表面的光嚴格地遵守光的反射定律,只有在反射方向上,觀察者才能看到從鏡面反射出來的光線,如下圖a。

對於一般光滑平面,由於表面具有一定的粗糙度,其表面實際上是有許多朝向不同的微小表面組成,其鏡面反射光散布在反射方向周圍,如下圖b。

鏡面反射光亮度可表示為:

  Is = Is * Ks * cosnφ

  • Is:觀察者接受到的鏡面反射光亮度;
  • Ip:入射光的亮度;
  • Ks:鏡面反射系數(與材料材質和入射光波有關);
  • φ:鏡面反射方向與視線方向的夾角;
  • n:鏡面反射光的會聚系數(與物體表面的光滑度相關),一般1 ≤ n ≤ 2000;

對於較光滑的表面,其鏡面反射光會聚程度較高,n值較大;而較粗糙的鏡面反射光呈發散狀態,n值較小。

//_Object2World與_World2Object均為unity提供的內置uniform參數
float4x4 modelMatrix = _Object2World;
//世界坐標系到對象坐標系的變換矩陣
float4x4 modelMatrixInverse = _World2Object;
			
//法向量N變化至對象坐標系
float3 normalDirection = normalize(float3(mul(float4(input.normal, 0.0), modelMatrixInverse)));
			
//平行光源的入射向量L直接由uniform_WorldSpaceLightPos0給出
float3 lightDirection =normalize(float3(_WorldSpaceLightPos0));
			
//觀察向量V由攝像機坐標與頂點坐標矢量相減
float3 viewDirection = normalize(float3(float4(_WorldSpaceCameraPos, 1.0)
				- mul(modelMatrix, input.vertex)));
			
//鏡面反射光的計算
float3 specularReflection=float3(_LightColor0)*float3(_SpecColor)*pow(max(0.0,dot(reflect(-lightDirection, normalDirection),viewDirection)),_Shininess);
			

  


免責聲明!

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



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