添加PBR高光
贴图信息
金属度信息在下方贴图G通道中,高光遮罩在B通道

金属

高光Mask

光滑度信息在下方贴图的G通道中

G通道

金属和非金属划分

金属和非金属漫反射划分
这里pbrDiffuseColor进行金属与非金属的划分,非金属的最大漫反射比例是0.96,0.96 x GammColor就是非金属的漫反射,而金属部分是只有镜面反射的没有漫反射,所以漫反射为0

float3 pbrDiffuseColor = lerp(0.96 * gammaColor, 0, metallic);
金属和非金属镜面反射划分
pbrSpecularColor镜面反射,非金属的镜面反射比例就是1-0.96,因为非金属的镜面反射颜色不受本身颜色影响仅受材料的反射率影响,所以这里给上0.04固定颜色。而金属部分,金属的镜面反射是受颜色影响的所以反射原本的颜色

float3 pbrSpecularColor = lerp(0.04, gammaColor, metallic);

PBR高光计算
参数新增
分别对应是球形高光开关,球形高光范围,高光软硬度,高光范围

参数声明

获取贴图金属,高光遮罩信息
初始化

读取金属度和高光Mask

高光形状划分
对于高光方面,现在我们需要对头发的高光形状进行划分,非金属中仅头发高光就采用球形高光,而其余的高光使用本身的法线影响。这里设置球形高光开关和范围

常规计算高光方式
高光的常规计算方式是Phong和BlinnPhong
Phong BRDF
公式: K是指SpecularIntensity高光强度,R是灯光向量(-L)的反射向量,V是观察向量,这里需要指明一点这里参加计算的灯光向量是物体指向灯光的向量,也就是-L


常规计算代码:
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更好


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计算的结果



URP的BRDF.hlsl文件中也有介绍,但这里是使用的优化版的减少计算量

简化方式简单来说就是将F(菲涅尔项)与G(几何遮蔽项)变成了V点乘F

将含G的这部分式子替换成V了

不需要纠结怎么简化的,反正最后优化成近似的结果,V乘F公式就变成了下面这个,L是光向量,H是半角向量
V * F = 1.0 / ( LoH^2 * (roughness + 0.5) )
计算公式就变成了
BRDFspec = (D * V * F) / 4.0
Finalspec = (D * V * F) / 4.0 * NoL
饰品部分的卡通高光计算
获取半角向量
根据公式需要,计算半角向量

计算LoH
根据公式需要,这里计算LoH和LoH的平方参数,对LoH也进行重映射,因为希望保持高光一直在最暗的时候也存在

计算NoL
根据公式需要,最后需要乘上NoL,所以这里计算NoL并重映射提高暗处的亮度

URP中对LoH2做了处理所以这里直接照搬

头发和其余部分法线参数划分
对于非金属中的头发使用球形法线,而其他部分使用原本的贴图法线,根据_HeadSphereRang进行控制范围


头发和其余部分高光项划分
上面对头发和其余非金属的法线进行了划分,那么自然计算的NoH高光项也需要进行区分。最后将范围和Mask结合然后受衰减影响

上面对球形法线计算的shapeAttenuation做了开方处理,进行平滑处理,让高光强度衰减的更慢。下面的图可以更清晰的观察。

饰品卡通类高光部分最终计算
这里使用了softness参数控制软硬度。最后计算高光的公式在前面讲过: Finalspec = (D * V * F) / 4.0 * NoL 因为V * F = 1.0 / ( LoH^2 * (roughness + 0.5) ),代入进公式即可,因为是非金属,直接就粗糙度给1就行,所以6.0 x rangeLoH2就是这么来的

衣服部分写实类高光计算
参数新增
GGX的算法需要粗糙度信息所以需要获取贴图信息 这里参数分别是光滑度,Toon高光强度,根据模型大小控制高光强度的系数,整体高光强度,高光染色

获取贴图光滑度信息

身体部分

面部 面部没有金属和光滑度信息所以直接控制就行

计算GGX
金属部分直接使用GGX的计算方法就行,照抄代码

调整高光信息并乘上NoL

混合输出
使用强度系数进行混合控制Specular强度,设置混合染色

我们在最开始进行系数计算现在就可以用了,漫反射和镜面反射分别乘上albedo在相加输出

当前效果



