// Ref: http://jcgt.org/published/0003/02/03/paper.pdf
//GGX可见性项V
//G(l,v,h)=G1(l)G1(v)
inline half SmithJointGGXVisibilityTerm (half NdotL, half NdotV, half roughness)
{
//#if 0分支不会被执行,执行下面的简化
#if 0
//原始公式
//根据GGX的G(l,v,h)公式,分子分母同时除2*NdotL/2*NdotV,最后的结果分母可以整理成(1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
//疑问:下方的值计算不一致,以及最后G的值计算是否有问题
// Original formulation:
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
// G = 1 / (1 + lambda_v + lambda_l);
// Reorder code to be more optimal
half a = roughness;
half a2 = a * a;
//重排代码为何会出现NdotL,NdotV混用?
half lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
half lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
//简化的可见性项
//((4.0f * NdotL * NdotV)
// Simplify visibility term: (2.0f * NdotL * NdotV) / ((4.0f * NdotL * NdotV) * (lambda_v + lambda_l + 1e-5f));
return 0.5f / (lambdaV + lambdaL + 1e-5f); // This function is not intended to be running on Mobile,
// therefore epsilon is smaller than can be represented by half
#else
//上述公式的近似,简化了sqrt,数学不正确但足够接近
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
half a = roughness;
half lambdaV = NdotL * (NdotV * (1 - a) + a);
half lambdaL = NdotV * (NdotL * (1 - a) + a);
return 0.5f / (lambdaV + lambdaL + 1e-5f);
#endif
}
网友评论