图形学基础 | 基于物理的渲染PBR之直接光照
PBR的理论GraphicsLab Project之基于物理的着色系统(Physical based shading)-直接光照0 序列PBR 其实是一个光照模型.在经典的光照模型中:漫反射是 Lambert镜面反射是 blinn-Phong环境光是 c * (1-AO)PBR:漫发射依然是 Lambert(多出了一个PI).镜面反射是 Cook-Torrance....
PBR的理论
GraphicsLab Project之基于物理的着色系统(Physical based shading)-直接光照
0 绪论
基于物理的渲染. 其本质就是根据物理世界中光与材质之间的交互方式.提出了一种方案模拟其效果.
其理论主要基于以下三个:
- 基于微平面(Microfacet)的表面模型
- 能量守恒
- 应用基于物理的BRDF
PBR 其实是一个光照模型.
在经典的光照模型中:
- 漫反射是 Lambert
- 镜面反射是 blinn-Phong
- 环境光是 c * (1-AO)
PBR:
- 漫发射是 Lambert/PI.
- 镜面反射是 Cook-Torrance.
- 环境光是 IBL (Image-Based Lighting).
PBR材质

1 反射方程
L o = ∫ Ω f ( p i , w i , w o ) L ( p i , w i ) n ⋅ w i d w i \begin{array}{l}L_o=\int_\Omega f\left(p_i,w_i,w_o\right)L\left(p_i,w_i\right)n\cdot w_idw_i\\\end{array} Lo=∫Ωf(pi,wi,wo)L(pi,wi)n⋅widwi
L o L_o Lo : 表示经过着色之后 从 w o w_o wo方向观察点 p_i 时的颜色;
f ( p i , w i , w o ) f\left(p_i,w_i,w_o\right) f(pi,wi,wo) : 表示的是点 p i p_i pi 上,从 w o w_o wo 方向反射出去的光照与从 w i w_i wi 方向的入射的光照的比值,该函数称为BRDF(Bidirectional Reflection Distribution Function).
L i L_i Li : 表示从 w i w_i wi方向入射观察点 p_i 时的光照;
n ⋅ w i n\cdot w_i n⋅wi : 表示入射光 w i w_i wi 与 法线 n n n 之间的关系.
∫ Ω . . . d w i \int_\Omega...dw_i ∫Ω...dwi : 表示在点 p i p_i pi 法线方向上的半球,所有入射光线方向的积分
当光照射到物体表面. 分成两种反射的分量进行处理:
- 漫反射
- 镜面高光反射
将原先的BRDF函数分为了两个不同的部分:漫反射部分和镜面反射部分
反射方程可以等效为:
L o = ∫ Ω ( f d + f s ) L ( p i , w i ) n ⋅ w i d w i L_o=\int_\Omega\left(f_d+f_s\right)L\left(p_i,w_i\right)n\cdot w_idw_i Lo=∫Ω(fd+fs)L(pi,wi)n⋅widwi
2 PBR之直接光照
在直接光照部分. 由于我们知道每一个光源的位置 / 方向 以及光照颜色.
针对单一光源有: 物体表面上同一个点只会从一个方向接受到来自光源的光照
所以可以用简单的叠加来避免积分的计算:
即有:
L o = ( f d + f s ) L i ( n ⋅ w i ) L_o=\left(f_d+f_s\right)L_i\left(n\cdot w_i\right) Lo=(fd+fs)Li(n⋅wi)
2.1 漫反射
漫反射.它模拟的是从物体内部反射出去的光线效果.
Lambertian Reflection模型实际上假设物体内部反射出来的光线,是均匀的分布在半球上的,所以这种模型又被称之为Perfect Diffuse Reflection.
f d = C π f_d={\textstyle\frac{\mathrm C}{\mathrm\pi}} fd=πC
其中:
C C C : 表示 albedo贴图上采样得到的值
在经典光照模型中. 漫反射系数就是 albedo贴图采样得到的值.为什么PBR中多除了一个 π \mathrm\pi π 呢?
- 为了保证能量守恒
其实,实际上还乘了个 k d k_d kd
k d k_d kd 的计算与镜面反射中 F的求解有关.
2.2 镜面反射
PBR的镜面反射是 Cook-Torrance镜面反射光照模型
f s = D F G 4 ( w i ⋅ n ) ( w o ⋅ n ) \begin{array}{l}f_s=\frac{DFG}{4\left(w_i\cdot n\right)(w_o\cdot n)}\\\end{array} fs=4(wi⋅n)(wo⋅n)DFG
D 法线分布函数 Normal Distribution Function(NDF)
这个函数描述的是:
- 微表面法线的分布.
- 当越多的微表面法线与宏观表面法线相近的时候. 高光区域会越亮. 区域越小. 反之. 高光区域会越暗. 区域越大.
- 这个函数返回的是一个标量
N D F G G X T R ( n , h , a ) = a 2 π ( ( n ⋅ h ) 2 ( a 2 − 1 ) + 1 ) 2 \begin{array}{l}NDF_{GGXTR}\left(n,h,a\right)=\frac{a^2}{\pi\left(\left(n\cdot h\right)^2\left(a^2-1\right)+1\right)^2}\\\end{array} NDFGGXTR(n,h,a)=π((n⋅h)2(a2−1)+1)2a2
其中.
h h h : 表示 半程向量. 即 blinn-Phong 计算高光反射时候使用的半程向量. 即 h = L + V ∣ L + V ∣ h=\frac{L+V}{\left|L+V\right|} h=∣L+V∣L+V
a a a : 表示 微表面的粗糙程度. 通过对粗糙纹理采样获得.
loat D_GGX_TR(vec3 N, vec3 H, float a)
{
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float nom = a2;
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
return nom / denom;
}
F 菲涅尔方程
F 表示 被反射的光线 所占的比率
这个比率会随着我们观察的角度不同而不同。
当光线碰撞到一个表面的时候,菲涅尔方程会根据观察角度告诉我们被反射的光线所占的百分比。
利用这个反射比率和能量守恒原则,我们可以直接得出光线被折射的部分以及光线剩余的能量。
F ( h , v , F 0 ) = F 0 + ( 1 − F 0 ) ( 1 − h ⋅ v ) 5 \begin{array}{l}F\left(h,v,F_0\right)=F_0+(1-F_0)(1-h\cdot v)^5\\\end{array} F(h,v,F0)=F0+(1−F0)(1−h⋅v)5
其中:
h h h : 表示半程向量
v v v : 表示观察向量
F 0 F_0 F0 : 表示 表面的基本反射属性
F项描述的是镜面反射部分的比例,那么漫反射部分的比例自然就是1 - F了.
注意:
- 对于金属材质来说,只有镜面反射,没有漫反射。也就是说,这里的F项,需要区别对待金属材质和非金属材质
- 所以需要引入一个 金属材质
Metallic
对于 非金属材质 来说,我们就直接认定 F 0 F_0 F0=0.04
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
vec3 F0 = vec3(0.04);
F0 = mix(F0, surfaceColor.rgb, metalness);
vec3 F = fresnelSchlick( max(HdotV,0.0),F0);
就是说F即镜面高光反射的部分.即 K s K_s Ks
求可以求出 漫反射部分 K d K_d Kd
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
kD *= 1.0 - metallic;
G 几何函数
几何函数从统计学上近似的 求得了微平面间相互遮蔽的比率,这种相互遮蔽会损耗光线的能量.
几何函数采用一个材料的粗糙度参数作为输入参数,粗糙度较高的表面其微平面间相互遮蔽的概率就越高.
G项描述了 几何遮蔽 和 几何阴影 两种情况:
- 观察方向(几何遮蔽(Geometry Obstruction))
- 光线方向向量(几何阴影(Geometry Shadowing))
G ( n , v , l , k ) = G s u b ( n , v , k ) ⋅ G s u b ( n , l , k ) G\left(n,v,l,k\right)=G_{sub}(n,v,k)\cdot G_{sub}(n,l,k) G(n,v,l,k)=Gsub(n,v,k)⋅Gsub(n,l,k)
G S c h l i c k G G X ( n , v , k ) = n ⋅ v ( n ⋅ v ) ( 1 − k ) + k G_{SchlickGGX}\left(n,v,k\right)=\frac{n\cdot v}{\left(n\cdot v\right)(1-k)+k} GSchlickGGX(n,v,k)=(n⋅v)(1−k)+kn⋅v
这里的k是α基于几何函数是针对直接光照还是针对IBL光照的重映射(Remapping) :
k d i r e c t = ( a + 1 ) 2 8 k_{direct}=\frac{(a+1)^2}8 kdirect=8(a+1)2
k i b l = a 2 2 k_{ibl}=\frac{a^2}2 kibl=2a2
float GeometrySchlickGGX(float NdotV, float k)
{
float nom = NdotV;
float denom = NdotV * (1.0 - k) + k;
return nom / denom;
}
float GeometrySmith(vec3 N, vec3 V, vec3 L, float k)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx1 = GeometrySchlickGGX(NdotV, k);
float ggx2 = GeometrySchlickGGX(NdotL, k);
return ggx1 * ggx2;
}
3 总结
直接光照的反射方程:
L o = ( k d f d + k s f s ) L i ( w i ⋅ n ) L_o=(k_df_d+k_sf_s)L_i\left(w_i\cdot n\right) Lo=(kdfd+ksfs)Li(wi⋅n)
- 其中 k s k_s ks 和 F F F 是一个东西. 只需要计算一次. 把打出来只是为了强调 能量守恒 这个关系.
最终的直接光照反射方程为:
L o = ( k d C π + D F G 4 ( w i ⋅ n ) ( w o ⋅ n ) ) L i ( w i ⋅ n ) L_o=(k_d\frac C\pi+\frac{DFG}{4\left(w_i\cdot n\right)\left(w_o\cdot n\right)})L_i\left(w_i\cdot n\right) Lo=(kdπC+4(wi⋅n)(wo⋅n)DFG)Li(wi⋅n)
注意事项
PBR对计算空间的每个值是否为线性的有强烈的依赖性. 必须有:
- HDR
- Gamma校正
// base tone mapping
color = color / (color + vec3(1.0, 1.0, 1.0));
// gamma correction
color = pow(color, vec3(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2));
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)