博客 / Blog
PBR 系列#3

【PBR系列-3】迪士尼原则的 BRDF 与 BSDF 相关总结

·渲染, PBR, BRDF, 迪士尼

参考文章:知乎-PRB3

迪士尼与基于物理的渲染发展

在2012年受到Disney Principled BRDF的启发后,主流游戏引擎都开始从传统的渲染工作流转移到基于物理的渲染工作流。

以下是主流游戏引擎转移到基于物理的渲染的时间节点:

  • 【SIGGRAPH 2013】 UE4 :《Real Shading in Unreal Engine 4》
  • 【SIGGRAPH 2014】 Frostbite(寒霜): 《Moving Frostbite to PBR》
  • 【GDC 2014】 Unity:《Physically Based Shading in Unity》

迪士尼采用的BRDF可视化方案与工具

  • MERL 100 BRDF材质库:Matusik等人[Matusik et al.2003]捕获的一组100个各向同性BRDF材质样本库。涵盖了各种材质,包括油漆,木材,金属,织物,石材,橡胶,塑料和其他合成材质。对学术与研究免费授权。

MERL 100的数据库|693x373MERL 100的数据库|693x373

BRDF ExplorerBRDF Explorer

  • BRDF Image Slice切片:θh\theta_hθd\theta_d作为横轴和纵轴,对观察到的材质的BRDF进行建模的2D图像切片。

迪士尼对MERL材质数据库的观察结论

在提出Disney Principled BRDF之前,Disney已经做了大量的前置工作,其中,最主要的工作便是 对材质数据库的观察与进行理论分析。按照不同项的分类,可以总结为如下6个部分:

  • Diffuse 项的观察结论
  • Specular D项的观察结论
  • Specular F项的观察结论
  • Specular G项的观察结论
  • 布料(Fabric)材质的观察结论
  • 彩虹色(Iridescence)观察结论

Diffuse项的观察结论

漫反射:表示 折射 到表面,经过 散射和部分吸收。最终重新在表面出射的光。

  • 被着色的任意 非金属材质 的任意出射部分都可以视为 漫反射
  • 通过观察得出,很少有材质的漫反射表现和Lambert反射模型吻合,因此我们需要 更准确 的漫反射模型。
  • 掠射逆反射 有明显的着色现象 可以将掠射逆反射看做一种漫反射现象。
  • 粗糙程度 会对 菲涅尔折射 造成影响,而一般的漫反射模型如Lambert忽略了这种影响。

漫反射模型的BRDF切片和点光源响应漫反射模型的BRDF切片和点光源响应

  • Oren-Nayer:预测 粗糙漫反射表面逆向反射 的增加会使漫反射形状变平。然而,其逆向反射波峰不像测量数据那样强,并且粗糙测量的材质 通常不显示漫反射 的平坦化。
  • Hanrahan-Krueger:源自次表面散射理论, 也预测了漫反射形状的平坦化,但在边缘处没有足够强的峰值。与Oren-Nayar相比,该模型呈现出完美光滑的表面。下图中比较了Oren-Nayar、Hanrahan-Krueger和Lambert模型。

Specular D项的观察结论

  • 微观分布函数D(θh)D(\theta_h)可以从测量材质的逆反射 retroreflective 响应观察得到。
  • 绝大多数MERL材质都有 镜面波瓣 (specular lobes),且尾部比传统的镜面模型长得多。 即反射分布项需要 更宽 的尾部。
  • GGX比其他分布具有更长的尾部,仍然无法捕捉到铬金属样本的闪亮亮点

