unity Shader複雜光照

2021-10-02 03:33:49 字數 3548 閱讀 6198

一、渲染路徑

1、unity支援的渲染路徑:前向渲染路徑(forword)、延遲渲染路徑(deferred)、頂點照明渲染路徑(vertex lit)。

2、可以在專案上設定、也可以在攝相機上設定或者在shader上設定,在shader上利用lightmode標籤實現。

3、pass的lightmode標籤支援的渲染路徑設定選項。

lightmode標籤支援的渲染路徑設定選項

標籤名描述always

不管使用那種渲染路徑,該pass總是會被渲染,但不計算任何光照

forwardbase

用於前向渲染,該pass會計算環境光、最重要的平行光、逐頂點/sh光源和lightmaps

forwardadd

用於前向渲染,該pass會計算額外的逐畫素光源,每個pass對應乙個光源

deferred

用於延遲渲染,該pass會渲染g快取(g-buffer)

shadowcaster

把物體的深度資訊渲染到陰影對映紋理(shadowmap)或一張深度紋理中

prepassbase

用於遺留的延遲渲染,該pass會渲染法線和高光反射的指數部分

prepassfinal

用於遺留的延遲渲染,該pass通過合併紋理、光照和自發光來渲染得到最後的顏色

vertex、vertexmrgbm和vertexlm

用於遺留的頂點照明渲染

注意:在渲染設定的時候,我們除了設定pass的標籤外,還要正確使用#pragma multi_compile_fwdbase這樣的編譯指令。實驗表明只有分別為bass pass和additional pass設定#pragma multi_compile_fwdbase和

#pragma multi_compile_fwdadd編譯指令,我們才可以在相關的pass中得到正確的光照變數,例如光照衰減值等。

4、前向渲染路徑

①原理:每進行一次完整的前向渲染,我們需要渲染該物件的渲染圖元,並計算兩個緩衝區的資訊:乙個是顏色緩衝區,乙個是深度緩衝區,我們利用深度緩衝來決定乙個片元是否可見,如果可見就更新顏色緩衝區中的顏色值。

②unity中前向渲染路徑有3種處理光照的方式:逐頂點處理、逐畫素處理、球諧函式處理。乙個光源使用哪種處理模式取決於它的型別和渲染模式。

③unity會根據場景中各個光源的設定以及這些光源對物體的影響程度對這些光源進行乙個重要度排序。規則如下:

ⅰ、場景中最亮的平行光總是按逐畫素處理的

ⅱ、渲染模式被設定為not important的光源,會按逐頂點或者sh處理

ⅲ、渲染模式設定為important的光源,會按逐畫素處理

ⅳ、如果根據以上規則得到的逐畫素光源數量小於quality setting中的逐畫素光源數量(pixel light count),會有更多的光源以逐畫素的方式進行渲染。

④unity中前向渲染的兩種pass

5、頂點照明渲染路徑

它是對硬體配置要求最少、運算效能最高,但得到效果最差的一種型別,它不支援逐畫素才能得到的效果,它僅僅是前向渲染路徑的乙個子集。

6、延遲渲染路徑

①原理:延遲渲染主要包含兩個pass,在第乙個pass中,我們不進行任何光照計算,僅是計算那些片元可見的,這主要通過深度緩衝技術實現,當我們發現乙個片元是可見的,我們就把它的資訊儲存到g緩衝區中。然後,在第二個pass中,我們利用g緩衝區的各個片元資訊,進行真正的光照計算。

②缺點不支援真正的抗鋸齒(anti-aliasing)功能

不能處理半透明物體

對顯示卡有一定要求

二、光源型別

1、unity一共支援四種光源型別:平行光、點光源、聚光燈和面光燈。並且在在shader中常用的光源屬性有光源的位置、方向、顏色、強度以及衰減。

三、unity的陰影

1、在實時渲染中,最常用的一種名為shadow map的技術,這種技術它會首先把攝像機的位置放在於光源重合的位置上,那麼場景中該光源的陰影區域就是那些攝像機看不到的地方,而unity就是使用的這種技術。

