shader光照和陰影

一.標(biāo)準(zhǔn)光照模型
OpenGL與Direct3D提供了幾乎相同的固定功能光照模型楣嘁。什么是固定功能光照模型?在過去只有固定繪制流水線的時候翎冲,該流水線被限制只能使用一個光照模型,也即是固定功能光照模型。該模型基于phong光照模型襟雷。在下面的這個例子里,我們使用一個“基本”模型對固定功能光照模型提供了簡化版本蛹找。這個基本模型的數(shù)學(xué)描述為高級公式為:
   surfaceColor = emissive + ambient + diffuse + specular
從式子可以看出:物體表面的顏色是自發(fā)光(放射 emissive)肚豺、環(huán)境反射(ambient)、漫反射(diffuse)和鏡面反射(specular)等光照作用的總和谷异。每種光照作用取決于表面材質(zhì)性質(zhì)(例如亮度和材質(zhì)顏色)和光源的性質(zhì)(例如光的位置和顏色)分尸。
下面對這個基本模型的各個部分進(jìn)行講解,最后我們使用CG語言寫出該基本模型歹嘹。

圖片1.png

    
1.)自發(fā)光(emissive)
自發(fā)光光照作用獨(dú)立于所有的光源箩绍。物體的自發(fā)光并不能照亮場景中的其他物體。換句話說尺上,物體自發(fā)光不能照亮其他物體或者投下陰影材蛛。因此圆到,一個放射性物體本身并不是一個光源。
另一個解釋放射項(xiàng)的方法:它是一種在計(jì)算完其他所有光照項(xiàng)后添加的顏色卑吭。
自發(fā)光的數(shù)學(xué)公式:emissive = Ke
其中Ke代表材質(zhì)的放射光顏色

2.)環(huán)境光(ambient)
環(huán)境光來自于四面八方芽淡,故環(huán)境放射光照項(xiàng)并不依賴于光源的位置。
1.環(huán)境放射項(xiàng)依賴:1.材質(zhì)的反射能力 2.照射到材質(zhì)上的環(huán)境光的顏色豆赏。
2.用于環(huán)境放射項(xiàng)的數(shù)學(xué)公式:
ambient = Ka * globalAmbient
其中ka是材質(zhì)的環(huán)境反射系數(shù)挣菲,globalAmbient是入射環(huán)境光的顏色。
ka= tex2D(_MainTex, i.uv.xy).rgb
globalAmbient=UNITY_LIGHTMODEL_AMBIENT.xyz

環(huán)境光.png

3.)漫反射項(xiàng)(diffuse)

圖片2.png

蘭伯特(Lambert )光照模型是目前最簡單通用的模擬漫反射的光照模型掷邦,定義如下:模型表面的明亮度直接取決于光線向量(light vector)和表面法線(normal)兩個向量夾角的余弦值白胀。光線向量是指這個點(diǎn)到光從哪個方向射入,表面法線則定義了這個表面的朝向抚岗。

diffuse = kd * lightColor * max ( NL(點(diǎn)積) , 0 )
max ( N
L(點(diǎn)積) , 0 )
規(guī)范化的向量N和L的點(diǎn)積是兩個向量之間夾角的一個度量或杠,夾角越小,P點(diǎn)受到更多的入射光照苟跪。而背向光源的表面將產(chǎn)生負(fù)數(shù)點(diǎn)積值廷痘,因此,公式*max ( NL(點(diǎn)積) , 0 )使得背向光源的表面的漫反射光為0件已,確保這些表面不會顯示漫反射光照笋额。

_WorldSpaceLightPos0這是一個表示世界做表中的光源的位置矢量或者方向矢量;
如果_WorldSpaceLightPos0.w為0篷扩,則表示該光源為平行光兄猩,_WorldSpaceLightPos0.xyz為此平行光的方向向量;
反之_WorldSpaceLightPos0.w不為0,則表示光源為點(diǎn)光源鉴未,_WorldSpaceLightPos0.xyz為此點(diǎn)光源.

半蘭伯特光照模型
半蘭伯特光照模型枢冤,解了決光照無法到達(dá)的區(qū)域, 背光面更亮一些
diffuse = kd * lightColor * (N * L *0.5 +0.5)
cos的值是-1到1之間,乘上0.5再加0.5后,值域是(0,1)

4.)鏡面反射項(xiàng)(specular)

