BlueRoseNote/03-UnrealEngine/Rendering/RenderingPipeline/Lighting/Lighting阶段的ShadowMap逻辑.md
2023-06-29 11:55:02 +08:00

2.8 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
Lighting阶段的ShadowMap逻辑 2023-04-10 14:45:45

PS Parameter

FDeferredLightPS::FParameters GetDeferredLightPSParameters()

  • LightAttenuationTexture = ShadowMaskTexture ? ShadowMaskTexture : WhiteDummy;
  • One pass projection
    • VirtualShadowMap = VirtualShadowMapUniformBuffer;
    • VirtualShadowMapId = VirtualShadowMapId;
    • ShadowMaskBits = ShadowMaskBits ? ShadowMaskBits : GSystemTextures.GetZeroUIntDummy(GraphBuilder);

最后输出

  • SceneColorTexture
  • SceneDepthTexture

Lighting阶段中VSM 渲染函数

RenderDeferredShadowProjections(),输出ScreenShadowMaskTexture

问题所在

LightAttenuation

  • x整个场景的方向光阴影。
  • y整个场景的方向光SSS阴影。
  • zLight function + per-object shadows
  • wper-object SSS shadowing in w

zw用于非方向光或者移动端渲染路径。

if (LightData.bRadialLight || SHADING_PATH_MOBILE)  
{  
   // Remapping the light attenuation buffer (see ShadowRendering.cpp)  
  
   Shadow.SurfaceShadow = LightAttenuation.z * StaticShadowing;  
   // SSS uses a separate shadowing term that allows light to penetrate the surface  
   //@todo - how to do static shadowing of SSS correctly?   Shadow.TransmissionShadow = LightAttenuation.w * StaticShadowing;  
  
   Shadow.TransmissionThickness = LightAttenuation.w;  
}  
else  
{  
   // Remapping the light attenuation buffer (see ShadowRendering.cpp)  
   // Also fix up the fade between dynamic and static shadows   // to work with plane splits rather than spheres.  
   float DynamicShadowFraction = DistanceFromCameraFade(SceneDepth, LightData);  
   // For a directional light, fade between static shadowing and the whole scene dynamic shadowing based on distance + per object shadows  
   Shadow.SurfaceShadow = lerp(LightAttenuation.x, StaticShadowing, DynamicShadowFraction);  
   // Fade between SSS dynamic shadowing and static shadowing based on distance  
   Shadow.TransmissionShadow = min(lerp(LightAttenuation.y, StaticShadowing, DynamicShadowFraction), LightAttenuation.w);  
  
   Shadow.SurfaceShadow *= LightAttenuation.z;  
   Shadow.TransmissionShadow *= LightAttenuation.z;  
  
   // Need this min or backscattering will leak when in shadow which cast by non perobject shadow(Only for directional light)  
   Shadow.TransmissionThickness = min(LightAttenuation.y, LightAttenuation.w);  
}

DeferredLightingCommon.ushDeferredLightPixelShaders.usf中的LightAttenuation即为ShadowMap数据。具体可以参考GetLightAttenuationFromShadow()可以看得出EPIC之后打算通过抖动来消除VSM的阴影锯齿。

主要的阴影效果由LightAttenuation与ShadingModels.ush中的NoL提供。我们只需要调整自阴影也就是z通道其他的整个场景的阴影。