從最簡單的SurfaceShader開始層層解剖unity的標準光照模型
我們新建一個Standard Surface Shader,單擊showgenerated code開啟該表面著色器被編譯成vfShader之後的程式碼。
程式碼框架如下:
每個pass裡面還帶有1~2個前處理器模組,每個必要的模組的片段程式中都進行了標準光照模型的處理,我們提取其中一個
開啟Unity安裝目錄Editor\Data\CGIncludes中的UnityPBSLighting.cginc檔案找到這兩個方法。
LightingStandard_GI()函式輸出一個UnityGI型的全域性光照引數,傳入到LightingStandard方法中。
LightingStandard()方法中計算一些引數傳入核心的UNITY_BRDF_PBS()方法中。
我們開啟UnityStandardBRDF.cginc找到BRDF3_Unity_PBS()方法
// Old school, not microfacet based Modified Normalized Blinn-Phong BRDF
// Implementation uses Lookup texture for performance
//
// * Normalized BlinnPhong in RDF form
// * Implicit Visibility term
// * No Fresnel term
//
// TODO: specular is too weak in Linear rendering mode
half4 BRDF3_Unity_PBS (half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
half3 normal, half3 viewDir,
UnityLight light, UnityIndirect gi)
{
half3 reflDir = reflect (viewDir, normal);
half nl = saturate(dot(normal, light.dir));
half nv = saturate(dot(normal, viewDir));
// Vectorize Pow4 to save instructions
half2 rlPow4AndFresnelTerm = Pow4 (half2(dot(reflDir, light.dir), 1-nv)); // use R.L instead of N.H to save couple of instructions
half rlPow4 = rlPow4AndFresnelTerm.x; // power exponent must match kHorizontalWarpExp in NHxRoughness() function in GeneratedTextures.cpp
half fresnelTerm = rlPow4AndFresnelTerm.y;
half grazingTerm = saturate(smoothness + (1-oneMinusReflectivity));
half3 color = BRDF3_Direct(diffColor, specColor, rlPow4, smoothness);
color *= light.color * nl;
color += BRDF3_Indirect(diffColor, specColor, gi, grazingTerm, fresnelTerm);
return half4(color, 1);
}
half3 BRDF3_Indirect(half3 diffColor, half3 specColor, UnityIndirect indirect, half grazingTerm, half fresnelTerm)
{
half3 c = indirect.diffuse * diffColor;
c += indirect.specular * lerp (specColor, grazingTerm, fresnelTerm);
return c;
}
這裡就是對光照模型的實現,包括菲涅耳反射(最簡單)等效果。
另外Lighting.cginc中還封裝了Lambert和BlinnPhong光照模型,自己寫vfShader的時候可以拿來用。
下面來看看Standard.Shader:
下載"Standard" Shader 並開啟,找到第一個pass的主體。
開啟UnityStandardCore.cginc檔案找到片段程式,發現也是用的該光照模型。(這是forwardbase通道,其他通道相同)