10_添加PBR高光
添加PBR高光
贴图信息
找到找到DataTex1贴图组,其中G通道就是金属度,B通道是高光遮罩
金属度
高光遮罩 
找到DataTex2组,光滑度信息在G通道中
光滑度 
提取贴图信息
金属和高光遮罩
修改之前解释DataTex1的组,提取金属和高光遮罩信息

光滑度
修改之前解释DataTex2的组,提取光滑度信息
这里注意默认给0.58的光滑度而不是0 
PBR漫反射和高光划分
划分比例

创建DividePBRColor新组
pbrDiffuseColor进行金属与非金属的划分,非金属的最大漫反射比例是0.96,0.96 x Color就是非金属的漫反射,而金属部分是只有镜面反射的没有漫反射,所以漫反射为0。pbrSpecularColor镜面反射,非金属的镜面反射比例就是1-0.96,因为非金属的镜面反射颜色不受本身颜色影响仅受材料的反射率影响,所以这里给上0.04固定颜色。而金属部分,金属的镜面反射是受颜色影响的所以反射原本的颜色 
高光的一般计算方法
高光的常规计算方式是Phong和BlinnPhong
Phong BRDF
公式: K是指SpecularIntensity高光强度,R是灯光向量(-L)的反射向量,V是观察向量,这里需要指明一点这里参加计算的灯光向量是物体指向灯光的向量,也就是-L
常规计算代码:
1
2
3
float3 reflect_dir = reflect(-light_dir, normal_dir); //获取灯光反射向量
float RdotV = dot(reflect_dir, view_dir);//数值范围在-1~1所以需要限制
float3 specular = pow(max(0.0, RdotV), _Shininess) * _SpecularIntensity;
Blinn-Phong BRDF
K是指SpecularIntensity高光强度,H是半角向量是L和V之间的向量,V是观察向量,它不需要计算反射所以性能被Phong更好

1
2
half3 half_dir = normalize(light_dir + view_dir);//获得灯光与视角中间的半角向量
half NdotH = dot(normal_dir, half_dir);///数值范围在-1~1所以需要限制
PBR中 GGX BRDF高光计算
相关资料 https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/siggraph2015_2D00_mmg_2D00_renaldas_2D00_notes.pdf 公式: 公式看起来太复杂了,说人话就是D是像NoH粗糙度影响然后乘上SpecularMask得到高光形状(这部分可以由我们自己调整),F是菲涅尔系数,G是物体表面的遮蔽。F和G是固定公式 GGX高光计算
不乘上面末尾的NoL就是BRDF计算的结果

Unity中URP的BRDF.hlsl文件中也有介绍,但这里是使用的优化版的减少计算量
简化方式简单来说就是将F(菲涅尔项)与G(几何遮蔽项)变成了V点乘F
将含G的这部分式子替换成V了
不需要纠结怎么简化的,反正最后优化成近似的结果,V乘F公式就变成了下面这个,L是光向量,H是半角向量
1
V * F = 1.0 / ( LoH^2 * (roughness + 0.5) )
计算公式就变成了
1
2
3
BRDFspec = (D * V * F) / 4.0
Finalspec = (D * V * F) / 4.0 * NoL
Forward组输入参数增加
分别对应金属度,光滑度,头部球形法线范围,总高光强度,球形法线高光开关,高光范围,高光软硬度控制,高光Toon强度,根基模型大小控制高光强度的额外控制
高光染色 
饰品类PBR卡通高光计算
参数处理
使用MatID和Select组处理输入 
创建高光Shader组

计算HalfDir和传入参数
传入对应参数 
计算球形法线使用范围
Specular内 头发部分使用球形法线,其余部分使用贴图法线,使用顶点位置减去球心HeadCenter位置就可以得到球状法线,使用HeadSphereRang进行控制范围计算出球形法线的一个遮罩,使用遮罩对贴图法线和球形法线混合输出 

使用球状遮罩混合法线
当HeadSphereRang有效时输出混合的法线,无效则输出贴图法线 
计算高光项和衰减项
根据公式,计算高光项ShapeNoH。当HeadSphereRang计算ShapeAttenuation,反之使用原贴图法线计算的BaseAttenuation
使用混合法线计算的衰减进行了开方和重映射都是为了调整曲线,增加高光的有效范围,开放可以使高光的衰减变平缓 
最终计算
1
2
V * F = 1.0 / ( LoH^2 * (roughness + 0.5) )
Finalspec = (D * V * F) / 4.0 * NoL
回忆公式,这里VxF项中Roughness直接给1,然后直接使用公式计算
计算完(D * V * F) / 4.0后和RangeNoL相乘就得到高光了

衣服类PBR写实高光计算
这里直接照抄GGX就行
1
2
3
brdfData.normalizationTerm = (roughness + 0.5) * 4.0
Final BRDFspec = roughness^2 / ( NoH^2 * (roughness^2 - 1) + 1 )^2 * (LoH^2 * (roughness + 0.5) * 4.0)
光滑度转粗糙度等参数处理
这里还是使用GGX的计算方式,但需要引入粗糙度计算了,贴图给的是光滑度,需要进行处理,这里直接新建一个处理光滑度的组
这里计算Roughness的相关参数。光滑度转粗糙度是1-Smoothness在平方,1-Smoothness是感知粗糙度,真正参与计算的是它的平方,也就是粗糙度 
计算GGX
根据公式直接计算GGX高光,这里直接使用贴图法线计算 
最终混合
计算完GGX后减去光滑度,降低光滑表面的高光强度,然后乘上光照衰减,钳制到0~1。除以粗糙度这里在提高粗糙表面的高光强度。最后使用两个参数控制高光强度然后乘上高光遮罩后就得到了高光,末尾的乘法相当于提高了高光的硬度 

两种高光混合
使用是否开启了球形法线为判断来混合,后面使用SpecularIntensity进行整体的强度控制,然后染色 

混合颜色
使用区域判断,因为高光在面部眼睛是没有的,所以使用身体开关判断
使用乘法进行计算,最后混合Diffuse和Specular直接加法混合即可 
当前效果
参数 默认总强度是0.01,头发需要开启球形法线高光,其余参数自己看着调就行

Enjoy Reading This Article?
Here are some more articles you might like to read next: