網(wǎng)站原則做抖音seo排名軟件是否合法
?0 、分析
在前向渲染中,對于逐像素光源來說,①ForwardBase中只計算一個平行光,其他的光都是在FowardAdd中計算的,所以為了能夠渲染出其他的光照,需要在第二個Pass中再來一遍光照計算。
而有所區(qū)別的操作是,②FowardAdd的Pass要能夠針對?不同類型的光源?做出不同的計算方法,因為在這個pass中要處理的就不僅僅是一個平行光了,各種燈光都有可能。
雖然所有光在本質(zhì)上照亮的原理都是一樣的,但由于他們的?形式?有點不同,從宏觀來看 參數(shù)會有所不同,例如平行光是沒有衰減的,放置在不同位置也是沒有區(qū)別的,而點光源恰恰相反,光亮與光源的位置關(guān)系是緊密掛鉤的。
所以內(nèi)容分為兩個部分,1.? 兩種光在計算上有何不同,2. 如何利用?變體?來實現(xiàn)不同分支的計算。
一、平行光與點光源的不同
1. 光的方向
形式的區(qū)別不再贅述,而在shader中的區(qū)別在于:雖然他們的光源數(shù)據(jù)都是存儲在?_WorldSpaceLightPos0?中的,但是一個表示光的方向 而另一個表示光的位置。
對于平行光來說,_WorldSpaceLightPos0.xyz就能表示光的方向(w為0);
對點光源來說,_WorldSpaceLightPos0.xyz表示的是光的位置(w為1),而光的方向需要?再減去物體頂點位置?得到。
2. 光的衰減
對于平行光來說,是沒有光的衰減的;
對于點光源來說,光會隨著距離衰減,其衰減與?距離平方的倒數(shù)?成正相關(guān)? [球的表面積公式為4ΠR2 ]? 。
二、著色器變體
著色器變體的分支 結(jié)合了靜態(tài)(#if 宏定義)和動態(tài)(if 語句判斷)的特點:編譯時會先生成多個版本的靜態(tài)分支,運行時再動態(tài)地選擇要執(zhí)行的版本。
三、 核心操作
1. 第一個ForwardBase的pass,獲取光照實現(xiàn)PBS
//PBS
UnityLight directLight = (UnityLight)0;
directLight.color = _LightColor0.xyz;
directLight.dir = l;UnityIndirect indirectLight = (UnityIndirect)0;
indirectLight.diffuse = 0;
indirectLight.specular = 0;return UNITY_BRDF_PBS(albedo, _SpecColor, OneMinusReflectivity, _SpecPower, n, e, CreateLight(i), indirectLight );
2. 復制出第二個ForwardAdd的pass
? ? ? ? 這里代碼的復用我使用了?Unity Shader代碼復用的2個方法-CSDN博客?中抽離為cginc的方法。
3. ForwardAdd中創(chuàng)建出兩個變體分支? ??
4. 實現(xiàn)點光源不同的地方
? ? ? ? 將獲取直接光照的代碼封裝成一個單獨的函數(shù),實現(xiàn)其兩個分支的不同算法。
UnityLight CreateLight(v2f i){UnityLight directLight = (UnityLight)0;#if defined(POINT)float3 lightVec = _WorldSpaceLightPos0.xyz - i.posWorld;//光方向#elsefloat3 lightVec = _WorldSpaceLightPos0.xyz ;#endif//float3 att = 1 / (1 + dot(lightVec, lightVec));//光的衰減,和距離平方的倒數(shù)成正相關(guān),+1是為了防曝光UNITY_LIGHT_ATTENUATION(att, 0, i.posWorld);directLight.color = _LightColor0.rgb * att;directLight.dir = normalize(lightVec);return directLight;
}