图 MERL 铬金属(chrome)与几个镜面分布的比较。 左:镜面波峰的对数比例图); 黑色曲线表示MERL 铬金属(chrome),红色曲线表示 GGX分布(α= 0.006),绿色曲线表示Beckmann分布(m = 0.013),蓝色曲线表示 Blinn Phong(n = 12000),其中,绿色曲线和蓝色曲线基本重合。 右: chrome 、GGX和Beckmann分布的点光源响应。图 MERL 铬金属(chrome)与几个镜面分布的比较。 左:镜面波峰的对数比例图); 黑色曲线表示MERL 铬金属(chrome),红色曲线表示 GGX分布(α= 0.006),绿色曲线表示Beckmann分布(m = 0.013),蓝色曲线表示 Blinn Phong(n = 12000),其中,绿色曲线和蓝色曲线基本重合。 右: chrome 、GGX和Beckmann分布的点光源响应。

Specular F项的观察结论

  • 菲涅尔反射系数F(θd)F(\theta_d)表示了,当光和视图矢量(视角方向)分开时,镜面反射的增加。【水面远处反射更强,近处不反射
  • 光滑表面在 切线入射 时有接近100%的镜面反射
  • 对于粗糙表面,无法实现100%的镜面反射,但反射率会变得越来越高?(啥意思?
  • 每种材质在掠射角附近都显示出一些反射率的增加。
  • 掠射角入射附近的许多曲线的陡度已经大于菲涅尔效应的预测值。

Specular G项的观察结论

  • 几何项的影响可以间接的看作其对 方向反射率 (direcitonal albedo)的影响。
  • 大多数材质的方向反射率(directional albedo)对于前70度是相对平坦的,并且 切线入射处的反射率 与表面 粗糙度 密切相关。
  • 几何项的选择会对反射率产生影响,反过来又会对表面外观产生影响。
  • 完全省略G项和1cosθlcosθv\frac{1}{cos\theta_l} cos\theta _v (这又啥?)的模型,又被称为“No G”模型,会导致在掠射角处过暗的响应。

布料材质的观察结论

  • 许多布料样本在 掠射角处 呈现出镜面反射的色调,并且还具有比具有 十分粗糙 的材质更强的 菲涅尔波峰
  • 布料具有有色的掠射反射,可以理解为是其轮廓附近获取到材质颜色的 透射纤维 (transmissive fibers)造成的。
  • 布料在掠射角处的 额外光泽增加,超出了普通微平面模型的预测范围。

各种布料样本的BRDF图像切片各种布料样本的BRDF图像切片

彩虹色的观察结论

  • 变色涂料(color-changing-paint)在(θh,θd)(\theta_h,\theta_d)空间上显示出 连续的色块,切对ϕd\phi_d依赖性最小。
  • 彩虹色远离镜面峰值的反射率非常小,所以可以将彩虹色理解为一种镜面反射现象。
  • 可以将镜面色调调制为θhθd\theta_h和\theta_d的函数,配合小尺寸纹理贴图对彩虹色进行建模。

3种变色涂料(color-changing-paint)的BRDF图像切片。3种变色涂料(color-changing-paint)的BRDF图像切片。

上图:原始数据;下图:通过每像素缩放1/ max(r, g, b)生成的相应色度图像。

迪士尼原则的BRDF

Disney Principled BRDF的理念

其他的在前面已经介绍过。

而从本质上而言,Disney Principled BRDF模型是 金属和非金属的混合型模型,最终结果是基于 金属度(metallice)在金属BRDF和非金属BRDF 之间进行线性插值。

也正因如此,在PBR的金属/粗糙度工作流中,固有色(baseColor)贴图才会同时包含金属和非金属的材质数据:

  • 金属的反射率值
  • 非金属的漫反射颜色

Disney Principled BRDF的参数

之前总结过,放张图。

Disney Principled BRDF的着色模型

核心BRDF模型

Disney采用了通用的microfacet Cook-Torrance BRDF着色模型:

f(l,v)=diffuse+D(h)F(v,h)G(l,v,h)4(nl)(nv)=diffuse+D(h)F(v,h)G(l,v,h)4cosθlcosθvf(l,v) = diffuse+ \frac{D(h)F(v,h)G(l,v,h)}{4(n·l)(n·v)} \\=diffuse+ \frac{D(h)F(v,h)G(l,v,h)}{4cos\theta_lcos\theta_v}

  • diffuse 是漫反射项
  • D(h)F(v,h)G(l,v,h)4cosθlcosθv\frac{D(h)F(v,h)G(l,v,h)}{4cos\theta_lcos\theta_v}为镜面反射项
    • D为微平面分布函数,主要负责镜面反射波峰(specular peak)的形状。
    • F为菲涅尔反射系数(Fresnel reflection coefficient)
    • G为几何衰减(geometric attenuation)/ 阴影项(shadowing factor)。

下面会对这些项进行说明

漫反射项(Diffuse):Disney Diffuse

Disney表示,Lambert漫反射模型在 边缘上通常太暗,而通过尝试添加菲涅尔因子以使其在物理上更合理,但会导致其更暗。

所以,根据对Merl 100材质库的观察,Disney开发了一种用于漫反射的 新的经验模型,以在光滑表面的 漫反射菲涅尔阴影粗糙表面 之间进行平滑过渡。

Disney使用了Schlick Fresnel近似,并修改 掠射逆反射 (grazing retroreflection response)以达到其特定值。(由 粗糙度值 确定,而不是简单为0。

Disney Diffuse漫反射模型的公式为:

fd=baseColorπ(1+(FD901)(1cosθl)5)(1+(FD901)(1cosθv)5)f_d = \frac{baseColor}{\pi}(1 + (F_{D90}-1)(1-cos\theta_l)^5)(1+(F_{D90}-1)(1-cos\theta_v)^5)

FD90=0.5+2roughnesscos2θdF_{D90} = 0.5 + 2·roughness·cos^2\theta_d

  • cosθdcos\theta_dlhl·h光照和半程向量
  • cosθlcos\theta_llnl·n光照和法线
  • cosθvcos\theta_vvnv·n视线和法线
  • FD90F_{D90}:由粗糙程度和视线方向与半程向量决定。当观察方向越接近半程向量,或者是粗糙程度变大,反射率就会增加。
  • 随着法线和光线的角度,以及法线和视线的角度越大,反射率就越大。但是加上了FD90F_{D90},根据视线和光线的角度变小而增大。(主要考虑漫反射在实现和光线角度较小的时候,粗糙度大的表面会反射更多光到视野的现象)
float3 Diffuse_Burley_Disney(float3 DiffuseColor, float Roughness, float Nov, float NoL, float VoH)
{
    float FD90 = 0.5 + 2 * VoH * VoH * Roughness;

    float FdV = 1 + (FD90 - 1) * Pow5(1 - NoV);
    float FdL = 1 + (FD90 - 1) * Pow5(1 - NoL);
    return DiffuseColor * ((1 / Pi) * FdV * FdL)
}

法线分布项(Specular D) : GTR

有点没看懂,待定待定,不明白为什么实现和公式是两个东西?

在流行的模型中,GGX拥有最长的尾部。而GGX其实与Blinn (1977)推崇的Trowbridge-Reitz(TR)(1975)分布等同。然而,对于许多材质而言,即便是GGX分布,仍然没有足够长的尾部。

Trowbridge-Reitz(TR)的公式:

DTR=c(α2cos2θh+sin2θh)2D_{TR} = \frac{c}{(\alpha^2cos^2\theta_h + \sin^2\theta_h)^2}

其中:

  • cc:缩放常数
  • α\alpha:粗糙度参数,其值在0~1之间。当为0时,产生完全平滑分布。当为1时,产生完全粗糙或者均匀的分布。

来自Berry(1923)的分布函数和Trowbridge-Reitz分布具有非常相似的形式,但指数为1而不是2,从而导致了 更长的尾部

DBerry=cα2cos2θh+sin2θhD_{Berry} = \frac{c}{\alpha^2cos^2\theta_h + \sin^2\theta_h}

通过,Trowbridge-Reitz和Berry的形式的对比, Disney发现其具有相似的形式只是幂次不同,于是,Disney将Trowbridge-Reitz进行了 N次幂的推广,并将其取名为 Generalized-Trowbridge-Reitz,GTR

DGTR=c(α2cos2θh+sin2θh)γD_{GTR} = \frac{c}{(\alpha^2cos^2\theta_h + \sin^2\theta_h)^\gamma}

指数值与分布曲线之间的关系指数值与分布曲线之间的关系

另外,Disney Principled BRDF中使用了两个固定的镜面反射波瓣(specular lobe),且都使用GTR模型,可以总结如下:

  • 主波瓣(primary lobe)
    • γ=2\gamma = 2GTR
    • 代表基础底层材质的反射
    • 可为各向异性或者各向同性的金属、非金属
  • 次级波瓣(secondary lobe)
    • γ=1\gamma = 1GTR
    • 代表基础材质上的清漆层(ClearCoat Layer)的反射
    • 一般为各项同性(isotropic)的非金属材质,即清漆层(ClearCoat Layer)

以下是shader代码实现

// Generalized-Trowbridge-Reitz distribution
float D_GTR1(float alpha, float dotNH)
{
    float a2 = alpha * alpha;
    float cos2th = dotNH * dotNH;
    float den = (1.0 + (a2 - 1.0) * cos2th);

    return (a2 - 1.0) / (PI * log(a2) * den);
}

float D_GTR2(float alpha, float dotNH)
{
    float a2 = alpha * alpha;
    float cos2th = dotNH * dotNH;
    float den = (1.0 + (a2 - 1.0) * cos2th);

    return a2 / (PI * den * den);
}


//各向异性的版本
float D_GTR2_aniso(float dotHX, float dotHY, float dotNH, float ax, float ay)
    {
            float deno = dotHX * dotHX / (ax * ax) + dotHY * dotHY / (ay * ay) + dotNH * dotNH;
            return 1.0 / (PI * ax * ay * deno * deno);
    }

菲涅尔项(Specular F): Schlick Fresnel

菲涅尔项(Specular F)方面,Disney表示Schlick Fresnel近似已经足够精确,且比完整的菲涅尔方程简单得多; 而由于其他因素,Schlick Fresne近似引入的误差明显小于其他因素产生的误差。

FSchlick(v,h)=F0+(1F0)(1cosθd)5F_{Schlick}(v,h) = F_0 + (1-F_0)(1-cos\theta_d)^5

  • F0F_0:表示 垂直入射 时的镜面反射率
  • θd\theta_d:为半程向量hh和视角方向vv的夹角
// [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"]
float3 F_Schlick(float HdotV, float3 F0)
{
    return F0 + (1 - F0) * pow(1 - HdotV , 5.0));
}

//一般建议实现一个自定义的Pow5工具函数替换pow(xx, 5.0)的调用,以省去pow函数带来的稍昂贵的性能开销。
half Pow5(half v)
{
	return v * v * v * v * v;
}

公式懒得打的,自己看看。

几何项(Specular G): Smith - GGX

几何项(Specular G)方面,对于主镜面波瓣(primary specular lobe),Disney参考了 Walter的近似方法,使用 Smith GGX导出的G项,并将粗糙度参数进行重映射以减少光泽表面的极端增益,即将α 从 [0, 1] 重映射到 [0.5, 1],α的值为(0.5+roughness2)2(0.5 + \frac{roughness}{2})^2

Smith-GGX几何项表达式:

G(l,v,h)=GGGX(l)GGGX(v)GGGX(v)=2(nv)(nv)+α2+(1α2)(nv)2α=(0.5+roughness2)2\begin{align}G(l,v,h) &= G_{GGX}(l)G_{GGX}(v)\\G_{GGX}(v) &= \frac{2(n·v)}{(n·v)+\sqrt{\alpha^2 + (1-\alpha^2)(n·v)^2}} \\\alpha &= (0.5 + \frac{roughness}{2})^2\end{align}

对于对清漆层进行处理的次级波瓣(secondary lobe),Disney没有使用Smith G推导,而是直接使用 固定粗糙度为0.25的GGX的 G项,便可以得到合理且很好的视觉效果。

// Smith GGX G项,各项同性版本
float smithG_GGX(float NdotV, float alphaG)
{
    float a = alphaG * alphaG;
    float b = NdotV * NdotV;
    return 1 / (NdotV + sqrt(a + b - a * b));
}

// Smith GGX G项,各项异性版本
// Derived G function for GGX
float smithG_GGX_aniso(float dotVN, float dotVX, float dotVY, float ax, float ay)
{
	return 1.0 / (dotVN + sqrt(pow(dotVX * ax, 2.0) + pow(dotVY * ay, 2.0) + pow(dotVN, 2.0)));
}


// GGX清漆几何项
// G GGX function for clearcoat
float G_GGX(float dotVN, float alphag)
{
		float a = alphag * alphag;
		float b = dotVN * dotVN;
		return 1.0 / (dotVN + sqrt(a + b - a * b));
}

迪士尼原则的分层材质

迪士尼原则的分层材质(Disney Principled Layers Material)的核心设计原则是,所有参数需允许健壮地插值,以基于纹理Mask在不同材质之间进行线性混合,实现复杂的材质外观。

使用Disney Principled Shading Model在闪亮的金属金色和蓝色橡胶之间线性插值使用Disney Principled Shading Model在闪亮的金属金色和蓝色橡胶之间线性插值

Disney Principled BRDF实现代码

已经开源,GitHub链接如下:

BRDF-git

经典代码我记录一下,配上之前的知识点做点备注。

这里用的是特有的着色器语言

//一些重要参数
::begin parameters
color baseColor .82 .67 .16
float metallic 0 1 0
float subsurface 0 1 0
float specular 0 1 .5
float roughness 0 1 .5
float specularTint 0 1 0
float anisotropic 0 1 0
float sheen 0 1 0
float sheenTint 0 1 .5
float clearcoat 0 1 0
float clearcoatGloss 0 1 1
::end parameters

//shader部分 
const float PI = 3.14159265358979323846;

float sqr(float x) { return x*x; }

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

//代表材质上的清漆层反射
//一般为各项同性(isotropic)的非金属材质。(ClearCoat Layer)
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);
}

