From d3c3d0cdd99cc674bfa8e7c5a7fd76d10209448d Mon Sep 17 00:00:00 2001 From: atdunbg Date: Thu, 24 Sep 2026 12:10:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BD=B1=E5=AD=90=E4=B8=AD=E9=95=9C?= =?UTF-8?q?=E9=9D=A2=E9=AB=98=E5=85=89=E6=AE=8B=E7=95=99=E5=AF=BC=E8=87=B4?= =?UTF-8?q?"=E5=BD=B1=E5=AD=90=E6=AF=94=E5=A4=A9=E7=A9=BA=E4=BA=AE"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 掠射角下 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 单面朝上不受影响) --- Engine/src/Renderer/Passes/ShadowPass.cpp | 5 ++++- shaders/simple_shader.frag | 12 ++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Engine/src/Renderer/Passes/ShadowPass.cpp b/Engine/src/Renderer/Passes/ShadowPass.cpp index 2e22030..75d5758 100644 --- a/Engine/src/Renderer/Passes/ShadowPass.cpp +++ b/Engine/src/Renderer/Passes/ShadowPass.cpp @@ -55,7 +55,10 @@ namespace Engine::Passes cmd.setDepthBiasEnable(VK_TRUE); cmd.setDepthBias(0.006f, 0.0f, 0.006f); cmd.setPolygonModeEXT(vk::PolygonMode::eFill); - cmd.setCullMode(vk::CullModeFlagBits::eNone); + // 正面剔除渲染阴影图:封闭网格只写背面深度,正面深度比 + // ref 恒大一个表面厚度 → 从根上消除自阴影 acne,bias 只需 + // 兜底数值噪声。代价:单面薄片在光背面时会漏写(可接受) + cmd.setCullMode(vk::CullModeFlagBits::eFront); cmd.setFrontFace(vk::FrontFace::eCounterClockwise); cmd.setPrimitiveTopology(vk::PrimitiveTopology::eTriangleList); cmd.setPrimitiveRestartEnable(VK_FALSE); diff --git a/shaders/simple_shader.frag b/shaders/simple_shader.frag index 61911d6..72c4151 100644 --- a/shaders/simple_shader.frag +++ b/shaders/simple_shader.frag @@ -142,6 +142,7 @@ void main() { vec3 F0 = mix(vec3(0.04), albedo, metallic); // 电介质基准反射率 4% vec3 Lo = vec3(0.0); + float shade0 = 1.0f; // 【诊断】阴影系数可视化用 for (int i = 0; i < MAX_LIGHTS; ++i) { // 按类型分支:方向光无衰减;点光方向指向光源 + 平方距离衰减 @@ -180,8 +181,14 @@ void main() { // 阴影只来自第 0 盏方向光(CSM) float shade = (i == 0 && ubo.lights[0].params.x < 0.5) ? 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(阶段②③)。 @@ -203,7 +210,8 @@ void main() { 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 ambient = (diffuse + specular) * ubo.ambientColor.rgb + * mix(0.4, 1.0, shade0); // 阴影区环境同步衰减(简化遮蔽) vec3 color = ambient + Lo + emissive;