Unity3D中Shader光照模型基礎(chǔ)

在講Unity光照模型之前,先介紹圖形學(xué)中的兩個(gè)基礎(chǔ)光照模型原理,將會(huì)更利于我們理解和使用Unity中的光照模型。

物體表面的光照顏色由入射光。物體材質(zhì),以及材質(zhì)和光的交互規(guī)律共同決定的。

1、圖形學(xué)中的兩個(gè)基礎(chǔ)光照模型

(1)漫反射與Lambert光照模型

粗糙的物體表面向各個(gè)方向等強(qiáng)度地反射光,這種等同度地散射現(xiàn)象稱為光的漫反射(Diffuse Reflection)。產(chǎn)生光的漫反射現(xiàn)象的物體表面稱為理想漫反射體,也稱為L(zhǎng)ambert反射體。

對(duì)于暴露在環(huán)境光下的Lambert反射體,可以用以下公式表示某點(diǎn)處的漫發(fā)射光強(qiáng):

Iad= K*Ia

(約定:小寫的字母表示下標(biāo),ad = ambient diffuse)

其中Ia表示環(huán)境光強(qiáng)度,k(0<k<1)為材質(zhì)對(duì)環(huán)境光的反射系數(shù),Iad是漫發(fā)射體與環(huán)境光交互時(shí)反射的光強(qiáng)。

理想的環(huán)境光是無序的,但是表面光強(qiáng)還依賴于光線的入射方向,這種現(xiàn)象可以用Lambert定律進(jìn)行數(shù)學(xué)上的量化。

Lambert定律:當(dāng)方向光照射到理想反射體上時(shí),漫反射光的光強(qiáng)與入射光方向和入射點(diǎn)便面法向量夾角的余弦成正比。

Ild = K*Il*Cosa

Iid是漫反射體與方向光交互反射的光強(qiáng),Il是方向光的光源強(qiáng)度,a是入射光線與定點(diǎn)法向量的夾角,k是材質(zhì)的反射系數(shù)。

當(dāng)入射角為零時(shí),說明光線垂直于物體表面,漫反射光強(qiáng)最大;九十度時(shí)光線與物體表面平行,物體接收不到任何光線。

若N表示頂點(diǎn)單位法向量,L表示從頂點(diǎn)指向光源位置的單位向量(主意指向,不要弄反了),那么Cosa等價(jià)于N與L的點(diǎn)積。

即:

Ild = k*I*(N·L)

那么綜合考慮環(huán)境光和方向光,Lambert光照模型可寫為:

Idiff = Iad + Ild = k*Ia + k*Il*(N·L)

(****2****)鏡面反射與****Phong****光照模型

Lambert模型較好的表現(xiàn)了粗糙表面的光照現(xiàn)象,如墻壁,紙張等,但是在用于諸如金屬等有光澤效果的材質(zhì)上則會(huì)顯得呆板,表現(xiàn)不出光澤,主要原因是Lambert光照模型沒有考慮表現(xiàn)這些表面的鏡面反射效果。

一個(gè)光滑物體被光照射時(shí),可以早某個(gè)方向上看到很強(qiáng)的反射光,這是因?yàn)樵诮咏R面反射角的一個(gè)區(qū)域內(nèi),反射了入射光的全部或大部分光強(qiáng),這種現(xiàn)象稱為鏡面發(fā)射。

故此,Phong Bui Tuong提出一個(gè)計(jì)算鏡面反射光強(qiáng)的光照模型,稱為Phong模型,認(rèn)為鏡面反射的光強(qiáng)與反射光線和視線的夾角相關(guān)。

Phong模型數(shù)學(xué)表達(dá)式:

Ispec = Ks*Il*(V·R)^n