//法线分布项 SpecularD
//代表基础底层材质的反射
//可为各向异性或者各项同性的金属、非金属
float GTR2(float NdotH, float a)
{
    float a2 = a*a;
    float t = 1 + (a2-1)*NdotH*NdotH;
    return a2/(PI*t*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 ));
}

//几何项 SpecularG
float smithG_GGX(float NdotV, float alphaG)
{
    float a = alphaG*alphaG;
    float b = NdotV*NdotV;
    return 1 / (NdotV + sqrt(a + b - a*b));
}

//各向异性的几何项
float smithG_GGX_aniso(float NdotV, float VdotX, float VdotY, float ax, float ay)
{
    return 1 / (NdotV + sqrt( sqr(VdotX*ax) + sqr(VdotY*ay) + sqr(NdotV) ));
}

//显示器空间到线性空间的颜色转换 gamma -> 线性
vec3 mon2lin(vec3 x)
{
    return vec3(pow(x[0], 2.2), pow(x[1], 2.2), pow(x[2], 2.2));
}

vec3 BRDF()
{
    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);

    vec3 Cdlin = mon2lin(baseColor); ///转换到线性空间
    float Cdlum = .3*Cdlin[0] + .6*Cdlin[1]  + .1*Cdlin[2]; //估算颜色的亮度
    // 人眼对绿色最敏感0.6、红色0.3、最后蓝色0.1

    vec3 Ctint = Cdlum > 0 ? Cdlin/Cdlum : vec3(1); //提取色调,去掉亮度,只保留颜色的成分

    //lerp = mix
    //mix(vec3(1), Ctint, specularTint):根据Tint值混合高光颜色,将漫反射部分颜色混入
    //最后根据metallic来调节
    vec3 Cspec0 = mix(specular*.08*mix(vec3(1), Ctint, specularTint), Cdlin, metallic);

    //计算材质的“光泽颜色”,尤其用于布料材质(比如丝绸、天鹅绒)
    vec3 Csheen = mix(vec3(1), Ctint, sheenTint);

    //漫反射添加roughness影响和掠射角的影响
    float FL = SchlickFresnel(NdotL);
    float FV = SchlickFresnel(NdotV);
    float Fd90 = 0.5 + 2 * LdotH*LdotH * roughness;
    float Fd = mix(1.0, Fd90, FL) * mix (1.0, Fd90, FV);

    
}

