Cook-Torrance BRDF 和 Lambert BRDF 上有很多材料。Unreal Engine 4 中的 Real Shading和Moving Frostbite to BPR深入解释了如何实现它们以进行实时渲染。
他们忽略了两个 BRDF 的组合来创建完整的着色模型。如果我理解正确,我们至少可以使用两个基本原则来做到这一点:镜面反射和金属度工作流程。这是它们的比较。
我决定实施金属性工作流程。所以我有以下参数来计算:
- 反照率 (RGB)
- 粗糙度(浮动)
- 金属度(浮动)
对于镜面反射部分,我需要确定我的镜面反射颜色。
Mamoset指出
使用金属度贴图时,绝缘表面 - 在金属度贴图中设置为 0.0(黑色)的像素 - 被分配一个固定的反射率值(线性:0.04 sRGB:0.22)并使用反照率贴图作为漫反射值。对于金属表面——在金属度贴图中设置为 1.0(白色)的像素——镜面反射颜色和强度取自反照率贴图,并且在着色器中将漫反射值设置为 0(黑色)。
因此,镜面反射颜色应通过以下方式计算:
vec3 specularColor = mix(vec3(0.04), material.albedo, material.metalness);
随后,这可用于计算反射辐射率。为了限制我的问题的范围,我将在此处参考Brian Karis的实现,如下所示:
vec3 L_specular = specularIBL(specularColor, material.roughness, normal, view);
对于漫反射部分,我需要确定反照率。
上面的同一引文描述了它的工作原理:
vec3 albedo = mix(material.albedo, vec3(0), material.metalness);
现在,Lambert BRDF 可用于计算来自一些入射辐照度 E 的漫反射光照:
vec3 L_diffuse = f_lambert(albedo) * E;
为了获得最终的辐射,将漫反射和镜面反射部分结合起来:
vec3 L = kd * L_diffuse + ks * L_specular;
我的问题是如何计算kd
和ks
?
- Codinglabs建议在半球上整合菲涅尔函数来计算
ks
.
kd
之后通过以下方式计算:
vec3 kd = (1 - ks) * (1 - material.metalness);
例如,当将它与虚幻引擎进行比较时,我在非金属上得到的结果并不是我所期望的。在法向入射时,反射比预期的要低得多,这应该是由于在非金属情况下设置的低 F0。但我检查了进一步的来源,0.04 似乎是常用的值。
有人可以确认Codinglabs的建议计算吗?甚至提供 Epic 使用的代码?