5366d0160924ab18b03b605431fae6cd7b890ba7.jpg

Phong光照模型:

圖片3.png

Ks:材質(zhì)的鏡面反射顏色
facing的取值為0或1:當(dāng)N* L大于0時為1铜秆,當(dāng)N *L小于0時為0
R = reflect(-worldLightDir, worldNormal) ;

BlinnPhong光照模型
BlinnPhong光照模型混合和了Lambert的漫反射和標(biāo)準(zhǔn)的高光淹真,渲染有時比Phong高光更柔和、更平滑连茧,此外它的處理速度相當(dāng)快核蘸,因此成為許多CG軟件中默認(rèn)的光照渲染方法。
specular = KslightColor pow(( dot(N,H), shininess )
其中H = (L + V) / | L+V |啸驯,實(shí)際就是normalize(L + V) , 計(jì)算H比計(jì)算反射向量R更快速客扎。

4.)UnityCG.cginc常用內(nèi)置函數(shù)
float3 WorldSpaceViewDir(float4 v) 輸入一個模型空間中的頂點(diǎn)位置,返回世界空間中從該點(diǎn)到攝像機(jī)的觀察方向罚斗。
float3 UnityWorldSpaceViewDir(float4 v) 輸入一個世界空間中的頂點(diǎn)位置徙鱼,返回世界空間中從該點(diǎn)到攝像機(jī)的觀察方向。
float3 ObjSpaceViewDir(float4 v) 輸入一個模型空間中的頂點(diǎn)位置针姿,返回模型空間中從該點(diǎn)到攝像機(jī)的觀察方向袱吆。
float3 WorldSpaceLightDir(float4 v) 僅可用于前向渲染中厌衙。輸入一個模型空間中的頂點(diǎn)位置,返回世界空間中從該點(diǎn)到光源的光照方向杆故。
float3 UnityWorldSpaceLightDir(float4 v) 僅可用于前向渲染中迅箩。輸入一個世界空間中的頂點(diǎn)位置溉愁,返回世界空間中從該點(diǎn)到光源的光照方向处铛。
float3 ObjSpaceLightDir(float4 v) 僅可用于前向渲染中。輸入一個模型空間中的頂點(diǎn)位置拐揭,返回模型空間中從該點(diǎn)到光源的光照方向撤蟆。沒有被歸一化。
float3 UnityObjectToWorldNormal(float3 norm) 把法線方向從模型空間轉(zhuǎn)換到世界空間中堂污。
float3 UnityObjectToWorldDir(flaot3 dir) 把方向矢量從模型空間變換到世界空間中家肯。
float3 UnityWorldToObjectDir(float dir) 把方向矢量從世界空間變換到模型空間中。

二.法線貼圖
逐像素計(jì)算光照時盟猖,我們每一個像素都會根據(jù)該點(diǎn)的法向量來計(jì)算最終該點(diǎn)的光照結(jié)果讨衣,那么,我們?nèi)绻軌蚋淖冞@個法線的方向式镐,不是就可以改變這個點(diǎn)的光照結(jié)果了呢反镇!那么,把紋理采樣的思想用在這里娘汞,我們直接用一張圖來存儲法線(或者法線偏移值歹茶,見下文),逐像素計(jì)算時你弦,在采樣diffuse貼圖的時候惊豺,再采樣一張法線的貼圖,就可以修改法線了禽作,進(jìn)而修改最終的效果尸昧。

什么是切線空間?
切線空間就是旷偿,基于模型上的一個頂點(diǎn)建立的坐標(biāo)空間烹俗,它的X軸是這個頂點(diǎn)在模型中的切線分量,Z軸是改點(diǎn)在模型上的法線狸捅,Y軸就是這個頂點(diǎn)的副切線衷蜓,因?yàn)樽鴺?biāo)空間XYZ三個面都是互相垂直的嘛,所以這個副切線我們是可以求出來的(以為同樣是與一個平面垂直的單位向量是有兩方向的尘喝,在Unity中模型會提供一個副切線的方向的數(shù)據(jù))磁浇。
來上一個圖,讓我們更好的理解這個所謂的切線空間朽褪。

QQ截圖20170424172859.png