注:((V·R)^n表示(V·R)的n次方即(V·R)^n 。

Ks表示材質(zhì)的鏡面反射系數(shù),n指高光指數(shù),V表示從頂點(diǎn)到視點(diǎn)觀察方向,R表示反射光方向。

高光指數(shù)n反映了物體表面的光澤程度。n越大,反射越集中,當(dāng)偏離發(fā)射方向時(shí),光線衰減的越厲害,只有當(dāng)視線方向與反射光線非常接近時(shí),才能看到鏡面反射的高光現(xiàn)象。此時(shí),鏡面反射光將會(huì)在反射方向附近形成亮且小的光斑。n越小,表示物體表面越粗糙,反射光越分散,觀察到的光斑區(qū)域越小,強(qiáng)度弱。

反射光方向向量R可以通過入射方向L(從頂點(diǎn)指向光源)和物體表面法向量L求出。

R+L = (2N·L)N

下面是一段Phong模型的cg代碼:

void main_f( VertexScreen posIn,
 out float4 color : COLOR,
 uniform float4x4 worldMatrix,
 uniform float4x4 worldMatrix_IT,
 uniform float3 globalAmbient,
 uniform float3 eyePosition,
 uniform float3 lightPosition,
 uniform float3 lightColor,
 uniform float3 Kd,
 uniform float3 Ks,
 uniform float shininess)
{
 float3 worldPos = mul(worldMatrix,  posIn.objectPos).xyz;
 float3 N = mul(worldMatrix_IT,  posIn.objectNormal).xyz;
 N = normalize(N);
 //計(jì)算入射光方向、視線方向、反射光線方向
 float3 L = normalize(lightPosition - worldPos);
 float3 V = normalize(eyePosition - worldPos);
 float3 R = 2*max(dot(N, L), 0)*N-L;
 R = normalize(R);
 // 計(jì)算漫反射分量
 float3 diffuseColor = Kd * globalAmbient +Kd*lightColor*max(dot(N, L), 0);
 //計(jì)算鏡面反射分量
 float3 specularColor = Ks *  lightColor*pow(max(dot(V, R), 0), shininess);
 color.xyz = diffuseColor + specularColor;
 color.w = 1;
}

(3)BlinnPhong光照模型

BlinnPhong光照模型混合和了Lambert的漫反射和標(biāo)準(zhǔn)的高光,渲染小股票有時(shí)比Phong高光更柔和、更平滑,此外它的處理速度相當(dāng)快,因此成為許多CG軟件中默認(rèn)的光照渲染方法。

在Phong模型中,必須計(jì)算V·R的值,其中R為反射光線的單位向量,V為視線方向的單位向量,但是在BlinnPhong模型中,用N·H的值來取代V·R。
BlinnPhong光照模型公式:

Ibp = Ks*Il(N·H)^n

其中N是入射點(diǎn)的單位法向量,H是“光入射方向L和視點(diǎn)方向V的中間向量”,通常也稱為半角向量。
注:半角向量被廣泛運(yùn)用于各類光照模型,因?yàn)槠浼群懈鞣N信息價(jià)值(光線入射方向以及視點(diǎn)方向),而且計(jì)算快速方便。

H = (L+V)/(|L+V|)

同樣還有Cook-Torrence、BRDF等高級(jí)光照模型,可以自己去查資料拓展。

2、Unity中自定義光照模型

(1)、光照模型聲明

光照模型函數(shù)的聲明一般以“Lighting”開頭的幾個(gè)模板,可以被定義在你的Shader里的任何位置。

1、half4 Lighting<name> (SurfaceOutput s,half3 lightDir,half atten);
這個(gè)函數(shù)模板一般用于正向渲染路徑(forward rendering path),并且是視線方向無關(guān)的。

2、half4 Lighting<name>(SurfaceOutput s,half3 lightDir,half3 viewDir,half atten);
一般用于forward rendering path,并且是視線方向相關(guān)的。

3、half4 Lighting<name>_OrePass(SurfaceOutput s,half4 light);
用于deferred lighting path。

