disney BRDF代码解释

来源:互联网 发布:淘宝怎么改评价 编辑:程序博客网 时间:2024/06/05 18:42

图片稍后补上..

vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y )
{
//计算有用的变量
float NdotL = dot(N,L);
float NdotV = dot(N,V);
//简单的背面判断
if (NdotL < 0 || NdotV < 0) return vec3(0);

vec3 H = normalize(L+V);float NdotH = dot(N,H);float LdotH = dot(L,H);

//gamma 修正
vec3 Cdlin = mon2lin(baseColor);
//亮度 =>通过rgb计算灰度
float Cdlum = .3*Cdlin[0] + .6*Cdlin[1] + .1*Cdlin[2]; // luminance approx.
//归一化(分离色相,饱和度)??
vec3 Ctint = Cdlum > 0 ? Cdlin/Cdlum : vec3(1); // normalize lum. to isolate hue+sat
//??
vec3 Cspec0 = mix(specular*.08*mix(vec3(1), Ctint, specularTint), Cdlin, metallic);
//??
vec3 Csheen = mix(vec3(1), Ctint, sheenTint);

// Diffuse fresnel - go from 1 at normal incidence to .5 at grazing

// and mix in diffuse retro-reflection based on roughness

//FL = (1-NdotL)^5 = (1-cosL)^5
float FL = SchlickFresnel(NdotL), FV = SchlickFresnel(NdotV);
float Fd90 = 0.5 + 2 * LdotH*LdotH * roughness;
//mix(a,b,c) = (a+(b-a) * c)
//mix(1, Fd90, FL) = (1+(Fd90-1)*FL)
float Fd = mix(1, Fd90, FL) * mix(1, Fd90, FV);

// Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
// 1.25 scale is used to (roughly) preserve albedo
// Fss90 used to “flatten” retroreflection based on roughness
//次表面参数
float Fss90 = LdotH*LdotH*roughness;
float Fss = mix(1, Fss90, FL) * mix(1, Fss90, FV);
float ss = 1.25 * (Fss * (1 / (NdotL + NdotV) - .5) + .5);

// specularfloat aspect = sqrt(1-anisotropic*.9);float ax = max(.001, sqr(roughness)/aspect);

float ay = max(.001, sqr(roughness)*aspect);
//GGX分布函数
//此处是各项异性

float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay);

//Specular 菲涅尔
//mix(a,b,c) = (a+(b-a) * c)

//F0 = Cspec0
float FH = SchlickFresnel(LdotH);
vec3 Fs = mix(Cspec0, vec3(1), FH);

//smithG GGX

float roughg = sqr(roughness*.5+.5);
float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg);

// sheenvec3 Fsheen = FH * sheen * Csheen;

//处理透明层:

// clearcoat (ior = 1.5 -> F0 = 0.04)
//GTR1:
float Dr = GTR1(NdotH, mix(.1,.001,clearcoatGloss));

//mix(a,b,c) = (a+(b-a) * c)

//F0 = 0.04(ior = 1.5 -> F0 = 0.04)
float Fr = mix(.04, 1, FH);

//透明层的固定粗糙度为0.25

float Gr = smithG_GGX(NdotL, .25) * smithG_GGX(NdotV, .25);return ((1/PI) * mix(Fd, ss, subsurface)*Cdlin + Fsheen) * (1-metallic)    + Gs*Fs*Ds + .25*clearcoat*Gr*Fr*Dr;

}

float SchlickFresnel(float u)
{
float m = clamp(1-u, 0, 1);
float m2 = m*m;
return m2*m2*m; // pow(m,5)
}

float GTR1(float NdotH, float a)
{
if (a >= 1) return 1/PI;
float a2 = a*a;
float t = 1 + (a2-1)*NdotH*NdotH;
return (a2-1) / (PI*log(a2)*t);
}

float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
{
return 1 / ( PI * ax*ay * sqr( sqr(HdotX/ax) + sqr(HdotY/ay) + NdotH*NdotH ));
}

float smithG_GGX(float Ndotv, float alphaG)
{
float a = alphaG*alphaG;
float b = Ndotv*Ndotv;
return 1/(Ndotv + sqrt(a + b - a*b));
}

0 0
原创粉丝点击