迪士尼BSDF

前文提到,Disney BRDF模型本质上是 金属和非金属 的混合型模型,对于Disney BSDF,Disney仍然延续了之前的设计理念,采用了 混合的方式并结合已有的Disney BRDF模型 进行实现。如下图,Disney新增了⼀个参数specTrans(镜面反射透明度)来控制BRDF 和BSDF的混合。基于specTrans完成混合后,再使用和 Disney BRDF 类似的方式,基于metallic再进行一次混合。

参数方面,Disney BSDF按普通表面和薄表面各有不同

  • 对于 普通表面,Disney BSDF在Disney BRDF的基础上新增 specTrans(镜面反射透明度)scatterDistance(散射距离) 两个参数,共12个。
  • 对于 薄表面(Thin-surface),Disney BSDF在Disney BRDF的基础上新增 specTrans (镜面反射透明度)、 scatterDistance (散射距离)和 flatness (平坦度)三个参数,共13个。

除了新增的Specular BSDF模型,Disney还提出了新的 次表面散射模型,以及针对薄表面的 折射处理

  • 在Disney BRDF中加入次表面散射模型。具体思路是首先将漫射波瓣重构为两部分:

    • 1、方向性的 微表面效应 (microsurface effect),主要为逆反射(retroreflection)。
    • 2、 非方向性的次表面效应 (subsurface effect),即Lambertian。
      • 用散射模型(diffusion model)或体积散射模型(volumetric scattering model)替换漫反射波瓣中的Lambert部分。
      • 这样,便能保留微表面效应(microsurface effect),让散射模型在散射距离较小时收敛到与漫反射BRDF相同的结果。
  • 提出基于两个指数项总和的次表面漫射(Subsurface diffusion)模拟模型

    • Disney通过蒙特卡洛模拟(Monte Carlo simulation),观察到对于典型的散射参数,包括单次散射的扩散剖面(diffusion profile),使用两个指数项的总和(a sum of two exponentials)便可以很好地进行模拟,且得到了比偶极子剖面(dipole diffusion)更好的渲染结果。( 完全看不懂。。。
  • 薄表面BSDF(Thin-surface BSDF)

    • 对于薄的半透明表⾯,Disney选择在单个着色点处模拟入射和出射散射事件,作为 镜面反射漫反射传输 的组合,由specTrans和diffTrans参数控制,并用各向同性的 波瓣近似薄表面漫反射传输蒙特卡洛散射(Monte Carlo diffusion)模拟,指数拟合与偶极子数据的对比。蒙特卡洛散射(Monte Carlo diffusion)模拟,指数拟合与偶极子数据的对比。

exponential fit (指数拟合),Monte Carlo(蒙特卡洛),偶极子剖面(dipole diffusion)exponential fit (指数拟合),Monte Carlo(蒙特卡洛),偶极子剖面(dipole diffusion)

评论 / Comments