坐褐 发表于 昨天 18:35

【光照】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模型的高光过曝问题。
具体实现示例

预滤波环境贴图生成

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应用

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+静态高光反射分裂求和镜面IBLO(1)1.5MB动态PBR场景URP 2025优化方案O(1)0.8MB移动端开放世界该技术的演进使得移动设备能够实现主机级材质表现,如《原神》通过URP镜面IBL在iOS平台实现动态天气系统下的精确环境反射
<blockquote>
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 【光照】Unity[PBR]环境光中的[镜面IBL]