作用:
把阴影衰减与阴影遮罩叠加到光线衰减中
光线衰减是什么?
点光源的时候,距离光源越远,光照衰减值越小(0~1), 1表示光照不衰减,0表示全衰减。
直射光则没有所谓的距离衰减,详细解析看下面
https://blog.youkuaiyun.com/zengjunjie59/article/details/109533698
从UNITY_LIGHT_ATTENUATION宏中计算得到的光照衰减值是已与 阴影贴图(动态阴影贴图)采样得到的阴影值 融合后的值
阴影衰减是什么?
实时阴影衰减距离对应设置Edit - Project Setting - Quality - Shadows - Shadow Distance。当片元与摄像机距离超过这个设置的距离的时候,阴影会衰减到看不见。在距离边缘会出现阴影渐变。这个渐变的值就是阴影衰减。范围从0~1,0表示不衰减,1表示阴影全衰减(即没有阴影)
阴影遮罩是什么?
实际上就是静态阴影,灯管开启混合光照的时候才有用, 对应设置Window - Rendering - Lighting - Mixed Lightinig - Lighting Mode - Shadowmask。 开启这个选项之后对光照进行烘焙则会额外烘焙出阴影遮罩贴图。当片元与摄像机距离超过上述的阴影衰减距离后,可以直接对该贴图进行采样得到阴影遮罩值,不需要对阴影进行衰减了,即在很远的地方都能看到阴影。
源码:
// 三个参数解析:
// realtimeShadowAttenuation:从UNITY_LIGHT_ATTENUATION宏中计算得到的光照衰减,已与阴影贴图采样得到的阴影值融合了
// bakedShadowAttenuation: 阴影遮罩值
// fade 阴影距离衰减值
half UnityMixRealtimeAndBakedShadows(half realtimeShadowAttenuation, half bakedShadowAttenuation, half fade)
{
// -- Static objects --
// FWD BASE PASS
// ShadowMask mode = LIGHTMAP_ON + SHADOWS_SHADOWMASK + LIGHTMAP_SHADOW_MIXING
// Distance shadowmask mode = LIGHTMAP_ON + SHADOWS_SHADOWMASK
// Subtractive mode = LIGHTMAP_ON + LIGHTMAP_SHADOW_MIXING
// Pure realtime direct lit = LIGHTMAP_ON
// FWD ADD PASS
// ShadowMask mode = SHADOWS_SHADOWMASK + LIGHTMAP_SHADOW_MIXING
// Distance shadowmask mode = SHADOWS_SHADOWMASK
// Pure realtime direct lit = LIGHTMAP_ON
// DEFERRED LIGHTING PASS
// ShadowMask mode = LIGHTMAP_ON + SHADOWS_SHADOWMASK + LIGHTMAP_SHADOW_MIXING
// Distance shadowmask mode = LIGHTMAP_ON + SHADOWS_SHADOWMASK
// Pure realtime direct lit = LIGHTMAP_ON
// -- Dynamic objects --
// FWD BASE PASS + FWD ADD ASS
// ShadowMask mode = LIGHTMAP_SHADOW_MIXING
// Distance shadowmask mode = N/A
// Subtractive mode = LIGHTMAP_SHADOW_MIXING (only matter for LPPV. Light probes occlusion being done on CPU)
// Pure realtime direct lit = N/A
// DEFERRED LIGHTING PASS
// ShadowMask mode = SHADOWS_SHADOWMASK + LIGHTMAP_SHADOW_MIXING
// Distance shadowmask mode = SHADOWS_SHADOWMASK
// Pure realtime direct lit = N/A
// 判断是否有动态阴影,如果没有,则直接返回烘焙出来的阴影遮罩贴图的值
#if !defined(SHADOWS_DEPTH) && !defined(SHADOWS_SCREEN) && !defined(SHADOWS_CUBE)
#if defined(LIGHTMAP_ON) && defined (LIGHTMAP_SHADOW_MIXING) && !defined (SHADOWS_SHADOWMASK)
//In subtractive mode when there is no shadow we kill the light contribution as direct as been baked in the lightmap.
return 0.0;
#else
return bakedShadowAttenuation; // 直接返回烘焙出来的阴影遮罩贴图的值
#endif
#endif
#if (SHADER_TARGET <= 20) || UNITY_STANDARD_SIMPLE
//no fading nor blending on SM 2.0 because of instruction count limit.
// 判断是否启用了阴影遮罩贴图
#if defined(SHADOWS_SHADOWMASK) || defined(LIGHTMAP_SHADOW_MIXING)
// 从光照衰减与阴影遮罩值中选个最小值返回,即返回一个最暗的
return min(realtimeShadowAttenuation, bakedShadowAttenuation);
#else
return realtimeShadowAttenuation;
#endif
#endif
// 阴影遮罩模式是否是Shadowmask模式,详细解析:https://blog.youkuaiyun.com/zengjunjie59/article/details/113868372
#if defined(LIGHTMAP_SHADOW_MIXING)
// 把阴影距离渐变衰减叠加到光照衰减中,并把范围限制到0~1
// 当阴影距离衰减算出来没有阴影的时候fade是1,有阴影的时候fade是0
// 当片元位于阴影中的时候realtimeShadowAttenuation是0
realtimeShadowAttenuation = saturate(realtimeShadowAttenuation + fade);
// 返回一个最暗的
return min(realtimeShadowAttenuation, bakedShadowAttenuation);
#endif
// 阴影遮罩模式是Distance Shadowmask模式或者没有阴影遮罩(静态阴影)的时候调用以下方法
// 最后返回实时阴影到静态阴影之间的插值,当没有静态阴影的时候bakedShadowAttenuation是1,相当于没阴影
//In distance shadowmask or realtime shadow fadeout we lerp toward the baked shadows (bakedShadowAttenuation will be 1 if no baked shadows)
return lerp(realtimeShadowAttenuation, bakedShadowAttenuation, fade);
}