如灰尘保佑的礼物

Unity PBR 实现分析

实现一个PBR光照Shader,参考Unity URP管线的Lit.shader实现,这里做个记录。

URP管线的光照公式为:

\[L_{输出}=(L_{环境光照}+L_{直接光照})+L_{自发光}\]

环境光照计算

\[L_{环境光照}=(L_{环境漫反射} + L_{环境高光})*AO\]

环境漫反射

\[L_{漫反射颜色} = (L_{基础色} - L_{金属度}) * (1 - 0.04)\]

0.04是一个常量,Unity将非金属的反射率定义为4%。

环境光漫反射 等于 基础色贴图 减去 金属度贴图
漫反射颜色 = 基础色 - 金属度

金属度越强(白)表示对光线的吸收能力越强,光线能反射出的颜色就越暗。金属度为0时,光线则全部被材质表面吸收。

漫反射项用球谐光照求出,环境光照的漫反射部分,就可以通过漫反射颜色乘以漫反射项算出结果。

\[L_{环境漫反射} = L_{漫反射颜色} * L_{漫反射项}\]
环境光漫反射 等于 基础色贴图 乘以 金属度贴图
环境漫反射 = 漫反射颜色 * 漫反射项

环境高光

\[L_{环境高光} = L_{HDR采样} * L_{表面高光颜色}\]
环境光漫反射 等于 基础色贴图 乘以 金属度贴图
环境高光 = HDR采样 * 表面高光颜色

环境光照

用上面算出的环境漫反射加上环境高光就得出了环境光照结果。

环境光漫反射 等于 基础色贴图 加上 金属度贴图
环境光照 = 环境漫反射 + 环境高光

环境光照应用AO环境遮蔽

环境光漫反射 等于 基础色贴图 乘以 金属度贴图
环境光照 = 环境光照 * 环境遮蔽

直接光照计算

环境光漫反射 等于 基础色贴图 乘以 金属度贴图
直接高光 = 高光颜色 * BRDF
环境光漫反射 等于 基础色贴图 加上 金属度贴图
直接光照 = 直接漫反射 + 直接高光
环境光漫反射 等于 基础色贴图 乘以 金属度贴图
直接光照 = 直接光照 + 光照辐射

最终结果

环境光漫反射 等于 基础色贴图 加上 金属度贴图
输出光照 = 环境光照 + 直接光照
环境光漫反射 等于 基础色贴图 加上 金属度贴图
输出光照 = 输出光照 + 自发光