feat: IBL 阶段③——pre-filtered cubemap + BRDF LUT,split-sum 镜面项接入
- pre-filter:GGX 重要性采样(Hammersley + van der Corput 位反转), 128²×5 mip 分级 roughness,采样数 32<<mip 上限 256;UploadCube 泛化 支持 mip 链([mip: 6面] 紧凑排布逐 mip 逐面拷贝) - BRDF LUT:128² R16G16Sfloat 积分表((NdotV,roughness)→F 缩放/偏置), 纯数学与环境无关,中性兜底同样生成;专用 clamp-to-edge 采样器 (共享 border 白采样器在 uv=1.0 混入白色导致高 roughness 偏大) - shader:specular = prefiltered(R, roughness×4) × (F·A+B), ambient = (diffuse + specular) × ambientColor - Hammersley 分母修正为当次积分采样数(低 mip 偏差 bug) - Debug 构建预积分 26s→14s(采样预算收敛 + pow 改乘法链; env 1024² 重采样为大头,compute 迁移后归零)
This commit is contained in:
@@ -46,6 +46,8 @@ layout(set = 2, binding = 0) uniform sampler2D shadowMap0; // CSM 级联 0(
|
||||
layout(set = 2, binding = 1) uniform sampler2D shadowMap1; // 级联 1
|
||||
layout(set = 2, binding = 2) uniform sampler2D shadowMap2; // 级联 2(最远)
|
||||
layout(set = 2, binding = 3) uniform samplerCube irradianceMap; // 漫反射环境光(IBL 阶段②)
|
||||
layout(set = 2, binding = 4) uniform samplerCube prefilteredMap; // 镜面环境(mip 分 roughness,阶段③)
|
||||
layout(set = 2, binding = 5) uniform sampler2D brdfLut; // BRDF 积分表 (NdotV, roughness) → (scale, bias)
|
||||
|
||||
// 第 0 盏方向光(KeyLight)的 CSM 阴影因子:0.3 影中 / 1.0 受光。
|
||||
// 级联按视图深度选择;采样器均 clamp-to-border 白色:
|
||||
@@ -166,14 +168,25 @@ void main() {
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL * shade;
|
||||
}
|
||||
|
||||
// 环境光:漫反射辐照度(IBL 阶段②,split-sum 的 diffuse 项)。
|
||||
// N 采样预卷积的 irradiance cube(半球 Lambert 积分已在加载期完成);
|
||||
// kD 用粗糙度感知 Fresnel + (1-metallic)(金属无漫反射)。
|
||||
// ambientColor = 用户可调强度/色调乘子。镜面项待阶段③ BRDF LUT
|
||||
// 环境光:IBL split-sum(阶段②③)。
|
||||
// 漫反射:N 采样 irradiance cube(半球 Lambert 预卷积)
|
||||
// 镜面:R 采样 pre-filtered cube(mip = roughness 分级)
|
||||
// × BRDF LUT 查表得 F 缩放/偏置
|
||||
// ambientColor = 用户可调强度/色调乘子
|
||||
vec3 F_amb = FresnelSchlickRoughness(NdotV, F0, roughness);
|
||||
vec3 kD_amb = (1.0 - F_amb) * (1.0 - metallic);
|
||||
|
||||
vec3 irradiance = texture(irradianceMap, N).rgb;
|
||||
vec3 ambient = kD_amb * irradiance * albedo * ubo.ambientColor.rgb;
|
||||
vec3 diffuse = kD_amb * irradiance * albedo;
|
||||
|
||||
vec3 R = reflect(-V, N);
|
||||
const float kMaxPrefilterMip = 4.0; // 与 Cubemap::kPrefilterMips - 1 同步
|
||||
vec3 prefilteredColor = textureLod(prefilteredMap, R,
|
||||
roughness * kMaxPrefilterMip).rgb;
|
||||
vec2 envBRDF = texture(brdfLut, vec2(NdotV, roughness)).rg;
|
||||
vec3 specular = prefilteredColor * (F_amb * envBRDF.x + envBRDF.y);
|
||||
|
||||
vec3 ambient = (diffuse + specular) * ubo.ambientColor.rgb;
|
||||
|
||||
vec3 color = ambient + Lo + emissive;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user