環(huán)境貼圖最主要的技術(shù)實(shí)現(xiàn)方式有三種:立方體貼圖、IBL和球諧光照迟蜜。
之前已經(jīng)說過立方體貼圖和IBL谢肾,今天重點(diǎn)來(lái)聊一聊球諧光照。
在立方體貼圖IBL的基本設(shè)置里小泉,Convolution Type屬性 除了設(shè)置為Specular(Glossy Reflection)之外芦疏,還可以設(shè)置為Diffuse(Irradiance)。Specular 是IBL用于模擬間接光照高光反射的微姊,而Diffuse是模擬間接光照漫反射的酸茴。
間接光照漫反射(下文只稱漫反射)的實(shí)現(xiàn)方式有兩種:一種是IBL,另外一種就是球諧光照兢交。先來(lái)看看IBL實(shí)現(xiàn)漫反射的方式薪捍。
IBL漫反射
漫反射區(qū)別于高光反射,它的顏色變化不會(huì)隨視角的轉(zhuǎn)動(dòng)而發(fā)生變化,使用IBL實(shí)現(xiàn)漫反射酪穿,首先要將Convolution Type屬性設(shè)置為Diffuse(Irradiance)凳干。
高光反射的顏色會(huì)隨著視角的變化而變化,而漫反射不會(huì)被济,在計(jì)算顏色時(shí)只和法線方向有關(guān)救赐,因此,IBL漫反射的計(jì)算公式是
// 漫反射顏色的計(jì)算
float4 uv_ibl = float4(normal_dir, mip_level);
half4 color_cubemap = texCUBElod(_CubeMap, uv_ibl);
half3 env_color = DecodeHDR(color_cubemap, _CubeMap_HDR);
大家可以對(duì)比一下IBL高光反射計(jì)算的方式只磷,看看二者的區(qū)別:
half4 colorCubeMap = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0,reflect_dir,mip_Level);
half3 env_color = DecodeHDR(colorCubeMap,unity_SpecCube0_HDR);
在貼圖尺寸設(shè)置上经磅,如果只是用來(lái)實(shí)現(xiàn)漫反射效果,貼圖的尺寸不需要太大钮追,一般設(shè)置512*512就足夠了预厌。
漫反射效果,忽略AO元媚,物體各處的光照強(qiáng)度基本一致轧叽,沒有太多的強(qiáng)弱之分,在視覺上也呈現(xiàn)出溫和的效果刊棕。
球諧光照
球諧光照最主要的應(yīng)用就是用于計(jì)算間接光照(也叫環(huán)境光)犹芹,這里的間接光照是指skybox所發(fā)出的光。
IBL也是計(jì)算間接光照鞠绰,skybox發(fā)出的環(huán)境光有什么特點(diǎn)呢?它最大的特點(diǎn)skybox無(wú)限大飒焦,如此一來(lái)我們可以忽略掉位置信息而只考慮法線信息蜈膨。也就是說,不管我們的模型多么大牺荠,在計(jì)算模型上某一個(gè)具體點(diǎn)的時(shí)候我們認(rèn)為該點(diǎn)處于天空球中心翁巍。
不過IBL計(jì)算間接光照最大的缺點(diǎn)就是紋理采樣。采用IBL的方法休雌,我們需要存儲(chǔ)一張立方體貼圖灶壶,紋理采樣的帶寬對(duì)于電腦來(lái)說可能不算什么,不過對(duì)于手機(jī)而言就實(shí)在是有點(diǎn)奢侈了杈曲。
球諧光照可以說是為了彌補(bǔ)IBL的缺點(diǎn)而誕生的一種更加性能優(yōu)化的計(jì)算方式驰凛。
這里不探討球諧光照是如何實(shí)現(xiàn)的,因?yàn)槠渲猩婕暗臄?shù)學(xué)模型計(jì)算實(shí)在是太復(fù)雜了担扑。我們只關(guān)注在unity中如何實(shí)現(xiàn)球諧光照恰响。
我們先要明白球諧光照的一個(gè)最基本原理,它是通過從立方體貼圖中計(jì)算提取出七個(gè)球諧光照系數(shù)涌献,然后通過一些復(fù)雜的數(shù)學(xué)計(jì)算生成光照顏色胚宦,最后賦予給物體。
這些系數(shù)的格式如下所示,僅供參考:
獲取到這些系數(shù)后枢劝,然后把它傳遞到shader里面參與計(jì)算井联,計(jì)算的核心代碼如下所示:
float4 normalForSH = float4(normal_dir, 1.0);
//SHEvalLinearL0L1
half3 x;
x.r = dot(custom_SHAr, normalForSH);
x.g = dot(custom_SHAg, normalForSH);
x.b = dot(custom_SHAb, normalForSH);
//SHEvalLinearL2
half3 x1, x2;
// 4 of the quadratic (L2) polynomials
half4 vB = normalForSH.xyzz * normalForSH.yzzx;
x1.r = dot(custom_SHBr, vB);
x1.g = dot(custom_SHBg, vB);
x1.b = dot(custom_SHBb, vB);
// Final (5th) quadratic (L2) polynomial
half vC = normalForSH.x*normalForSH.x - normalForSH.y*normalForSH.y;
x2 = custom_SHC.rgb * vC;
float3 sh = max(float3(0.0, 0.0, 0.0), (x + x1 + x2));
sh = pow(sh, 1.0 / 2.2);
half3 env_color = sh;
光照探針
掌握了了球諧光照的基本原理,我們?cè)賮?lái)說說光照探針您旁。
球諧光照是光照探針的使用基礎(chǔ)烙常,如果手動(dòng)實(shí)現(xiàn)球諧光照,就要像上面一樣又是計(jì)算光照系數(shù)被冒,又是引入立方體貼圖军掂,還要在shader中進(jìn)行大量復(fù)雜的計(jì)算。這無(wú)疑非常困難昨悼。
但unity已經(jīng)給開發(fā)者封裝好了這一系列操作蝗锥,它就是光照探針!我們來(lái)看看光照探針是如何使用的率触。
全局光照探針
如果場(chǎng)景中沒有放置光照探針终议,unity會(huì)默認(rèn)使用一個(gè)全局光照探針,它是在Lightint面板中設(shè)置的葱蝗。
不過穴张,在此之前要先烘焙立方體貼圖,這和使用反射探針的操作是一樣的两曼。
Environment Light是設(shè)置光照探針烘焙貼圖的相關(guān)屬性
Environment Reflections是設(shè)置反射探針烘焙貼圖的相關(guān)屬性
設(shè)置完成后皂甘,點(diǎn)擊Generate Lighting按鈕,就會(huì)在場(chǎng)景Scene文件夾下生成一張帶有光照信息的立方體貼圖悼凑。
第二歩偿枕、漫反射的計(jì)算。球諧光照的shader計(jì)算很復(fù)雜户辫,但是使用unity內(nèi)置的球諧光照計(jì)算方法ShadeSH9()渐夸,計(jì)算就會(huì)變得非常簡(jiǎn)單,不過在此之前渔欢,還需要設(shè)置LightMode墓塌、引入相關(guān)文件,具體如下:
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma multi_compile_fwdbase
#include "AutoLight.cginc"
#include "UnityCG.cginc"
half3 env_color = ShadeSH9(float4(normal_dir,1.0));
打開Frame Debugger,在渲染流程中可以查看到球諧光照的系數(shù)信息
手動(dòng)計(jì)算球諧光照奥额,需要開發(fā)者自己在參數(shù)面板上設(shè)置球諧系數(shù)值苫幢,這些系數(shù)值的計(jì)算是一個(gè)非常復(fù)雜的過程,往往需要借助一些第三方工具垫挨。而使用全局光照探針和unity內(nèi)置的球諧光照計(jì)算的函數(shù)态坦,就免去了上述一系列復(fù)雜的操作。
對(duì)比一下手動(dòng)計(jì)算球諧光照和使用光照探針計(jì)算球諧光照的效果棒拂,二者之間沒有太大的差別伞梯。
局部光照探針
局部光照探針需要開發(fā)者手動(dòng)添加玫氢,我們來(lái)看看該如何操作?
1谜诫、添加LightProbeGroup
2漾峡、進(jìn)入edit 模式,排列布置探針小球的采樣點(diǎn)位置
3喻旷、添加光源生逸,光源模式設(shè)置為Baked
4、在Lighting面板中勾選“Baked Global Illumination”且预,然后點(diǎn)擊“Generate Lighting”
5送丰、最后看看效果瘪菌,當(dāng)物體移動(dòng)時(shí)名党,物體表面的光照也會(huì)時(shí)刻發(fā)生變化帝际。
為什么會(huì)這樣呢?這是因?yàn)楹姹嘿N圖后涮拗,光照探針組的每一個(gè)光照小球乾戏,都帶有球諧值。我們可以通過下面的設(shè)置三热,直接查看光照小球的信息鼓择。
點(diǎn)擊物體模型,帶線條的小球就是對(duì)物體光照產(chǎn)生影響的光照探針就漾。當(dāng)物體移動(dòng)時(shí)呐能,它附近的光照小球可以將攜帶的球諧信息進(jìn)行插值混合運(yùn)算,生成新的球諧系數(shù)抑堡,最后再賦予給物體的shader摆出,從而照亮物體。