本文为这篇文章的翻译与整理
彩虹色(Iridescence)
彩虹色描述了一种色调随观察角和光照角变化的效果。
- 半透明层的薄膜产生相互反射,由于薄膜干涉,某些波长被吸收或放大。
- 例子包括肥皂泡、油膜和昆虫翅膀。
- 此扩展允许指定薄膜的厚度和折射率(IOR),实现彩虹色材质。
属性
| 类型 |
描述 |
必需 |
iridescenceFactor |
彩虹色强度因子。 |
否,默认值:0.0 |
iridescenceTexture |
彩虹色强度纹理。 |
否 |
iridescenceIor |
薄膜层的折射率。 |
否,默认值:1.3 |
iridescenceThicknessMinimum |
最小薄膜厚度(纳米)。 |
否,默认值:100.0 |
iridescenceThicknessMaximum |
最大薄膜厚度(纳米)。 |
否,默认值:400.0 |
iridescenceThicknessTexture |
厚度纹理。 |
否 |
iridescence = iridescenceFactor * iridescenceTexture.r
|
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 ) }
|
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)) }
|
彩虹色菲涅尔
建模两个材质界面:
- 外部 → 薄膜
- 薄膜 → 基础材质
菲涅尔方程
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): 实时渲染彩虹色物体