我們的表面法線是單位向量, 位于范圍 -1.0 到 1.0 之間. 而RGB的值域是(0,1) , 我們可以通過把法線范圍轉(zhuǎn)換為 0.0 到 1.0之間來把法線向量(x, y, z)存儲到一個 RGB 紋理貼圖中.
Color.rgb = Normal.xyz / 2.0 + 0.5;
現(xiàn)在我們可以分析為什么tangent space法線貼圖是偏藍(lán)色了.因?yàn)檫@個面渲染時計(jì)算機(jī)認(rèn)為這個面的"彎曲"程度很小,即面上各個點(diǎn)插值得來的法線相互間偏差很小.基本跟整個面的垂直方向不會差太多.因此在tangent space里,這些法線都跟z軸偏差較小.而z軸是被保存在貼圖里的b字節(jié)處(藍(lán)色通道)里.所以貼圖顯示出來的顏色就偏藍(lán)了.

http://blog.csdn.net/candycat1992/article/details/41605257

三.(渲染路徑)Rendering Paths
1.Deferred Lighting置吓,延遲光照路徑无虚。3者中最高質(zhì)量地還原光照陰影。光照性能只與最終像素?cái)?shù)目有關(guān)衍锚,光源數(shù)量再多都不會影響性能友题。
2.Forward Rendering,前向渲染路徑戴质。能發(fā)揮出Shader全部特性的渲染路徑度宦,當(dāng)然也就支持像素級光照。最常用告匠、功能最自由戈抄,性能與光源數(shù)目*受光照物體數(shù)目有關(guān),具體性能視乎其具體使用到的Shader的復(fù)雜度后专。
3.Vertex Lit划鸽,頂點(diǎn)光照路徑。頂點(diǎn)級光照戚哎。性能最高裸诽、兼容性最強(qiáng)、支持特性最少型凳、品質(zhì)最差丈冬。

1.)前向渲染
根據(jù)影響物體的光源的不同,正向渲染路徑用單個或多個通道來渲染物體啰脚。在正向渲染中殷蛇,光源本身也會根據(jù)他們的設(shè)置和強(qiáng)度受到不同的對待。
在正向渲染中橄浓,影響物體的最亮的幾個光源使用逐像素光照模式粒梦。接下來,最多有4個點(diǎn)光源會以逐頂點(diǎn)渲染的方式被計(jì)算荸实。其他光源將以球面調(diào)和(Spherical Harmonics)的方式進(jìn)行計(jì)算匀们,球面調(diào)和技術(shù)計(jì)算很快但只能得到近似值。根據(jù)以下的規(guī)則判斷一個光源是否為逐像素光源:

?渲染模式被設(shè)置為不重要(Not Important)的光源以逐頂點(diǎn)或球面調(diào)和的方式進(jìn)行計(jì)算
?最亮的方向光源為像素光源
?渲染模式被設(shè)置重要(Important)的光源為像素光源
?如根據(jù)以上規(guī)則得到的像素光源數(shù)量小于質(zhì)量設(shè)置中的像素光源數(shù)量(Pixel Light Count)准给,為了減少亮度泄朴,會有更多的光源以逐像素的方式進(jìn)行渲染

Base Pass 基本通道
Base pass renders object with one per-pixel directional light and all SH/vertex lights. This pass also adds any lightmaps, ambient and emissive lighting from the shader. Directional light rendered in this pass can have Shadows. Note that Lightmapped objects do not get illumination from SH lights.
Note that when “OnlyDirectional” pass flag is used in the shader, then the forward base pass only renders main directional light, ambient/lightprobe and lightmaps (SH and vertex lights are not included into pass data).
需要在設(shè)置Pass的 Tags { "LightMode"="ForwardBase" }
定義宏#pragma multi_compile_fwdbase
Additional Passes附加通道
Additional passes are rendered for each additional per-pixel light that affect this object. Lights in these passes by default do not have shadows (so in result, Forward Rendering supports one directional light with shadows), unless multi_compile_fwdadd_fullshadows variant shortcut is used.
需要在設(shè)置Pass的 Tags { "LightMode"="ForwardAdd" }
定義宏#pragma multi_compile_fwdadd

https://docs.unity3d.com/Manual/RenderTech-ForwardRendering.html

四.投射陰影和接收陰影
1.)投射陰影
需要有平行光,且平行光開啟陰影
物體的renderer組件需要開啟Cast Shadow
物體的shader需要一個tags為”ShadowCaster”的pass來讓物體加入陰影貼圖的渲染內(nèi).可用FallBack "Specular"來讓Unity自動查詢可用的shader,注意透明物體需要特別指定.另外,如果有使用頂點(diǎn)動畫,則需要自己定義可用的shader

