fix: 影子中镜面高光残留导致"影子比天空亮"
掠射角下 GGX spec 分母 (4·NdotV·NdotL) 变小,HDR 值可达 8+; 阴影只把它乘 0.3,30% 的刺眼白仍比天空亮——观感即"影子发白"。 - spec 项按 shade 重映射(0.3→0,1.0→1):光源被遮挡,其镜面像 应完全消失;diffuse 保留 0.3 作间接近似 - ShadowPass 改正面剔除渲阴影图(标准 acne 治法):封闭网格只写 背面深度,正面深度天然比 ref 大一个表面厚度,从根上消自阴影 acne;代价是单面薄片在光背面时漏写(plane 单面朝上不受影响)
This commit is contained in:
@@ -55,7 +55,10 @@ namespace Engine::Passes
|
|||||||
cmd.setDepthBiasEnable(VK_TRUE);
|
cmd.setDepthBiasEnable(VK_TRUE);
|
||||||
cmd.setDepthBias(0.006f, 0.0f, 0.006f);
|
cmd.setDepthBias(0.006f, 0.0f, 0.006f);
|
||||||
cmd.setPolygonModeEXT(vk::PolygonMode::eFill);
|
cmd.setPolygonModeEXT(vk::PolygonMode::eFill);
|
||||||
cmd.setCullMode(vk::CullModeFlagBits::eNone);
|
// 正面剔除渲染阴影图:封闭网格只写背面深度,正面深度比
|
||||||
|
// ref 恒大一个表面厚度 → 从根上消除自阴影 acne,bias 只需
|
||||||
|
// 兜底数值噪声。代价:单面薄片在光背面时会漏写(可接受)
|
||||||
|
cmd.setCullMode(vk::CullModeFlagBits::eFront);
|
||||||
cmd.setFrontFace(vk::FrontFace::eCounterClockwise);
|
cmd.setFrontFace(vk::FrontFace::eCounterClockwise);
|
||||||
cmd.setPrimitiveTopology(vk::PrimitiveTopology::eTriangleList);
|
cmd.setPrimitiveTopology(vk::PrimitiveTopology::eTriangleList);
|
||||||
cmd.setPrimitiveRestartEnable(VK_FALSE);
|
cmd.setPrimitiveRestartEnable(VK_FALSE);
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ void main() {
|
|||||||
vec3 F0 = mix(vec3(0.04), albedo, metallic); // 电介质基准反射率 4%
|
vec3 F0 = mix(vec3(0.04), albedo, metallic); // 电介质基准反射率 4%
|
||||||
|
|
||||||
vec3 Lo = vec3(0.0);
|
vec3 Lo = vec3(0.0);
|
||||||
|
float shade0 = 1.0f; // 【诊断】阴影系数可视化用
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; ++i) {
|
for (int i = 0; i < MAX_LIGHTS; ++i) {
|
||||||
// 按类型分支:方向光无衰减;点光方向指向光源 + 平方距离衰减
|
// 按类型分支:方向光无衰减;点光方向指向光源 + 平方距离衰减
|
||||||
@@ -180,8 +181,14 @@ void main() {
|
|||||||
// 阴影只来自第 0 盏方向光(CSM)
|
// 阴影只来自第 0 盏方向光(CSM)
|
||||||
float shade = (i == 0 && ubo.lights[0].params.x < 0.5)
|
float shade = (i == 0 && ubo.lights[0].params.x < 0.5)
|
||||||
? ShadowFactor(N, fragViewDepth) : 1.0;
|
? ShadowFactor(N, fragViewDepth) : 1.0;
|
||||||
|
if (i == 0) shade0 = shade;
|
||||||
|
|
||||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL * shade;
|
// 漫反射影中保留 0.3(间接光近似);镜面项是"光源的镜面像",
|
||||||
|
// 光源被遮挡即完全消失——按 shade 重映射(0.3→0,1.0→1)。
|
||||||
|
// 否则掠射角下 spec(HDR 8)×0.3 仍是白块,影子比天空还亮
|
||||||
|
float shadeSpec = max((shade - 0.3f) / 0.7f, 0.0f);
|
||||||
|
Lo += (kD * albedo / PI) * radiance * NdotL * shade
|
||||||
|
+ specular * radiance * NdotL * shadeSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 环境光:IBL split-sum(阶段②③)。
|
// 环境光:IBL split-sum(阶段②③)。
|
||||||
@@ -203,7 +210,8 @@ void main() {
|
|||||||
vec2 envBRDF = texture(brdfLut, vec2(NdotV, roughness)).rg;
|
vec2 envBRDF = texture(brdfLut, vec2(NdotV, roughness)).rg;
|
||||||
vec3 specular = prefilteredColor * (F_amb * envBRDF.x + envBRDF.y);
|
vec3 specular = prefilteredColor * (F_amb * envBRDF.x + envBRDF.y);
|
||||||
|
|
||||||
vec3 ambient = (diffuse + specular) * ubo.ambientColor.rgb;
|
vec3 ambient = (diffuse + specular) * ubo.ambientColor.rgb
|
||||||
|
* mix(0.4, 1.0, shade0); // 阴影区环境同步衰减(简化遮蔽)
|
||||||
|
|
||||||
vec3 color = ambient + Lo + emissive;
|
vec3 color = ambient + Lo + emissive;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user