PBR來龍去脈篇五:建立標準的重要性和寒霜引擎的pbr材質綜述

yxriyin發表於2021-01-03

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

相關文章