2.)接收陰影
Unity中,對于衰減露氮,主要是通過一張光照衰減紋理(_LightTexture0)的采樣得到,其采樣操作主要是在光照空間中進(jìn)行祖灰。對于陰影,一般不會采用實(shí)時陰影的方式(性能耗費(fèi)太高)畔规,但是現(xiàn)在隨著技術(shù)的發(fā)展局扶,越來越多的游戲采用的實(shí)時光照,當(dāng)然這是對整體的光照的優(yōu)化有一個極其高的情況下。一般情況下都是將場景烘培三妈,對模型自身添加相應(yīng)的光照設(shè)置畜埋。
在unity中,主要是通過一個shadowCaster的shader來實(shí)現(xiàn)對陰影的計(jì)算畴蒲,對于物體是否投射陰影可以在其自身的組件上設(shè)置悠鞍。而unity將陰影和衰減的計(jì)算合并在一起,主要通過三個基本的內(nèi)部操作來實(shí)現(xiàn):在a2v的結(jié)構(gòu)體中設(shè)置SHADOW_COORDS(n)模燥,在vert shader中進(jìn)行TRANSFER_SHADOW(o)咖祭,最后在frag shader中進(jìn)行 UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos),此時得到的atten就是綜合了衰減和陰影的結(jié)果涧窒,可以用其來作為衰減和陰影的因子與最終的光照顏色相乘心肪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锭亏,一起剝皮案震驚了整個濱河市纠吴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌慧瘤,老刑警劉巖戴已,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锅减,居然都是意外死亡糖儡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門怔匣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來握联,“玉大人,你說我怎么就攤上這事每瞒〗鹈觯” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵剿骨,是天一觀的道長代芜。 經(jīng)常有香客問我,道長浓利,這世上最難降的妖魔是什么挤庇? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮贷掖,結(jié)果婚禮上嫡秕,老公的妹妹穿的比我還像新娘。我一直安慰自己苹威,他們只是感情好昆咽,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般潮改。 火紅的嫁衣襯著肌膚如雪狭郑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天汇在,我揣著相機(jī)與錄音翰萨,去河邊找鬼。 笑死糕殉,一個胖子當(dāng)著我的面吹牛亩鬼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播阿蝶,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼雳锋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羡洁?” 一聲冷哼從身側(cè)響起玷过,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎筑煮,沒想到半個月后辛蚊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡真仲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年袋马,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秸应。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡虑凛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出软啼,到底是詐尸還是另有隱情桑谍,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布焰宣,位于F島的核電站霉囚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏匕积。R本人自食惡果不足惜盈罐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闪唆。 院中可真熱鬧盅粪,春花似錦、人聲如沸悄蕾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奠骄,卻和暖如春豆同,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背含鳞。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工影锈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蝉绷。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓鸭廷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親熔吗。 傳聞我的和親對象是個殘疾皇子辆床,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • <轉(zhuǎn)>我也忘了轉(zhuǎn)自哪里,抱歉,感謝原作者 什么是Shader Shader(著色器)是一段能夠針對3D對象進(jìn)行操作...
    星易乾川閱讀 5,580評論 1 16
  • 版本記錄 前言 OpenGL 圖形庫項(xiàng)目中一直也沒用過,最近也想學(xué)著使用這個圖形庫桅狠,感覺還是很有意思讼载,也就自然想著...
    刀客傳奇閱讀 6,026評論 0 2
  • 一、Surface Output (表面著色器的標(biāo)準(zhǔn)輸出結(jié)構(gòu))Surface Shader的標(biāo)準(zhǔn)輸出結(jié)構(gòu)-第一要素...
    CarlDonitz閱讀 913評論 0 1
  • 給你 ——釋白丁 時時想起的 是你那含羞時粉紅的臉頰 在微微的笑容的襯托下 如春天含苞待放的花 我小心翼翼地...
    釋白丁閱讀 207評論 0 0
  • 每個人都有自己的舞臺垂攘,都是自己生命中的主角维雇。人有時可能會身不由己,但是我覺得堅(jiān)持做真實(shí)的自己晒他,就會成就一個...
    李嘉欣_d162閱讀 264評論 0 1