你不需要聲明所有的函數(shù),一個(gè)光照模型是否使用view direction。如果一個(gè)光照模型不在deferred lighting起作用,你就不需要聲明_PrePass函數(shù),并且所有的Shader都會(huì)被編譯成forward rendering path。

(2)、解碼光照貼圖

對(duì)于forward 和 deferred 光照,解碼光照貼圖可以被定制為何光照函數(shù)相似的方式。使用下面的函數(shù)取決于你是否使用了視線方向相關(guān)的光照模型。
解碼基礎(chǔ)的Unity光照貼圖數(shù)據(jù)(通過color,totalcolor,indirectOnlyColor和scale參數(shù))使用內(nèi)置的DecodeLightmap函數(shù)。

定制的光照貼圖解碼函數(shù)會(huì)自動(dòng)處理forward和deferred渲染路徑。但是在deferred case Lighting<name> _PrePass函數(shù)將會(huì)在光照貼圖解碼之后被調(diào)用,并且光照參數(shù)將會(huì)包含實(shí)時(shí)光照和光照貼圖。

如果需要的需要的話你可以用Unity內(nèi)置的宏UNITY_PASS_PREPASSFINAL來區(qū)分forward和deferred渲染路徑。

對(duì)于解碼單個(gè)光照貼圖的自定義函數(shù):

1、half4 Lighting<Name> _SingleLingtingMap(SurfaceOutput s,fixed4 color);
用于不依賴視線方向的光照模型。

2、half4 Lighting<Name>(SurfaceOutput s,fixed4 color,half3 vieDir);
用于依賴視線方向的光照模型。

對(duì)于解碼雙光照貼圖的自定義函數(shù):

1、half4 Lighting<Name> _DualLightMap(SurfaceOurput s,fixed4 totalColor,fixed4 indirectionOnlyColor,half indirectFade);
用于不依賴視線方向的光照模型。
2、half4 Lighting<Name> _DualLightMap(SurfaceOurput s,fixed4 totalColor,fixed4 indirectionOnlyColor,half indirectFade,half3 viewDir);
用于依賴視線方向的光照模型。

對(duì)于解碼定向光照貼圖的自定義函數(shù):

1、half4 Lighting<Name> _DirLightMap(SurfaceOutput s,fixed4 color,fixed4 scale,bool surfFuncWritesNormal);
用于不依賴視線方向的光照模型。

2、half Lighting<Name> _DirLightMap(SurfaceOutput s,fixed4 color,fixed4 scale,half3 viewDir,bool suefFuncWritesNormal,out half3 specColor);
用于依賴視線方向的光照函數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Surface Output (表面著色器的標(biāo)準(zhǔn)輸出結(jié)構(gòu))Surface Shader的標(biāo)準(zhǔn)輸出結(jié)構(gòu)-第一要素...
    CarlDonitz閱讀 1,038評(píng)論 0 1
  • 一.標(biāo)準(zhǔn)光照模型OpenGL與Direct3D提供了幾乎相同的固定功能光照模型。什么是固定功能光照模型?在過去只有...
    karma085閱讀 3,861評(píng)論 0 2
  • 現(xiàn)實(shí)世界的光照是極其復(fù)雜的,而且會(huì)受到諸多因素的影響,這是以目前我們所擁有的處理能力無法模擬的。因此OpenGL的...
    IceMJ閱讀 2,146評(píng)論 1 6
  • 關(guān)于本系列這是Unity3D Shader入門指南系列的第二篇,本系列面向的對(duì)象是新接觸Shader開發(fā)的Unit...
    JumboWu閱讀 1,660評(píng)論 0 2
  • 這個(gè)表姐是我大舅舅的女兒,從小沒媽媽,大舅舅常年不回家也不管她,連撫養(yǎng)費(fèi)都不給,她是我外公外婆帶大的。而且兩個(gè)舅舅...
    一路上有你真好閱讀 374評(píng)論 0 0

友情鏈接更多精彩內(nèi)容