2、陰影實現流程

ⅰ、讓物體接收陰影

簡單總結一下物體接收來自其他物體的陰影,以及它向其他物體投射陰影是兩個過程。

①如果我們想要乙個物體接收來自其他物體的陰影,就必須在shader中對陰影對映紋理(包括螢幕空間的陰影圖)進行取樣,把取樣結果和最後的光照結果相乘來產生陰影效果。

②如果我們想要乙個物體向其他物體投射陰影,就必須把該物體加入到光源的陰影對映紋理的計算中,從而讓其他物體在對陰影對映紋理取樣時可以得到該物體的相關資訊。在unity中,這個過程是通過為該物體執行lightmode為shadowcaster的pass來實現的,如果使用了螢幕空間的投影對映技術,unity還會使用這個pass產生一張攝像機的深度紋理。

③讓物體接收陰影:在前向渲染中,巨集shadow_coords就是宣告了乙個名為_shadowcoord的陰影紋理座標變數。而transfer_shdow的實現會根據平台不同而有所差異。如果當前平台可以使用螢幕空間的陰影對映技術,transfer_shadow會呼叫內建的computescreenpos函式計算_shadowcoord;如果該平台不支援螢幕空間的陰影對映技術,就會使用傳統的陰影對映技術,transfer_shadow會把頂點座標從模型空間變換到光源空間後儲存到_shadowcoord中。然後shadow_attenuation負責使用_shadowcoord對相關的紋理進行取樣,得到陰影資訊。

注意,當關閉了陰影後,shadow_coords和transfer_shdow實際沒有任何作用,而shadow_attenuation會直接等同於數值1。

ⅱ、讓物體投射陰影(對於非透明物體),我們把fallback設為vertexlit就可以得到正確的陰影。

對於使用透明物體我們要小心設定物體的fallback也可以得到算是理想的效果,

對於使用透明度測試實現透明的物體,fallback設定為transparent/cutout/vertexlit實現透明度陰影

對於透明度混合來講,在unity中,所有內建的半透明shader是不會產生任何陰影效果的,但是可以將fallback設定為不透明物體使用的vertexlit,diffuse。這樣unity就會在它的fallback中找到乙個陰影投射pass,但此時陰影不會穿透半透明物體。

3、統一管理關照衰減和陰影

unity_light_attenuation是unity內建的用於計算關照衰減和陰影的巨集,我們可以在內建的autolight.cginc裡找到它的相關宣告。它接收3個引數,它會將光照衰減和陰影值相乘後的結果儲存到第乙個引數中。第二個引數是結構體v2f,這個是傳遞給shadow_attenuation,用來計算陰影值。第三個引數是世界空間的座標,這個引數會用於計算光源空間下的座標,再對光照衰減紋理取樣來得到光照衰減。

在autolight.cginc中unity_light_attenuation宣告的時候,unity針對不同的光源型別、是否啟用cookie等不同情況宣告了多個版本的unity_light_attenuation。

4、透明物體陰影

Unity Shader 光照模式

shader custom deferred forward vertex subshader blend one zero cgprogram pragma vertex vert pragma fragment frag include unitycg.cginc include lightin...

unity Shader基礎光照

一 光 1 輻射度 用來量化光。對於平行光來說,輻射度可以通過計算在垂直於l的單位面積上單位時間內穿過的能量來得到。2 散射和吸收 光線和物體相交會發生的現象。散射 只改變光線的方向,不改變光線的密度和顏色。散射後兩個方向 折射和反射。在關照模型中,高光反射部分體現反射,漫反射部分體現折射 吸收 只...

Unity Shader (六)基礎光照

一 輻照度 q1.如何量化光?a 用輻照度irradiance。q2 什麼是輻照度?圖中a點單位時間內穿過的能量就是輻照度。q2 怎麼計算輻照度呢?上圖中cos 值就是輻照度。0 時,cos 1,也就是說光線垂直於物體表面時,輻照度最大。越大,表示光線越不垂直,輻照度越小。二 吸收和散射 學過基礎光...