Unity阴影优化实战:PCF与PCSS技术详解与参数调优 1. 项目概述阴影问题的根源与解决思路在Unity里做项目尤其是涉及到室内场景或者需要强烈光影氛围的时候阴影锯齿和漏光这两个问题几乎是每个开发者都会遇到的“拦路虎”。你精心搭建的场景可能因为阴影边缘那刺眼的“狗牙”而显得粗糙也可能因为墙角、物体接缝处莫名其妙透出的“光斑”而破坏整体的沉浸感。这不仅仅是美观问题更直接关系到项目的视觉品质和玩家的体验。我自己在项目里就踩过不少坑。比如一个看似简单的Directional Light平行光阴影调高了分辨率锯齿依然明显又或者使用了Spot Light聚光灯或Point Light点光源后物体靠近光源的部分阴影会莫名其妙地消失形成难看的漏光。这些问题单纯靠拉高Unity质量设置里的“Shadow Resolution”往往治标不治本还会带来巨大的性能开销。其实这些问题的核心大多出在阴影的采样和过滤算法上。Unity内置的阴影系统特别是URP通用渲染管线和HDRP高清渲染管线已经为我们封装好了强大的工具但需要我们理解其背后的原理——也就是PCFPercentage-Closer Filtering百分比渐近过滤和PCSSPercentage-Closer Soft Shadows百分比渐近软阴影技术。标题里提到的“调参数”绝不是漫无目的地滑动滑块而是基于对这两种技术工作原理的深刻理解进行有的放矢的优化。这篇文章我就以一个实战者的角度带你彻底搞懂Unity中阴影锯齿和漏光的成因并手把手教你如何通过调整PCF与PCSS的相关参数来解决它们。我会提供完整的、可即插即用的Shader代码片段并解释每一行代码的作用让你不仅能“抄作业”更能明白为什么要这么写。无论你使用的是URP还是内置的Built-in管线核心思路都是相通的。2. 阴影锯齿与漏光现象、成因与基础诊断在动手调参之前我们必须先当个好“医生”准确诊断出症状的根源。阴影锯齿和漏光虽然经常同时出现但它们的成因和解决方案侧重点不同。2.1 阴影锯齿为什么边缘像锯子现象阴影的边缘特别是斜向的边缘呈现出明显的、阶梯状的像素块看起来非常粗糙专业术语常称之为“Aliasing”走样。核心成因根本原因在于阴影贴图Shadow Map的分辨率有限。你可以把阴影贴图想象成一张从光源视角“拍摄”的场景深度照片。渲染阴影时我们需要比较当前像素点到光源的距离与阴影贴图中记录的距离。由于贴图像素是离散的一个屏幕像素可能对应阴影贴图上的多个纹素Texel或者反过来。当阴影边缘恰好落在这些离散的纹素边界时就会产生非0即1的二值化判断从而形成锯齿。Unity中的表现与基础排查检查阴影贴图分辨率这是第一步。在Project Settings - Quality中找到Shadows下的Shadow Resolution。Low/Medium/High/Very High分别对应不同的分辨率。如果你的场景很大或者相机可以拉得很近观察阴影细节Low或Medium是绝对不够的。观察锯齿模式静态锯齿不随相机移动而闪烁通常就是分辨率不足。动态锯齿随相机移动而闪烁则可能还涉及到阴影贴图的滤波方式这就是PCF要解决的问题。注意盲目将分辨率调到Very High会显著增加GPU内存和带宽消耗可能带来性能瓶颈。我们需要更聪明的方法——PCF。2.2 阴影漏光Light Bleeding/Shadow Acne为什么阴影会“破洞”现象在物体表面本该被阴影完全覆盖的区域出现了不应该有的光亮条纹或斑点或者两个紧密接触的物体如墙与地板之间阴影无法正确连接出现缝隙透光。核心成因这个问题比锯齿更复杂通常是多个因素共同作用深度偏移Depth Bias问题这是最常见的原因。由于数值精度限制在比较深度时物体自身的像素深度值可能和阴影贴图中记录的深度值非常接近。由于浮点数精度误差可能导致本该被判定为“在阴影中”的像素被错误判定为“不在阴影中”从而漏光。这种现象也叫“Shadow Acne”阴影痤疮。阴影贴图采样与滤波当使用PCF等滤波技术时采样会取周围多个纹素的深度做平均。如果滤波范围核大小设置不当可能会采样到来自背景或其他物体的错误深度值导致阴影边缘出现不正确的半影Penumbra或漏光。光源范围与衰减特别是对于聚光灯和点光源如果物体的某些部分非常靠近光源甚至在光源的“体内”这些部分的深度比较会变得极不稳定容易产生漏光。几何体接缝两个网格的接缝处由于法线或渲染精度问题可能产生微小的间隙导致光线“泄漏”。Unity中的基础排查调整Depth Bias在光源组件如Directional Light的Shadow设置中找到Bias参数。尝试逐步增大这个值例如从0.05调到0.10.2。注意调得太大又会导致“Peter Panning”现象即阴影看起来与物体本体分离。检查Normal Bias同样在光源阴影设置中。这个参数会让阴影贴图在生成时沿着顶点法线方向做一个微小的偏移有助于解决由于曲面细分不足导致的表面自阴影错误。适当增加如从0.4调到1.0有时能改善漏光。诊断清楚后我们就进入核心环节利用PCF和PCSS这两种滤波技术从根源上优化阴影质量。3. PCF百分比渐近过滤原理与参数精调PCF不是一种消除锯齿的魔法而是一种“伪装”锯齿的技术。它的核心思想非常巧妙不再进行单次非黑即白的深度比较而是在当前像素周围的一个小区域内进行多次采样和比较最后将比较结果“在阴影中”的比例进行平均作为该像素最终的阴影强度。这样阴影的边缘就从0到1的硬边界变成了一个从0%到100%的灰度过渡带视觉上就是柔和的软阴影边缘锯齿感自然被大大削弱。3.1 PCF算法核心步骤拆解假设我们有一个3x3的PCF采样核对于当前屏幕像素点P确定其在阴影贴图纹理空间中的坐标。以该坐标为中心在一个预定义的范围内例如上下左右各偏移1个纹素生成多个采样点如9个点。对每一个采样点执行传统的深度比较如果像素深度 阴影贴图深度则在阴影中结果为1否则不在结果为0。将所有采样点的比较结果一堆0或1取平均值。这个平均值比如0.7就是像素P的阴影强度。0.7意味着70%的采样点认为它在阴影中所以它最终的颜色是物体本色 * (1 - 0.7 * 阴影强度)。3.2 Unity中控制PCF的关键参数在Unity URP/HDRP中PCF的配置通常不直接暴露为“PCF Size”而是通过其他参数影响滤波范围和方式。1. 光源上的Soft Shadows与Shadow StrengthSoft Shadows启用它Unity就会对这条光源的阴影应用PCF滤波。关闭则是硬阴影。Shadow Strength控制阴影的黑暗程度。在PCF下它乘以上述计算出的阴影强度平均值。调低此值可以轻微缓解因PCF采样不当导致的边缘半影过亮问题但本质是全局变暗。2. URP Asset / 质量设置中的关键参数这是调节PCF效果的主战场。在URP Asset或Quality设置中指定的URP Asset里找到Shadows分段。Filtering这是最重要的PCF模式选择器。No Filtering无滤波硬阴影锯齿严重。PCF 2x2,PCF 3x3,PCF 5x5,PCF 7x7数字代表采样核的大小。核越大阴影边缘越柔和锯齿消除效果越好但性能开销也呈平方增长。PCF 3x3是效果和性能的一个良好平衡点PCF 5x5能获得非常柔和的边缘。Max Distance阴影最大渲染距离。超过此距离的物体不投射阴影。合理设置此值避免为远处微小物体浪费阴影贴图分辨率间接提升近处阴影质量。Cascade Count与Split级联阴影CSM相关。对于平行光将一张大阴影贴图分割成多个级联近处分辨率高远处分辨率低能极大改善远近阴影质量不一的问题。增加Cascade Count如从1到4并合理调整Split比例是解决场景中远处阴影锯齿的最有效手段之一。3. Shader中的自定义PCF实现有时内置的PCF模式仍不能满足需求或者你想获得更精确的控制比如不同的采样模式就需要在Shader中手写PCF。下面是一个经典的3x3泊松圆盘采样Poisson Disk Sampling的PCF函数它能比均匀网格采样获得更自然的噪声分布。// 定义一个泊松圆盘采样数组12个采样点 static const float2 PoissonDisk[12] { float2(-0.326212, -0.40581), float2(-0.840144, -0.07358), float2(-0.695914, 0.457137), float2(-0.203345, 0.620716), float2(0.96234, -0.194983), float2(0.473434, -0.480026), float2(0.519456, 0.767022), float2(0.185461, -0.893124), float2(0.507431, 0.064425), float2(0.89642, 0.412458), float2(-0.32194, -0.932615), float2(-0.791559, -0.59771) }; float SampleShadowMap_PCF3x3(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, float2 texelSize) { float shadow 0.0; float2 uv shadowCoord.xy; // 根据阴影贴图像素大小确定采样偏移范围 float2 offset texelSize * 1.5; // 1.5倍纹素大小的采样半径 // 循环12个泊松采样点 for (int i 0; i 12; i) { float2 sampleUV uv PoissonDisk[i] * offset; // 使用SAMPLE_TEXTURE2D_SHADOW宏进行深度比较采样 shadow SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(sampleUV, shadowCoord.z)).r; } // 返回平均阴影强度 return shadow / 12.0; }实操要点texelSize需要传入阴影贴图的大小1.0 / shadowMapResolution。泊松采样虽然效果自然但采样点随机可能带来噪声。可以通过旋转采样盘、或者结合分层采样来改善。在Shader中调用此函数替代简单的SampleShadowmap你就能获得一个自定义的、更柔和的PCF阴影。注意事项PCF极大地改善了边缘锯齿但它本质上是用“模糊”来换取平滑。如果阴影贴图分辨率本身极低PCF只会将锯齿模糊成一团难看的灰色过渡并不会增加细节。因此PCF必须与足够高的阴影贴图分辨率结合使用。4. PCSS百分比渐近软阴影原理与实战配置PCF解决了边缘锯齿但它产生的软阴影是“均匀”的软即阴影边缘的模糊程度半影宽度是固定的。在现实世界中阴影的软硬取决于光源大小和遮挡物与接收面之间的距离遮挡物离接收面越远阴影越软半影越宽光源越大阴影也越软。PCSSPercentage-Closer Soft Shadows正是为了模拟这种物理正确的软阴影现象而设计的。它比PCF更进了一步能动态地根据遮挡关系计算每个像素点应有的半影大小。4.1 PCSS算法三步走PCSS算法的实现可以分为三个核心步骤遮挡物深度搜索Blocker Search在当前像素对应的阴影贴图位置在一个初始搜索范围内例如5x5的纹素区域进行多次深度采样。将所有采样到的深度值与当前像素的深度接收面深度进行比较。统计那些比当前像素深度更浅即更靠近光源属于“遮挡物”的采样点并计算这些“遮挡物”的平均深度。半影宽度计算Penumbra Estimation这是一个简单的几何比例计算。公式通常为半影宽度 (当前像素深度 - 遮挡物平均深度) / 遮挡物平均深度 * 光源尺寸。(当前像素深度 - 遮挡物平均深度)体现了遮挡物与接收面的距离差距离越大阴影越软。光源尺寸是一个可调的艺术性参数模拟物理光源的大小。值越大阴影整体越软。自适应PCF滤波Percentage-Closer Filtering使用上一步计算出的半影宽度作为PCF采样的滤波核大小。这意味着在阴影内部远离边缘和阴影外部滤波核很小或为0阴影较硬在阴影边缘过渡区滤波核根据半影宽度动态变大进行更多次采样产生柔和的渐变。这一步通常就调用我们上面写的SampleShadowMap_PCF函数但传入的offset采样范围是动态计算的半影宽度。4.2 在Unity中实现与调节PCSSUnity的URP和HDRP内置管线目前没有直接提供官方的PCSS实现作为一个可开关的选项。因此要实现PCSS我们需要编写自定义的Shader或后处理效果。下面提供一个简化版的PCSS核心函数思路并说明关键调节参数。float SampleShadowMap_PCSS(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, float2 texelSize, float lightSizeUV, float searchRadius) { // 步骤1遮挡物搜索 float blockerDepthSum 0.0; float numBlockers 0.0; float receiverDepth shadowCoord.z; // 当前接收面深度 for (int i 0; i BLOCKER_SEARCH_SAMPLES; i) { float2 sampleUV shadowCoord.xy PoissonDisk[i] * texelSize * searchRadius; float occluderDepth SAMPLE_TEXTURE2D(ShadowMap, sampler_ShadowMap, sampleUV).r; // 注意这里是采样深度不是比较 if (occluderDepth receiverDepth) { // 如果采样点深度比接收面浅说明是遮挡物 blockerDepthSum occluderDepth; numBlockers 1.0; } } float avgBlockerDepth (numBlockers 0.0) ? (blockerDepthSum / numBlockers) : 0.0; // 如果没有找到遮挡物直接返回无阴影1.0或进行硬阴影比较 if (numBlockers 0.0) { return SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(shadowCoord.xy, receiverDepth)).r; } // 步骤2计算半影宽度 float penumbraWidth (receiverDepth - avgBlockerDepth) / avgBlockerDepth * lightSizeUV; // 步骤3使用动态半影宽度进行PCF滤波 float shadow 0.0; for (int j 0; j PCF_SAMPLES; j) { float2 sampleUV shadowCoord.xy PoissonDisk[j] * texelSize * penumbraWidth; shadow SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(sampleUV, receiverDepth)).r; } return shadow / float(PCF_SAMPLES); }关键调节参数解析lightSizeUV光源尺寸这是什么一个艺术导向的参数并非真实的物理光源大小。它直接乘在半影宽度计算公式中。如何调节这是控制阴影“软硬度”的最主要参数。值越大计算出的半影宽度越大阴影边缘越柔和、模糊。通常需要根据场景尺度来调整。一个室内桌面场景可能用0.05而一个户外建筑场景可能需要0.5甚至更大。调试技巧在Shader中将其暴露为材质属性或全局变量在编辑器里实时调节观察阴影边缘的变化。searchRadius遮挡物搜索半径这是什么在第一步“遮挡物深度搜索”时采样点分布的半径以纹素为单位。如何调节影响算法寻找遮挡物的范围。过小可能导致找不到足够的遮挡物使半影计算不稳定尤其在尖锐边缘。过大则会采样到不相关的深度信息导致半影计算错误并增加性能开销。通常设置为3.0到10.0之间是一个不错的起点。注意事项这个参数对性能影响敏感因为它直接增加了第一阶段的采样次数。BLOCKER_SEARCH_SAMPLES和PCF_SAMPLES采样数这是什么分别是遮挡物搜索阶段和最终PCF滤波阶段的采样点数。如何调节直接影响效果质量和性能。更多的采样数带来更平滑、更准确的结果但代价是更高的GPU负载。通常BLOCKER_SEARCH_SAMPLES可以略少于PCF_SAMPLES例如用8次搜索和16次滤波。可以通过降低采样数来优化性能但可能会引入噪声。性能与质量平衡心法 PCSS是一种相对昂贵的阴影技术因为它每个像素至少要进行搜索采样数 滤波采样数次纹理采样。在移动平台或低端GPU上需谨慎使用。一个常见的优化策略是降低分辨率渲染将PCSS阴影计算在Half/Quarter分辨率的缓冲区中进行然后再与主画面合并可以大幅提升性能虽然会损失一些锐度。分层级优化对远处或次要物体使用简单的PCF甚至硬阴影只对近处主角或关键物体使用PCSS。5. 综合调优实战从参数到Shader的完整解决方案理解了PCF和PCSS的原理后我们现在将它们整合起来形成一个从项目设置到Shader代码的完整解决方案。我会按照从宏观到微观的顺序给你一个清晰的调优路线图。5.1 第一步项目级与光源基础设置在动Shader之前先把Unity能提供的基础设置做到位。选择正确的渲染管线与质量等级明确使用URP还是Built-in。URP在阴影设置上更模块化。在Project Settings - Quality中为不同平台PC、移动端设置不同的质量等级并在对应等级下指定URP Asset。配置URP Asset中的阴影全局参数Max Distance设置为你的相机最远可见距离的70%-80%。确保阴影不会浪费在看不见的地方。Cascade Count对于开放大世界平行光务必使用4级级联。对于小场景或室内2级可能足够。在Shadow Cascades选项中可视化调整Split确保每一级覆盖的范围合理近处级联足够密集。Filtering作为保底选择设置为PCF 3x3或PCF 5x5。即使你后面用自定义Shader这个设置也影响一些内置渲染器的物体。调节每个关键光源的阴影参数选中场景中的主光源通常是Directional Light。Bias从0.05开始尝试。如果看到漏光Shadow Acne以0.01为步长递增。如果看到阴影与物体分离Peter Panning则减小。这是一个需要反复微调的参数。Normal Bias对于复杂曲面模型可以增加到1.0到2.0来减少曲面上的自阴影错误。对于平整表面保持较低值如0.5。Soft Shadows确保勾选。5.2 第二步编写集成PCF/PCSS的自定义阴影采样Shader我们将创建一个自定义的URP Lit Shader用其替换场景中重要材质的标准Shader以应用我们更高级的阴影。1. 创建Shader与属性块Shader Custom/CustomShadowLit { Properties { _BaseColor(Base Color, Color) (1,1,1,1) _BaseMap(Base Map, 2D) white {} // PCSS专用参数 _LightSize(Light Size (PCSS), Range(0.001, 0.5)) 0.05 _SearchRadius(Search Radius (PCSS), Range(1.0, 15.0)) 5.0 // 阴影色调调节 _ShadowColor(Shadow Color, Color) (0,0,0,1) _ShadowStrength(Shadow Strength, Range(0, 1)) 1.0 } SubShader { Tags { RenderTypeOpaque RenderPipelineUniversalPipeline } ... // Pass等常规结构 } }2. 在HLSLINCLUDE中定义我们的采样函数 将前面章节的SampleShadowMap_PCF3x3和SampleShadowMap_PCSS函数代码放入一个通用的HLSL文件如CustomShadowSampling.hlsl中并在Shader中#include它。3. 在片元着色器中替换默认阴影采样 找到URP Lit Shader中计算阴影的关键部分通常是调用MainLightRealtimeShadow函数或直接采样SHADOWMAP的地方将其替换为我们自己的函数。// 原有的简单采样可能长这样 // half shadow MainLightRealtimeShadow(input.shadowCoord, input.positionWS); // 替换为我们的PCF采样 float2 texelSize _ShadowMapTexture_TexelSize.xy; // 需要声明并传递这个变量 half shadow SampleShadowMap_PCF3x3(TEXTURE2D_ARGS(_ShadowMapTexture, sampler_ShadowMapTexture), input.shadowCoord, texelSize); // 或者替换为更高级的PCSS采样 half shadow SampleShadowMap_PCSS(TEXTURE2D_ARGS(_ShadowMapTexture, sampler_ShadowMapTexture), input.shadowCoord, texelSize, _LightSize, _SearchRadius); // 最后应用阴影强度和颜色 shadow lerp(1.0, shadow, _ShadowStrength); float3 shadowedColor lerp(_ShadowColor.rgb, baseColor.rgb, shadow);4. 处理多个光源 对于额外的逐像素光点光源、聚光灯URP通常在一个单独的AdditionalLights循环中处理阴影。你需要找到对应的阴影坐标和纹理并应用相同的采样函数替换。5.3 第三步针对特定场景的微调策略不同的场景类型参数倾向完全不同。室内小场景特点相机距离近物体细节丰富阴影需要清晰。策略使用较高的阴影贴图分辨率如2048Filtering用PCF 3x3。PCSS的_LightSize可以较小0.02-0.05模拟小窗户或射灯的效果。重点调整Bias解决墙角漏光。技巧对于静态家具考虑使用烘焙光照Baked Global Illumination的阴影质量完美且无性能消耗。户外大世界特点视野辽阔近景远景兼顾平行光为主。策略级联阴影CSM是重中之重。使用4级级联仔细调整每一级的Split距离和Resolution。远景可以使用较低的PCF采样如2x2或甚至关闭软阴影来节省性能。PCSS的_LightSize可以调大0.1-0.3模拟太阳面光源产生的柔和阴影。技巧利用Shadow Distance Fade功能让阴影在最大距离处逐渐淡出避免突兀的消失。移动端/性能敏感项目特点GPU算力有限必须精打细算。策略降低主阴影贴图分辨率1024甚至512。使用PCF 2x2或硬阴影。谨慎使用PCSS如果必须用大幅减少采样数如搜索4次滤波8次。考虑使用Screen Space Shadows技术作为补充它利用深度缓冲在屏幕空间生成接触硬化阴影性价比很高。技巧对动态物体和静态物体使用不同的阴影设置。动态物体用低分辨率实时阴影静态物体用烘焙阴影或Lightmap。6. 常见问题排查与性能优化指南即使按照上述步骤操作在实际项目中你还是会遇到各种奇怪的问题。这里我整理了一份“阴影问题排查清单”和性能优化技巧。6.1 问题排查速查表问题现象可能原因排查步骤与解决方案阴影边缘有严重锯齿1. 阴影贴图分辨率过低。2. 未开启软阴影PCF。3. 级联阴影分割不当当前级联覆盖范围过大。1. 调高Shadow Resolution。2. 确保光源和URP Asset中启用了Soft Shadows和Filtering。3. 可视化Shadow Cascades调整Split值确保近处级联足够密集。阴影内部有闪烁或条纹漏光1.Depth Bias过低。2.Normal Bias不适用于当前几何体。3. 使用PCSS时searchRadius过大或采样数不足导致噪声。1. 逐步增加光源的Bias值。2. 对于平整表面尝试降低Normal Bias。3. 减小PCSS的searchRadius或增加BLOCKER_SEARCH_SAMPLES。阴影与物体明显分离漂浮Depth Bias或Normal Bias值过高。逐步减小光源的Bias和Normal Bias值直到阴影贴合物体。PCSS阴影边缘噪声大1. PCF采样数PCF_SAMPLES不足。2. 泊松采样盘噪声明显。1. 增加PCF_SAMPLES性能代价高。2. 改用旋转的泊松盘或蓝噪声Blue Noise采样序列可以在相同采样数下获得更均匀的分布。阴影在特定角度或距离突然消失/出现1. 阴影最大距离Max Distance设置过小。2. 级联过渡Cascade Blending区域设置不当或未启用。3. 阴影裁剪面Light Near/Far Plane设置不合理。1. 检查并增大URP Asset中的Max Distance。2. 启用Cascade Blending并调整过渡距离。3. 检查平行光的Near/Far平面确保覆盖整个需要阴影的视锥体。性能开销巨大1. 阴影分辨率过高。2. PCF/PCSS采样数过多。3. 级联数量过多或范围过大。4. 过多动态物体投射阴影。1. 分级设置近景用高分辨率远景用低分辨率。2. 降低采样数或改用更高效的滤波算法如VSM。3. 减少级联数或使用Stable Fit模式替代Close Fit。4. 使用阴影投射器剔除Culling Mask只为重要物体投射实时阴影。6.2 高级优化技巧实录1. 阴影图集Shadow Atlas与分辨率分配 Unity的实时阴影通常渲染到一张或几张“图集”纹理上。你可以通过脚本监控Shader.globalMaximumChunkSize或使用Frame Debugger工具查看阴影图集的利用率。如果图集空余很多可以尝试为不同的灯光分配不同的分辨率而不是全局提高。2. 接触硬化阴影Contact Hardening Shadows技巧 这是PCSS的自然结果但我们可以强化它。在PCSS的半影宽度计算中可以加入一个非线性函数来调整使得距离遮挡物非常近的接收面阴影更硬距离远的更软。例如将计算公式修改为penumbraWidth pow((receiverDepth - avgBlockerDepth) / avgBlockerDepth, 0.5) * lightSizeUV。这里的0.5次方就是一个压缩函数让近处的变化更敏感。3. 使用VSMVariance Shadow Maps作为备选方案 如果你受够了PCSS的性能开销和调参复杂度VSM是另一个强大的软阴影算法。它通过存储深度的均值和方差来快速计算阴影概率能产生非常平滑的软阴影且性能相对固定对滤波核大小不敏感。URP目前不直接支持但可以自己实现。但VSM有其致命缺点对深度偏移Bias极其敏感且容易在深度不连续处产生“光渗”现象需要配合Light Bleeding Reduction技巧使用。调阴影是一个视觉导向为主技术限制为辅的过程。没有一套放之四海而皆准的参数。最好的方法就是像我这样建立一个包含自定义PCSS Shader的测试场景里面摆放各种典型的几何体立方体、球体、复杂模型、阶梯然后一边调节_LightSize、_SearchRadius、Bias这些参数一边在Game视图里实时观察变化。记住你的目标是让阴影“看起来正确”而不是追求数学上的绝对物理精确。当你看到锯齿平滑消失漏光被巧妙掩盖阴影柔和地贴合在物体周围时那种成就感就是对我们这些图形程序员最好的奖励。