網(wǎng)上有很多關(guān)于pos機(jī)原理圖,光照模型的原理和實(shí)現(xiàn)思路——Phong的知識(shí),也有很多人為大家解答關(guān)于pos機(jī)原理圖的問(wèn)題,今天pos機(jī)之家(www.afbey.com)為大家整理了關(guān)于這方面的知識(shí),讓我們一起來(lái)看下吧!
本文目錄一覽:
pos機(jī)原理圖
Phong光照模型之前說(shuō)過(guò),游戲場(chǎng)景中計(jì)算光照時(shí),需要考慮光源、模型材質(zhì)和觀察方向三方面的因素。很多物理學(xué)家、數(shù)學(xué)家根據(jù)這些因素,再結(jié)合真實(shí)物理世界光照效果的經(jīng)驗(yàn),總結(jié)出幾種非常經(jīng)典的光照模型,比如說(shuō)蘭伯特(Lambert)、環(huán)境光(Ambient)、Phong、Blinn-Phong、PBR等等,其中最經(jīng)典的要數(shù)Phong光照模型。
Phong光照模型是由著名學(xué)者裴祥風(fēng)在1975年提出的第一個(gè)有巨大影響力的光照計(jì)算模型。這個(gè)模型只考慮物體對(duì)直接光照的反射作用,認(rèn)為環(huán)境光是常量,沒(méi)有考慮物體之間相互的反射光,物體間的反射光只用環(huán)境光表示。用一個(gè)簡(jiǎn)單的公式來(lái)表示,就是:
光照 = 漫反射(Diffuse) + 高光反射(Specular) + 環(huán)境光(Ambient)
漫反射漫反射用來(lái)描述,當(dāng)光線從光源照射到模型表面時(shí),該表面會(huì)向每個(gè)方向散射多少輻射量。**漫反射光線的強(qiáng)度與物體表面的法線和光源方向之間夾角的余弦值成正比。**這部分可以通過(guò)光源照射方向和法線方向的點(diǎn)積來(lái)實(shí)現(xiàn)。漫反射光的計(jì)算公式可以寫成:
其中,normalDir表示法線方向,lightDir表示光源方向,為了防止點(diǎn)積為負(fù)數(shù),因此使用max函數(shù)將其截取到0,這樣可以防止物體被后面來(lái)的光源照亮。C-light表示光源顏色,m-light表示材質(zhì)的漫反射顏色。
法線方向可以通過(guò)下面的公式計(jì)算得出:
// v表示頂點(diǎn)normalDir = normalize(mul(float4(v.normal,0.0),Unity_WorldToObject).xyz);
光源方向通過(guò)使用Unity內(nèi)置的變量_WorldSpaceLightPos0計(jì)算獲取,不過(guò)這里涉及到光源類型問(wèn)題,如果是平行光源,直接將_WorldSpaceLightPos0變量歸一化,就能得到光源方向;但如果是點(diǎn)光源,還需要再減去頂點(diǎn)的世界空間坐標(biāo)位置,然后再歸一化獲取光源方向。
//i.pos_world = mul(unity_ObjectToWorld,v.vertex).xyz;// v表示頂點(diǎn)// 獲取平行光、點(diǎn)光源方向#if defined (DIRECTIONAL)half3 light_dir = normalize(_WorldSpaceLightPos0.xyz);#elif defined (POINT)half3 light_dir = normalize(_WorldSpaceLightPos0.xyz - i.pos_world);#endif
除了使用max()函數(shù)截取點(diǎn)積結(jié)果,使用saturate()函數(shù)也可以達(dá)到同樣的效果。
接下來(lái)是C-light光源顏色,光源顏色使用內(nèi)置變量_LightColor0獲取,不過(guò)在此之前,還需要引入內(nèi)置文件“AutoLight.cginc”
最后是M-light材質(zhì)顏色,直接可以通過(guò)材質(zhì)紋理獲取。
知道了上述參數(shù)的計(jì)算或獲取方法,就能計(jì)算出漫反射顏色了,不過(guò)還有一個(gè)問(wèn)題沒(méi)有考慮,那就是光的衰減。
平行光通常是用來(lái)模擬自然界的太陽(yáng)光,因?yàn)樘?yáng)光有很高的強(qiáng)度,光的衰減幾乎可以忽略不計(jì)。而對(duì)于點(diǎn)光來(lái)說(shuō),就必須通過(guò)計(jì)算物體到光源之間的距離來(lái)獲得。具體計(jì)算方法如下:
// 計(jì)算衰減#if defined (DIRECTIONAL)half attuenation = 1.0; // 衰減系數(shù)#elif defined (POINT)// 計(jì)算點(diǎn)光源到物體之間的具體// i.pos_world = mul(unity_ObjectToWorld,v.vertex).xyz;// v表示頂點(diǎn)half distance = length(_WorldSpaceLightPos0.xyz - i.pos_world);// 衰減范圍值half range = 1.0 / unity_WorldToLight[0][0];float attuenation = normalize((range - distance)/range); // 點(diǎn)光源的衰減值#endif
漫反射最終的計(jì)算公式為:
half4 base_color = tex2D(_MainTex, i.uv);half3 NdotL = dot(normal_dir,light_dir);// 計(jì)算漫反射顏色half3 diffuse_color = max(0.0, NdotL) * _LightColor0.xyz * base_color.xyz * attuenation;高光反射
這里的高光反射是一種經(jīng)驗(yàn)?zāi)P?,并不完全符合真?shí)物理世界中的高光反射現(xiàn)象。當(dāng)一束光線照射到物體上時(shí),光線會(huì)沿著物體表面法線防線朝著和入射方向相反的方向反射,這種反射的光線,可以讓物體看起來(lái)更加有光澤。
另外,高光反射還和攝像機(jī)的觀察方向有關(guān),從不同的角度觀察物體,物體的高光反射也是不一樣的,高光反射的計(jì)算公式是:
reflectDir表示反射方向,viewDir表示攝像機(jī)的觀察方向,C-light表示光源顏色。
反射方向使用reflect()函數(shù),傳入光源負(fù)方向和法線方向,具體代碼如下:
half3 reflect_dir = reflect(-light_dir, normal_dir);
觀察方向通過(guò)攝像機(jī)世界空間坐標(biāo)位置減去頂點(diǎn)世界空間位置計(jì)算得出,具體代碼如下:
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);
高光反射的計(jì)算代碼如下:
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);half3 reflect_dir = reflect(-light_dir, normal_dir);half RdotV = dot(reflect_dir,view_dir);half3 spec_color = max(0.0,RdotV) * _LightColor0.xyz;
這個(gè)高光計(jì)算的代碼還是屬于簡(jiǎn)單版的,大家可以引入其他變量,比如反光度(shininess)、高光強(qiáng)度(specIntensity)、高光遮罩(specMask)等等,靈活控制高光反射的效果。
half3 spec_color = pow(max(0.0,RdotV),_Shininess) * _LightColor0.xyz * _SpecIntensity * spec_mask.rgb;環(huán)境光
最后一步的添加環(huán)境光,環(huán)境光相對(duì)來(lái)說(shuō)就非常簡(jiǎn)單了,可以使用純色,或者使用一張紋理貼圖來(lái)制作。
Phong光照模型最后的計(jì)算結(jié)果是
half3 phong_color = diffuse_color + spec_color + _AmbientColor.xyz;總結(jié)
上述漫反射、高光反射和環(huán)境光的計(jì)算屬于簡(jiǎn)易版本,實(shí)際在編寫shader中,還可以加入更多參數(shù)實(shí)現(xiàn)更復(fù)雜精確的控制效果,比如說(shuō)混入顏色貼圖、粗糙圖貼圖、法線貼圖。
另外,需要提醒的是:任何光照模型的計(jì)算,都需要根據(jù)渲染路徑的思路來(lái)進(jìn)行計(jì)算,具體思路請(qǐng)參考Unity中的渲染路徑RenderingPath,下面給出一個(gè)光照模型shader Pass的模板:
Shader "lit/Phong"{ SubShader { Tags {"RenderType"="Opaque"} Pass { Tags { "LightMode"="ForwardBase" } CGPROGRAM #pragma multi_compile_fwdbase #include "AutoLight.cginc" } Pass { Tags { "LightMode"="ForwardAdd" } Blend One One CGPROGRAM #pragma multi_compile_fwdadd #include "AutoLight.cginc" ENDCG } }}
以前向渲染路徑為例,它使用到了兩個(gè)Pass,一個(gè)是ForwardBase,另外一個(gè)是ForwardAdd,因此在Tags 中要將這兩個(gè)Pass名稱傳入到LightMode。
初次之外,還需要分別添加multi_compile_fwdbase 和 multi_compile_fwdadd。
另外,還需要再引入AutoLight.cginc內(nèi)置文件,這個(gè)文件包含了許多光源計(jì)算的內(nèi)置變量。
以上就是關(guān)于pos機(jī)原理圖,光照模型的原理和實(shí)現(xiàn)思路——Phong的知識(shí),后面我們會(huì)繼續(xù)為大家整理關(guān)于pos機(jī)原理圖的知識(shí),希望能夠幫助到大家!
