-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No point or spot light shadows on the first rendered frame #7715
Comments
@pixelflinger isn't that a change you made recently? |
I feel like I fixed this recently. Can you confirm this is with a recent version? |
I can confirm this is happening with the latest code in the main branch (and google3 HEAD). To demonstrate, I edited the loop here to be: auto const& passList = prepareShadowPass.getData().passList;
int i = 0;
static int render_count = 0;
render_count++;
for (auto const& entry: passList) {
if (render_count <= 3) {
std::cerr << "Render " << render_count << ", pass " << i
<< "(shadowType = " << (int) entry.shadowMap->getShadowType()
<< ") visibleShadows="
<< entry.shadowMap->hasVisibleShadows()
<< "\n";
}
i++;
if (!entry.shadowMap->hasVisibleShadows()) {
continue;
} When I run the lightbulb sample (with
In the original bug I mentioned point lights specifically, but this seems to apply to spot lights too. |
Or more visually, edit FilamentApp.cpp to stop rendering after the first 1 or 2 frames: filament/libs/filamentapp/src/FilamentApp.cpp Line 458 in a068143
to:
First render vs second render (note the effect of the red ![]() ![]() |
Okay, I'm able to reproduce and understand the problem. As things are set-up right now, the shadow visible/not visible status of point/spot lights is delayed by one frame. This is because it is set in the "execute" closure of AddPass(), but consumed in the "setup" closure of the next addPass(), so it's not ready yet at that point. |
We were calculating the shadow visibility of spot/point lights. The visibility was calculated during the "execute" phase of the FrameGraph but it was used/needed during the setup phase. The result was that the visibility was always delayed by one frame (really it was stale data from the previous calculation). We are now computing the shadow visibility earlier, during the setup phase. This is also better because we can now skip culling of these shadow maps entirely if we know they're not visible. Fixes #7715
We were calculating the shadow visibility of spot/point lights. The visibility was calculated during the "execute" phase of the FrameGraph but it was used/needed during the setup phase. The result was that the visibility was always delayed by one frame (really it was stale data from the previous calculation). We are now computing the shadow visibility earlier, during the setup phase. This is also better because we can now skip culling of these shadow maps entirely if we know they're not visible. Fixes #7715
I have a piece of code which sets up a scene with some POINT light sources, and renders one frame only.
The point lights are meant to cast shadows but they don't.
If I render two frames, instead, I get shadows.
I figured out the reason. In this piece of code, there is filtering based on
shadowMap->hasVisibleShadows()
:filament/filament/src/ShadowMapManager.cpp
Line 388 in 90d9009
However, the value of
shadowMap->hasVisibleShadows()
is not available until the call toupdatePoint
here, which is part of the Execute phase of prepareShadowPass:filament/filament/src/ShadowMapManager.cpp
Line 897 in 90d9009
Commenting out the if statement makes the shadows appear on the first frame. ShadowMap instances are cached between render calls, which is why on the second frame I get shadows.
Desktop (please complete the following information):
Additional context
I'm working in the Google code base and can share internal code to reproduce. I haven't tried building externally.
The text was updated successfully, but these errors were encountered: