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

彩虹色(Iridescence)

彩虹色描述了一种色调随观察角和光照角变化的效果。

  • 半透明层的薄膜产生相互反射,由于薄膜干涉,某些波长被吸收或放大。
  • 例子包括肥皂泡、油膜和昆虫翅膀。
  • 此扩展允许指定薄膜的厚度折射率(IOR),实现彩虹色材质。

属性

类型 描述 必需
iridescenceFactor 彩虹色强度因子。 否,默认值:0.0
iridescenceTexture 彩虹色强度纹理。
iridescenceIor 薄膜层的折射率。 否,默认值:1.3
iridescenceThicknessMinimum 最小薄膜厚度(纳米)。 否,默认值:100.0
iridescenceThicknessMaximum 最大薄膜厚度(纳米)。 否,默认值:400.0
iridescenceThicknessTexture 厚度纹理。
  • 强度计算
iridescence = iridescenceFactor * iridescenceTexture.r
  • 如果未设置纹理,假设值为1.0

  • 如果iridescenceFactor为零(默认),效果被禁用。

  • 厚度计算

thickness = mix(
iridescenceThicknessMinimum,
iridescenceThicknessMaximum,
iridescenceThicknessTexture.g
)
  • 如果缺少厚度纹理,默认为iridescenceThicknessMaximum
  • 色调变化源于反射波长的相长和相消干涉
  • 接近可见光波长一半(380–750 nm)的薄膜厚度产生最强的效果。
  • 增加厚度由于混合干涉产生柔和色彩图案

原理解释


折射率(IOR)

  • 薄膜折射率(iridescenceIor)可以与基础材质不同。
  • 薄膜折射率与基础材质折射率之间的差异越大,彩虹色效果越强
  • 折射率影响光程差和颜色偏移。

不同厚度效果

不同折射率效果


彩虹色BRDF

效果使用微表面BRDF和修改的菲涅尔反射项建模。

金属基础材质

metal_brdf =
iridescent_conductor_layer(
iridescence_strength = iridescence,
iridescence_thickness = iridescenceThickness,
iridescence_ior = iridescenceIor,
outside_ior = 1.0,
base_f0 = baseColor,
specular_brdf = specular_brdf(α = roughness^2)
)

电介质基础材质

dielectric_brdf =
iridescent_dielectric_layer(
iridescence_strength = iridescence,
iridescence_thickness = iridescenceThickness,
iridescence_ior = iridescenceIor,
outside_ior = 1.0,
base_ior = 1.5,
base = diffuse_brdf(color = baseColor),
specular_brdf = specular_brdf(α = roughness^2)
)
  • 对于透射材质diffuse_brdf被与specular_btdf的混合替换(见KHR_materials_transmission)。

  • base_ior可以通过KHR_materials_ior修改。

  • KHR_materials_specular结合时:

dielectric_brdf =
iridescent_dielectric_layer(
iridescence_strength = iridescence,
iridescence_thickness = iridescenceThickness,
iridescence_ior = iridescenceIor,
outside_ior = 1.0,
base_ior = 1.5,
base_f0_color = specularColor.rgb,
specular_weight = specular,
base = diffuse_brdf(color = baseColor),
specular_brdf = specular_brdf(α = roughness^2)
)
  • 清漆层忽略与薄膜的界面以简化。

实现说明

金属基础材质

function iridescent_conductor_layer(iridescence_strength, iridescence_thickness, iridescence_ior, outside_ior, base_f0, specular_brdf) {
return mix(
conductor_fresnel(base_f0, specular_brdf),
specular_brdf * iridescent_fresnel(outside_ior, iridescence_ior, base_f0, iridescence_thickness),
iridescence_strength
)
}

电介质基础材质

function iridescent_dielectric_layer(iridescence_strength, iridescence_thickness, iridescence_ior, outside_ior, base_ior, base, specular_brdf) {
base_f0 = ((1 - base_ior)/(1 + base_ior))^2

iridescent_f = iridescent_fresnel(outside_ior, iridescence_ior, base_f0, iridescence_thickness)

return mix(
fresnel_mix(base_ior, base, specular_brdf),
rgb_mix(base, specular_brdf, iridescent_f),
iridescence_strength
)
}
  • rgb_mix确保能量守恒
function rgb_mix(base, specular_brdf, rgb_alpha) {
rgb_alpha_max = max(rgb_alpha.r, rgb_alpha.g, rgb_alpha.b)
return (1 - rgb_alpha_max) * base + rgb_alpha * specular_brdf
}
  • KHR_materials_specular结合时,添加base_f0_color和specular_weight:
function iridescent_dielectric_layer(...) {
base_f0 = ((1-base_ior)/(1+base_ior))^2 * base_f0_color
base_f0 = min(base_f0, float3(1.0))
fr = base_f0 + (1 - base_f0)*(1 - abs(VdotH))^5

iridescent_f = iridescent_fresnel(outside_ior, iridescence_ior, specular_weight * base_f0, iridescence_thickness)

return rgb_mix(base, specular_brdf, mix(specular_weight * fr, iridescent_f, iridescence_strength))
}

彩虹色菲涅尔

  • 建模两个材质界面

    1. 外部 → 薄膜
    2. 薄膜 → 基础材质

菲涅尔方程

float IorToFresnel0(float transmittedIor, float incidentIor) {
return pow((transmittedIor - incidentIor) / (transmittedIor + incidentIor), 2.0);
}
  • 使用斯涅尔定律计算折射角的余弦:
float sinTheta2Sq = pow(outsideIor / iridescenceIor, 2.0) * (1.0 - pow(cosTheta1, 2.0));
float cosTheta2Sq = 1.0 - sinTheta2Sq;

if (cosTheta2Sq < 0.0) return vec3(1.0); // 全内反射

float cosTheta2 = sqrt(cosTheta2Sq);

相移

Δφ = (2π / λ) * OPD
OPD = 2 * iridescenceIor * iridescenceThickness * cosTheta2
  • 每个界面的基础相位根据折射率关系近似为0.0或π。
  • 忽略偏振。

解析光谱积分

  • 傅里叶空间中计算反射项:
vec3 R123 = clamp(R12 * R23, 1e-5, 0.9999);
vec3 r123 = sqrt(R123);
vec3 Rs = sq(T121) * R23 / (vec3(1.0) - R123);

vec3 C0 = R12 + Rs;
I = C0;

for (int m = 1; m <= 2; ++m) {
Cm *= r123;
vec3 Sm = 2.0 * evalSensitivity(float(m) * OPD, float(m) * phi);
I += Cm * Sm;
}

F_iridescence = max(I, vec3(0.0));
  • 敏感性函数:
vec3 evalSensitivity(float OPD, vec3 shift) {
float phase = 2.0 * M_PI * OPD * 1.0e-9;
vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13);
vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06);
vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09);

vec3 xyz = val * sqrt(2.0 * M_PI * var) * cos(pos * phase + shift) * exp(-sq(phase) * var);
xyz.x += 9.7470e-14 * sqrt(2.0 * M_PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift[0]) * exp(-4.5282e+09 * sq(phase));
xyz /= 1.0685e-7;

vec3 rgb = XYZ_TO_REC709 * xyz;
return rgb;
}
  • 颜色空间转换矩阵:
const mat3 XYZ_TO_REC709 = mat3(
3.2404542, -0.9692660, 0.0556434,
-1.5371385, 1.8760108, -0.2040259,
-0.4985314, 0.0415560, 1.0572252
);

完整推导在Belcour & Barla, 2017, section 4(解析光谱积分)中描述。


参考文献

  • Belcour, L. and Barla, P. (2017): 微表面理论在变化彩虹色建模中的实用扩展
  • Autodesk: Arnold for Maya用户指南 - 薄膜
  • Drobot, M. and Micciulla, A. (2017): 使命召唤:无限战争中的实用多层材质
  • Kneiphof, T., Golla, T., Klein, R. (2019): 变化彩虹色的微表面BRDF实时基于图像照明
  • Akenine-Möller, T. et al. (2018): 实时渲染,第四版,第361页及以后
  • Sussenbach, M. (2013): 实时渲染彩虹色物体