【光照】Unity[PBR]环境光中的[镜面IBL]

【从UnityURP开始探索游戏渲染】专栏-直达

核心原理

镜面IBL(Image-Based Lighting - Specular)是基于图像光照技术中的镜面反射部分,其核心技术是分裂求和近似法(Split Sum Approximation)。该方法将复杂的实时镜面积分拆分为预滤波环境贴图和BRDF积分两部分:预滤波环境贴图存储不同粗糙度下的环境光卷积结果,BRDF积分贴图(LUT)则编码菲涅尔与几何项的组合效应。数学表达式为:

L_o(p,\\omega_o)\\approx(\\int_\\Omega L_i(p,\\omega_i)d\\omega_i)∗(\\int_\\Omega \\frac {DFG}{4(\\omega_o \\cdot n)(\\omega_i \\cdot n)}n\\cdot \\omega_id\\omega_i)

其中D为GGX法线分布函数,F为菲涅尔项,G为史密斯几何遮蔽函数。

在PBR渲染中的作用

物理准确性‌:

  • 通过预计算环境光的镜面反射分量,实现与视角相关的精确高光反射,符合能量守恒原则。

性能优化‌:

  • 将实时计算转为预计算数据采样,使移动端能以0.5ms完成镜面反射计算,相比实时积分性能提升百倍。

动态适配‌:

  • 通过粗糙度控制mipmap层级选择,实现从镜面到粗糙表面的连续反射效果过渡。

重要发展阶段与优化

‌Unity 5.6(2017)

  • 首次引入分裂求和近似法,采用512x512的立方体贴图存储预滤波环境光,但仅支持静态场景反射。

‌URP 7.x(2020)

  • 引入RGBM编码的HDR环境贴图支持,解决低动态范围贴图的亮度失真问题,预滤波mipmap层级扩展至8级。

‌URP 12.x(2022)

  • 采用多级三线性滤波优化预卷积过程,通过重要性采样将蒙特卡洛积分样本数从1024降至256,烘焙速度提升75%。

‌URP 2025(最新)

  • 新增动态探针混合技术,允许实时更新局部镜面反射,同时引入压缩BRDF LUT(RG16格式),显存占用减少50%。

解决的关键问题与技术选择原因

实时性能瓶颈

  • 传统实时计算Cook-Torrance积分需处理O(n)量级的视角-光线组合,而分裂求和近似将其降为O(1)的贴图采样。Unity选择此方案因其在iPhone 13上可实现0.3ms内的镜面反射计算。

移动端适配

  • 预滤波环境贴图采用ASTC 4x4压缩(单张仅128KB),相比未压缩的立方体贴图(6MB)内存占用减少98%。

物理一致性

  • 通过GGX法线分布与Smith几何函数的精确匹配,确保金属材质在掠射角下的能量守恒,避免传统Phong模型的高光过曝问题。

具体实现示例

预滤波环境贴图生成

c 复制代码
hlsl
// 重要性采样GGX分布
float3 ImportanceSampleGGX(float2 Xi, float3 N, float roughness) {
    float a = roughness * roughness;
    float phi = 2 * PI * Xi.x;
    float cosTheta = sqrt((1 - Xi.y) / (1 + (a*a - 1) * Xi.y));
    float sinTheta = sqrt(1 - cosTheta * cosTheta);
    float3 H = float3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
    return normalize(TangentToWorld(H, N));
}

// 蒙特卡洛积分
for (int i = 0; i < SAMPLE_COUNT; i++) {
    float2 Xi = Hammersley(i, SAMPLE_COUNT);
    float3 H = ImportanceSampleGGX(Xi, N, roughness);
    float3 L = 2 * dot(V, H) * H - V;
    radiance += texCUBElod(envMap, float4(L, mipLevel)).rgb;
}
radiance /= SAMPLE_COUNT;

此代码生成不同粗糙度对应的mipmap层级,粗糙度越高采样的波瓣范围越大。

URP Shader中的镜面IBL应用

c 复制代码
hlsl
// 采样预滤波环境贴图
float mip = roughness * (UNITY_SPECCUBE_LOD_STEPS - 1);
float4 envMap = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectDir, mip);
float3 prefilteredColor = DecodeHDR(envMap, unity_SpecCube0_HDR);

// 采样BRDF LUT
float2 envBRDF = tex2D(_BRDFLUT, float2(NdotV, roughness)).rg;

// 合成镜面反射
float3 specularIBL = prefilteredColor * (F0 * envBRDF.x + envBRDF.y);

其中_BRDFLUT为预计算的BRDF积分贴图,存储菲涅尔系数与偏差项。

技术对比与演进意义

技术方案 计算复杂度 内存占用 适用场景
实时镜面积分 O(n) 0 离线渲染
传统立方体贴图反射 O(1) 6MB+ 静态高光反射
分裂求和镜面IBL O(1) 1.5MB 动态PBR场景
URP 2025优化方案 O(1) 0.8MB 移动端开放世界

该技术的演进使得移动设备能够实现主机级材质表现,如《原神》通过URP镜面IBL在iOS平台实现动态天气系统下的精确环境反射


【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)