什么是BRDF & PBR?
- 渲染其实是在计算画面的光照和阴影,而BRDF在渲染中起着举足轻重的作用。它会计算当光线物体接触后,光线如何反射的,对于该反射可用一个方程表示
- PBR是一种基于物理的渲染的理论,他从完全物理的角度去解BRDF,让物体的更贴近现实
什么是Disney BRDF
网上有不少文章解读了Disney的BRDF公式,但个人觉得解读程度还不够,并不易懂。当笔者看完这些文章再去实现Disney BRDF时发现光是这些公式并不够,Disney做了更多的处理。还需要搞清楚Disney的各种控制参数是如何与其公式配合的
自迪士尼在SIGGRAPH 2012上提出了著名的“迪士尼原则的BRDF(Disney Principled BRDF)”之后,由于其高度的易用性以及方便的工作流,已经被电影和游戏业界广泛使用,并成为了次时代高品质渲染技术的代名词。Disney BRDF其高度的通用性,将材质复杂的物理属性,用非常直观的少量变量表达了出来(如金属度metallic和粗糙度roughness),让美术更容易理解每个提供的参数
本质上,Disney Principled BRDF模型是金属和非金属的混合型模型,最终结果是基于金属度(metallice)在金属BRDF和非金属BRDF之间进行线性插值
Disney BRDF可视化方案
在BRDF可视化方面,迪士尼在分享中提出了三个方面的工具与资源
- MERL 100 BRDF材质库
涵盖各种材质,包括油漆,木材,金属,织物,石材,橡胶,塑料和其他合成材质
-
BRDF Explorer
主要用于分析测量材质,比较现有BRDF模型
-
BRDF Image Slice切片
将θh与θd作为横轴和纵轴,对BRDF进行建模的2D图像切片
BRDF Image Slice
个人认为在开发BRDF中,Image Slice是最重要的,通过控制光照向量l
和观察向量v
,在半球空间对一水平放置的材质进行BRDF运行,能直观的测试高光、Fresnel、diffuse、Grazing Retro-reflection
通过上图不难看出,该建模主要和两个变量相关
- θd:微观法线和宏观法线的角度几乎一致,主要受光照向量
l
和观察向量v
的角度差影响,从下到上范围从0到180 - θh:光照向量
l
和观察向量v
的角度差几乎一致,主要受微观法线和宏观法线的角度差,从左到右范围从0到180
Specular Peak
- 观察左边纵轴部分,可以发现微观法线和宏观法线几乎一致,那么该物体的粗糙度是非常非常低的。此时,相机观察物体的高光强度取决于L、V的角度差。当L、V的角度差越大,高光越明显
Fresnel Peak
- 观察顶部部分,可以发现L、V的角度差在180°左右,说明Fresnel强度是非常非常高的
Grazing Retro-reflection
- 观察右下角部分,可以发现光照向量
l
和观察向量v
的角度差几乎一致,这部分描述了光线从相机后方照射物体的现象,当微观法线和宏观法线的角度差越小,会导致有很少的光线能进入相机,从而导致阴影;当微观法线和宏观法线的角度差越大,因为变粗糙了,会造成进入相机的光线数量更多,也就形成高光
Diffuse
- Diffuse的光照主要来自于入射光线反射后形成的漫反射
公式解读
迪士尼亦采用Cook-Torrance的BRDF着色模型
Diffuse
Disney认为Lambert漫反射在边缘上通常太暗,无法处理Grazing Retro-reflection的高亮
,也无法处理光滑与粗糙表面的漫反射过渡
。为此Disney使用Schlick Fresnel近似,引入roughness,开发一种新的漫反射模型
参数:
- $cosθ_l:Dot(N, L)$
- $cosθ_v: Dot(N, V)$
- $cosθ_d: Dot(L, H) 或 Dot(V, H)$
float FNoL = SchlickFresnel(brdfData.NoL); // 返回(1-cosθ)^5
float FNoV = SchlickFresnel(brdfData.NoV); // 返回(1-cosθ)^5
float Fd90 = 0.5f + 2 * Pow2(brdfData.HoL) * brdfData.roughness; // 使用roughness计算diffuse
float Fd = lerp(1.f, Fd90, FNoL) * lerp(1.f, Fd90, FNoV); // 还未乘上baseColor/pi,会在最后进行
Fd90
正比roughness
,随着θd
的增大而减小,Fd90
的值可以大于1FL
和FV
都遵循菲涅尔现象,夹角越大(接近90度),返回值越大,最大为1Fd
受到V、L、Fresnel的共同影响,当形成掠射(L、V角度差接近90°)时,倾向于Fd90^2
;当形成垂直入射(L、V角度差接近0°)时,倾向于1
Subsurface
漫反射和次表面散射具有类似的原理,全部的能量还是来自于折射光分量,那么就可以用一个参数来在二者之间过渡,也就是Disney BRDF中的subsurface参数。Disney BRDF会计算出一个漫反射值Fd
和一个次表面散射值ss
,然后使用给定的subsurface对二者插值
对于次表面散射的计算,Disney BRDF并未使用Jensen BSSRDF等复杂模型,而是用BRDF来近似计算,从Hanrahan-Krueger BRDF改进而来
// 基于各向同性bssrdf的Hanrahan-Krueger brdf逼近
// 1.25用于保留反照率
float Fss90 = Pow2(brdfData.HoL) * brdfData.roughness; // 垂直于次表面的菲涅尔系数
float Fss = lerp(1.f, Fss90, FNoL) * lerp(1.f, Fss90, FNoV);
float ss = 1.25f * (Fss * (rcp(brdfData.NoL + brdfData.NoV) - 0.5f) + 0.5f); // 还未乘上baseColor/pi,会在最后进行
Fss90
不超过1,正比于roughness
,同时随着L与H的夹角变大,Fss90
也会下降,最终变为0-
Fss
受到V、L、菲涅尔反射率的共同影响,当形成掠射时,倾向于Fss90^2
;当形成垂直入射时,倾向于常数1
Frensel
Disney亦采用了业界常用的方案——Schlick Fresnel近似。主要因为计算成本低,且精度足够
不同的是,Disney不会刻意引入F0,而是通过metallic对specularTint、albedo插值
计算得到F0
// u:dot(V, N)
// 返回值:F0为0时的SchlickFresnel
// 在外部进行插值
float SchlickFresnel(float u)
{
float m = clamp(1-u, 0, 1); //将1-vdoth的结果限制在[0,1]空间内
float m2 = m*m;
return m2*m2*m; // pow(m,5) 求5次方
}
NDF
在NDF上,Disney选择了有着最长拖尾的GGX分布,且Disney发现Trowbridge-Reitz和Berry具有相似的形式,只是幂次不同。针对此现象的NDF函数做了N次幂的推广,并将其取名为Generalized-Trowbridge-Reitz,GTR
Trowbridge-Reitz:
Berry:指数为1而不是2,从而导致更长的尾部
Generalized-Trowbridge-Reitz:
- γ:用于控制尾部形状,γ越大,分布约集中,尾部约小
- c:缩放因子
另外,Disney使用两个固定的镜面反射波瓣(specular lobe),且都使用GTR模型,总结如下:
- 主波瓣(primary lobe)
- 使用γ= 2的GTR(即GGX分布)
- 代表基础底层材质(Base Material)
- 可为各项异性(anisotropic) 或各项同性(isotropic)的金属或非金属
- 次级波瓣(secondary lobe)
- 使用γ= 1的GTR(即Berry分布)
- 代表基础材质上的清漆层(ClearCoat Layer)
- 一般为各项同性(isotropic)的非金属材质,即清漆层(ClearCoat Layer)
// Disney发现GGX 和 Berry有相似的形式,只是幂次不同,于是,Disney将Trowbridge-Reitz进行了N次幂的推广,并将其取名为GTR
// 基本形式是:c/pow((a^2*cos(NdotH)^2 + sin(NdotH)^2),b) . c为放缩常数,a为粗糙度
// Disney的BRDF使用两个specular lobe
// b=1为次级波瓣,用来表达清漆层
// b=2为主波瓣,用来表达基础材质
float D_GTR1(float NoH, float roughness)
{
//考虑到粗糙度a在等于1的情况下,公式返回值无意义,因此固定返回1/pi,
//说明在完全粗糙的情况下,各个方向的法线分布均匀,且积分后得1
if (roughness >= 1) return 1/PI;
float a2 = roughness * roughness;
float cos2th = NoH * NoH;
float den = (1.0 + (a2 - 1.0) * cos2th);
return (a2 - 1.0) / (PI * log(a2) * den);
}
float D_GTR2(float roughness2, float NoH)
{
float a2 = roughness2 * roughness2;
float cos2th = NoH * NoH;
float den = (1.0 + (a2 - 1.0) * cos2th);
return a2 / (PI * den * den);
}
各项异性版本入参较为复杂,在使用前会对ax和ay做预处理,引入anisotrpic和roughness
//主波瓣 各项异性
// VoX:Dot(H, 物体表面的切线向量)
// HdotY:为半角点乘切线空间中的副切线向量
// ax 和 ay 分别是x、y2个方向上的可感粗糙度,范围是0~1
float GTR2_aniso(float NoH, float HoX, float HoY, float ax, float ay)
{
return rcp(PI * ax*ay * Pow2( Pow2(HoX / ax) + Pow2(HoY / ay) + Pow2(NoH) ));
}
- roughness与曲线斜率增长幅度成正相关
- anisotropic与曲线斜率增长幅度成正相关
Geometry
使用Smith GGX导出的G项,并重新适配参数,与NDF GTR配合使用。该G项本质是分离的遮蔽阴影函数,需要独立计算遮蔽和阴影部分
,最后用乘法统一起来。该模型完全不考虑复杂的多次反射光路
,只把光线分为在入射方面的损失(遮蔽G(l)
)和 在出射方面的损失(阴影G(v)
),且为一次性的
在一开始,对于主镜面波瓣(primary specular lobe),Disney参考了 Walter的近似方法,使用Smith GGX导出的G项,并将粗糙度参数进行重映射以减少光泽表面的极端增益,即将α 从[0, 1]重映射到[0.5, 1],α的值为(0.5 + roughness/2)^2。从而使几何项的粗糙度变化更加平滑,更便于美术人员的使用
但后来在SIGGRAPH 2015上,对G项进行了修订,他们基于Heitz的分析[Heitz 2014],淘汰了对于主镜面波瓣的Smith G粗糙度的特殊重映射,采用了Heitz各向异性的G
// 清漆层 次级波瓣
// 2012版disney,本质是Smith联合遮蔽阴影函数中的“分离的遮蔽阴影型”
// NoV视情况也可替换为NdotL,用于计算阴影相关的G1
// alphag被disney定义为0.25f
float G_GGX(float NoV, float alphag)
{
float a = alphag * alphag;
float b = NoV * NoV;
return 1.0 / (NoV + sqrt(a + b - a * b));
}
// 各向异性 主波瓣
float smithG_GGX_aniso(float NoV, float VoX, float VoY, float ax, float ay)
{
return 1 / (NoV + sqrt( Pow2(VoX*ax) + Pow2(VoY*ay) + Pow2(NoV) ));
}
- 各项同性和各项异性的版本,在各个角度保持了恒定的输出,但在掠射角附近骤然提升(降低遮蔽能力)
- 各项同性版本的
G
项使用固定的a
,为0.25
,用于清漆层高光渲染 - 增加
粗糙度
和各项异性度
都会让曲线斜率变得平缓——越是粗糙的表面,在掠射角附近遮蔽能力越强
参数解读
BaseColor
- 金属:反射率
- 非金属:漫反射颜色
Subsurface
近似控制漫反射形状
- 控制漫反射光渗入物体边缘的强度
- 大幅提高逆反射角的亮度
metallic
当metallic趋向1时,弱化漫反射率,强化镜面反射强度,同时镜面反射逐渐附带上金属色
- 纯金属材质几乎不形成漫反射,影响光照强度的只有高光和清漆波瓣
- 高光带(specular peak)体现出强烈的金属色,而非金属而没有
specular
控制镜面反射光占入射光的比率
- 金属的反射率取决于baseColor,该项对纯金属不生效
- 对非金属而言,该项控制镜面反射比率,影响菲尼尔项Fs
specularTint
和baseColor一起控制镜面反射的颜色
roughness
- 影响diffuse和specular
-
从完全光滑到完全粗糙,高光带的能量从聚集在一点,到分散(能量守恒),最后高光带消失(
Gs
和Ds
的共同影响)
anisotropic
控制镜面反射在不同朝向上的强度——镜面反射高光的纵横比
sheen
额外的漫反射掠射分量(边缘漫反射的补偿),主要用于布料。在掠射角附近,且微表面法线与宏观夹角接近90度时,引入额外的光量以起到提亮效果
- 金属没有sheen
- 专门控制物体轮廓/边缘的漫反射强度
- sheen值增加主要影响
Fresnel Peak的形状
,在掠射情况下,增强视角两侧边缘的光能的渗透
sheenTint
控制sheen的颜色
- Tint基于base color
clearcoat
控制第二个镜面反射波瓣的形成及影响范围
- 有自己的
G
,F
和D
函数(各项同性) - 控制反射光斑的大小
- 在底层镜面反射比较暗淡模糊时比较明显
clearcoatGloss
控制透明涂层的高光强度
- 影响清漆层BRDF函数中的法线分布项
Dr
代码仓库
https://github.com/chenglixue/Unity-Disney-BRDF-with-GI
Comments | NOTHING