![](https://i.iter01.com/images/310cbdf8ce1ebd8adc24a5b87b1dc0d1ac7eefe073d21afa66af8d99e78507b9.png)
![](https://i.iter01.com/images/8b0ab7e91ef083973a13978d2148a4b0bc90a502f64cd4e02069b4aaeb8618b9.png)
![](https://i.iter01.com/images/bb2a6c568220681870d0c08b7e7ad682c67fcdfb63527b1060fb3a4fb9e8a2e9.png)
![](https://i.iter01.com/images/c27b77166e50c712f10f99e4207d857abc0b2320c64d25a47de5950a1c304ff6.png)
![](https://i.iter01.com/images/babb832fdc40c76bc71227f5ea9fa01d2f63e59d3e1cc695ddcf58f61c8b3217.png)
![](https://i.iter01.com/images/063935f502557092d8d862406eb916910f46c14bb584261bb040f49dba4e08e5.png)
![](https://i.iter01.com/images/464efd33df5b67fcfb1c91991512357e0bc81375dba8ade75b77d7a246d16183.png)
![](https://i.iter01.com/images/8724b16075c343a5b1d933a1cc824368fa57a4437d913b7f6d0541b7ce795f3c.png)
float3 F_Schlick (in float3 f0 , in float f90 , in float u )
2 {
3 return f0 + ( f90 - f0 ) * pow (1. f - u , 5. f);
4 }
5
6 float V_SmithGGXCorrelated ( float NdotL , float NdotV , float alphaG )
7 {
8 // Original formulation of G_SmithGGX Correlated
9 // lambda_v = ( -1 + sqrt ( alphaG2 * (1 - NdotL2 ) / NdotL2 + 1)) * 0.5 f;
10 // lambda_l = ( -1 + sqrt ( alphaG2 * (1 - NdotV2 ) / NdotV2 + 1)) * 0.5 f;
11 // G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l );
12 // V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0 f * NdotL * NdotV );
13
14 // This is the optimize version
15 float alphaG2 = alphaG * alphaG ;
16 // Caution : the " NdotL *" and " NdotV *" are explicitely inversed , this is not a mistake .
17 float Lambda_GGXV = NdotL * sqrt (( - NdotV * alphaG2 + NdotV ) * NdotV + alphaG2 );
18 float Lambda_GGXL = NdotV * sqrt (( - NdotL * alphaG2 + NdotL ) * NdotL + alphaG2 );
19
20 return 0.5 f / ( Lambda_GGXV + Lambda_GGXL );
21 }
22
23 float D_GGX ( float NdotH , float m )
24 {
25 // Divide by PI is apply later
26 float m2 = m * m ;
27 float f = ( NdotH * m2 - NdotH ) * NdotH + 1;
28 return m2 / (f * f) ;
29 }
30
31 // This code is an example of call of previous functions
32 float NdotV = abs( dot (N , V )) + 1e -5 f; // avoid artifact
33 float3 H = normalize (V + L);
34 float LdotH = saturate ( dot (L , H ));
35 float NdotH = saturate ( dot (N , H ));
36 float NdotL = saturate ( dot (N , L ));
37
38 // Specular BRDF
39 float3 F = F_Schlick (f0 , f90 , LdotH );
40 float Vis = V_SmithGGXCorrelated ( NdotV , NdotL , roughness );
41 float D = D_GGX ( NdotH , roughness );
42 float Fr = D * F * Vis / PI ;
43
44 // Diffuse BRDF
45 float Fd = Fr_DisneyDiffuse ( NdotV , NdotL , LdotH , linearRoughness ) / PI ;
更多資訊參考:https://zhuanlan.zhihu.com/p/144611412