本文为这篇文章的翻译与整理

清漆层(Clearcoat)

类型 描述 必需
clearcoatFactor 清漆层强度。 否,默认值:0.0
clearcoatTexture 清漆层强度纹理。
clearcoatRoughnessFactor 清漆层粗糙度。 否,默认值:0.0
clearcoatRoughnessTexture 清漆层粗糙度纹理。
clearcoatNormalTexture 清漆层法线贴图纹理。

如果clearcoatFactor为零,整个清漆层将被禁用。

值计算

清漆层强度和粗糙度可以使用因子纹理或两者来定义。

  • 如果未提供clearcoatTextureclearcoatRoughnessTexture,则假设其纹理分量的值为1.0
  • 所有清漆层纹理在线性空间中包含RGB分量。
  • 如果同时存在因子和纹理,因子作为线性乘数
clearcoat = clearcoatFactor * clearcoatTexture.r
clearcoatRoughness = clearcoatRoughnessFactor * clearcoatRoughnessTexture.g
  • 如果未提供clearcoatNormalTexture,则不对清漆层应用法线映射。
  • 它可以引用与基础材质相同的法线贴图或任何兼容的法线贴图。

切线空间要求

使用带有清漆层法线纹理的清漆层材质的网格基元必须具有定义的切线空间:

  • 必须具有NORMALTANGENT属性,或者
  • 基础材质必须具有法线纹理。

如果缺失,切线向量将按照glTF 2.0的定义进行计算。

  • 网格基元应该提供NORMALTANGENT向量。
  • 如果同时定义了normalTextureclearcoatNormalTexture,它们应该使用相同的纹理坐标。

BRDF建模

清漆层效果通过微表面BRDF建模,层叠在glTF 2.0金属-粗糙度材质之上:

# 基础glTF 2.0金属-粗糙度
material = mix(dielectric_brdf, metal_brdf, metallic)

# 清漆层
clearcoat_brdf = specular_brdf(
normal = clearcoatNormal,
α = clearcoatRoughness^2
)

# 分层
coated_material =
fresnel_coat(
normal = clearcoatNormal,
ior = 1.5,
weight = clearcoat,
base = material,
layer = clearcoat_brdf
)
  • fresnel_coat使用菲涅尔项将BRDF作为层添加在另一个BSDF之上
weight_layer = weight * fresnel(ior)
weight_base = 1 - weight_layer
  • normal仅影响顶层。

实现(非规范性)

  • 实现可能因设备性能资源而异。

清漆层BRDF

镜面BRDF使用glTF 2.0金属-粗糙度镜面项

  • 粗糙度和法线来自clearcoatNormalclearcoatRoughness

分层

fresnel_coat函数使用Schlick菲涅尔项

function fresnel_coat(normal, ior, weight, base, layer) {
f0 = ((1-ior)/(1+ior))^2
fr = f0 + (1 - f0)*(1 - abs(dot(V, normal)))^5
return mix(base, layer, weight * fr)
}
  • 应用函数:
coated_material = mix(
material,
clearcoat_brdf(clearcoatRoughness^2),
clearcoat * (0.04 + (1 - 0.04) * (1 - VdotNc)^5)
)
  • 使用附录B中的符号:
clearcoat_fresnel = 0.04 + (1 - 0.04) * (1 - abs(VdotNc))^5
clearcoat_alpha = clearcoatRoughness^2
clearcoat_brdf = D(clearcoat_alpha) * G(clearcoat_alpha) / (4 * abs(VdotNc) * abs(LdotNc))

coated_material = mix(material, clearcoat_brdf, clearcoat * clearcoat_fresnel)

发射

  • 清漆层位于发射之上
  • 因此,发射被菲涅尔项变暗:
coated_emission = emission * (1 - clearcoat * clearcoat_fresnel)

讨论

为了通过简单的分层函数保持能量守恒

  • 微表面菲涅尔项使用NdotV而不是VdotH
  • 忽略微表面的方向。
  • 低清漆层粗糙度近似为NdotV ≈ NdotL

局限性:

  • 假设清漆层无限薄(无折射)。
  • 层的折射率独立计算。
  • 层间无散射。
  • 无衍射。

参考文献

  • 理论、文档和实现
  • Autodesk标准表面 - 涂层
  • AxF - 外观交换格式
  • Blender原理化BSDF
  • Disney BRDF探索器
  • 企业PBR着色模型 - 清漆层
  • Filament材质模型 - 清漆层
  • Disney的基于物理着色
  • Substance Painter - 更新的清漆着色器
  • ALLEGORITHMIC的PBR指南(第1部分和第2部分)
  • 虚幻引擎4材质 - 清漆层