Movable Objects Not Receiving Shadows From Stationary Light

I am having a really tough time figuring this out. For some reason my stationary spotlight is not casting a shadow onto a movable object. The movable object is properly casting a dynamic shadow, but it is not receiving the shadowing from the static environment. I have included an image. I have tried changing all kinds of settings on the stationary light, I have tried adjusting the bounds on both the movable object and the static object that is casting the shadow. Nothing makes the light properly cast shadows from static geo onto moving objects (the same problem happens with characters, the box is just for simplicity).

138275-badstationaryshadow.png

EDIT: Small addendum, by flipping the engine scalability settings around I can sometimes get it to work in editor view, but the minute I start PIE, it reverts to this broken state.

2 Likes

I can’t think of much, and I doubt anyone else can without more information or insight into your project.
What exactly do you mean by flipping engine scalability settings?

Specifically I mean switching from “epic” to “high” to “medium” to “high” etc in the quality settings in the editor.

So, super strangely, if I copy those actors into a new map with NOTHING in it and bake there, it behaves properly.
EDIT: our programmer tracked it down, has to do with a bug in the engine re: directional lights and spotlights. I will post the specific information as well as our fix once he sends it to me as a response to the original issue.

1 Like

The problem and our fix if anyone hits this.

FSceneRenderer::InitDynamicShadows builds an array of projected shadows for all lights. (ViewDependentWholeSceneShadows)
A bit further down the call stack, FSceneRenderer::CreatePerObjectProjectedShadow checks that array to see if a primitive is contained within the whole scene shadow; if so, it doesn’t set up a preshadow.
However, it’s checking the whole scene shadows for all lights iterated through so far.
In our case, the first light in the iteration was a directional light with a whole scene shadow.
The second light was a spotlight which should have been creating preshadows; but the shadow receiver was inside the directional light’s whole scene shadow, so the preshadow was skipped.

My fix is in ShadowSetup.cpp, around line 1689 in FSceneRenderer::CreatePerObjectProjectedShadow:

'for (int32 i = 0; i < ViewDependentWholeSceneShadows.Num(); i++)
{
const FProjectedShadowInfo* WholeSceneShadow = ViewDependentWholeSceneShadows[i];

// ENGINE_MOD... [DLP 17 May 2017]: Only consider a whole scene shadow if it actually belongs to this light!
// This fixes movable objects not receiving shadows from stationary lights when there is a directional light in the scene.
if (WholeSceneShadow->GetLightSceneInfoCompact().LightSceneInfo != LightSceneInfo)
{
    continue;
}
// ...ENGINE_MOD [DLP 17 May 2017]

const FVector2D DistanceFadeValues = WholeSceneShadow->GetLightSceneInfo().Proxy->GetDirectionalLightDistanceFadeParameters(Scene->GetFeatureLevel(), WholeSceneShadow->GetLightSceneInfo().IsPrecomputedLightingValid());
const float DistanceFromShadowCenterSquared = (WholeSceneShadow->ShadowBounds.Center - Bounds.Origin).SizeSquared();
//@todo - if view dependent whole scene shadows are ever supported in splitscreen, 
// We can only disable the preshadow at this point if it is inside a whole scene shadow for all views
const float DistanceFromViewSquared = ((FVector)WholeSceneShadow->DependentView->ShadowViewMatrices.GetViewOrigin() - Bounds.Origin).SizeSquared();
// Mark the preshadow as inside the whole scene shadow if its bounding sphere is inside the near fade distance
if (DistanceFromShadowCenterSquared < FMath::Square(FMath::Max(WholeSceneShadow->ShadowBounds.W - Bounds.SphereRadius, 0.0f))
    //@todo - why is this extra threshold required?
    && DistanceFromViewSquared < FMath::Square(FMath::Max(DistanceFadeValues.X - 200.0f - Bounds.SphereRadius, 0.0f)))
{
    bIsOutsideWholeSceneShadow = false;
    break;
}

}’

1 Like

This is a weird one, the only thing I can think of is that the settings change a ‘receive shadowing’ setting or something along the lines that resets every time you play. I don’t know whether the editor does actually change settings on play, or whether the settings affect lighting in this way but you could try going through the settings of the dynamic object to make sure everything is as it should be. Do all dynamic objects in the scene have the same problem, and if so what about in a new/different level?

I’m having the exact same issue on UE 5.1.1 :rage:

1 Like

I’m also having this issue in UE5, worked fine in earlier versions

This is a bug that has been fixed… but if it isn’t in 5.2 then you’ll have to wait until 5.3.

3 Likes

Same Problem in 5.3

Should try providing some or any information.

Should be noted that stationary lights will not cast dynamic shadows from Nanite meshes unless you are using Virtual Shadowmaps.