本人笔记,不喜勿喷
PBR在英文里面是 Physically Based Rendering 翻译成中文就是基于物理的渲染。
反射 散射 生成diffuse 漫反射
反射 生成Specular 镜面反射
进入物体生成透射
实现pbr渲染,抽象出来了相应的渲染方程
BSDF 双向散射表面分布函数,
这个由两部分组成,一部分是表面的函数 BSSRDF(双向散射表面反射分布函数)由BRDF(双向反射率分布函数)和SSS(次表面散射Subsurface scattering)组成。
另一部分是BSSTDF(双向散射表面透射率分布函数),由BTDF(双向透射率分布函数)和SSS(次表面散射Subsurface scattering)组成。
它们整体的组成了一个完整的渲染方程。
里面的重点是BRDF,简化计算,广泛应用于游戏领域。
基于微平面理论的BRDF
理论原理,在微观视角小的物体都是凹凸不平的,根据此角度进行相关推理而出。
迪士尼的PBS
基本原则:
实现:
漫反射项:迪士尼的diffuse
镜面反射:microfacet Cook-Torrance BRDF
这个分出三项来解释:D项 (法线分布函数)镜面高光 F项 菲涅尔 G项 几何遮挡
模拟方程:
Kd和Ks小于等于1,用于控制能量守恒
Fd是基本色 一般值为1/Pi * DiffuseColor
Fs是高光 SpecularColor 由DGF三项计算得出
D项
可以用来描述表面的平整度(宏观说就是光滑度或者粗糙度)
G项
用来描述光在微观平面产生的阴影,和视角方向的遮挡。
F项
菲涅尔方程
Fs 结果为 D * G * F /(4 * N dot L * N dot V)
N为法向 L为光的方向 V 为视角方向
主流演化,将G项和(4 * N dot L * N dot V)整合,演化成V项(The Visibility Term)简称V项
所以结果演变成 Kd / Pi + Ks * (D * V * F)
unity的变种:Kd + Ks * (D * V * F)* Pi 比正常亮度 高PI倍
光照公式:(DiffuseColor / Pi + SpecularColor * D * V * F) * NdotL * LightColor
各种公式选择
Diffuse BRDF
Specular BRDF
D项 定义了高光的形状
V项 解析了由于微平面相互这笔导致的光衰减(需要和D项配对使用)
F项 菲涅尔 根据视角和平面朝向计算反射率,如果朝向和视角方向趋于平行,菲涅尔越弱,也会受入射光影响。F0就是平面朝向和视角朝向趋于平衡,也是物体默认的反射率(返回的结果就是SpecularColor)。F90为,视角朝向和物体朝向呈90度角度得出的结果。
F0 为三通道的RGB彩色的值,金属的值都相对较高 0.5-1
金属的DiffuseColor = 0 颜色都是来自于F0
电解质颜色一般为单色 F0 0.02-0.05 PBR里面一般将此作为非金属
用的最多的是 Schlick ,他提出了一种近似得方法,利用已知的F0,就是默认的反射率,来求出菲涅尔反射率。
光照公式进一步优化:
(DiffuseColor / Pi + (D * Roughness) * (V * Roughness) * (F * SpecularColor)) * NdotL * LightColor
基于物理的环境光照
漫反射
镜面反射
分解求和近似
LD 预过滤环境映射 就是环境反射球 mipmap
DFG 环境BRDF 使用2D LUT或者解析拟合 函数如下
float3 EnvDFGLazarov( float3 specularColor, float gloss, float ndotv )
{
float4 p0 = float4( 0.5745, 1.548, -0.02397, 1.301 );
float4 p1 = float4( 0.5753, -0.2511, -0.02066, 0.4755 );
float4 t = gloss * p0 + p1;
float bias = saturate( t.x * min( t.y, exp2( -7.672 * ndotv ) ) + t.z );
float delta = saturate( t.w );
float scale = delta - bias;
bias *= saturate( 50.0 * specularColor.y );
return specularColor * scale + bias;
}
间接光照公式:IndirectLighting = DiffuseColor / pi * SH + LD * DFG(SpecularColor)
直接光照公式: DirectLighting = (DiffuseColor / pi + D(Roughness,x) * V(Roughness,x) * F(SpecularColor,x) )* NdotL * LightColor
AO 环境光遮蔽
一般使用的两种:
一种是自身物体生成,可以通过软件烘焙出的,用于自身的,一般是AO贴图。
另一种是物体和物体之间生成的,可以通过屏幕空间技术得到,比如SSAO。
一般两者取最小的值进行混合。(个人感觉取中间值比较好)。