Skip to content
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

Closed
nimrod-gileadi opened this issue Mar 27, 2024 · 5 comments · Fixed by #7727
Closed

No point or spot light shadows on the first rendered frame #7715

nimrod-gileadi opened this issue Mar 27, 2024 · 5 comments · Fixed by #7727
Assignees
Labels
bug Something isn't working

Comments

@nimrod-gileadi
Copy link
Contributor

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():

if (!entry.shadowMap->hasVisibleShadows()) {

However, the value of shadowMap->hasVisibleShadows() is not available until the call to updatePoint here, which is part of the Execute phase of prepareShadowPass:

auto shaderParameters = shadowMap.updatePoint(mEngine, lightData, lightIndex,

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):

  • OS: Linux
  • GPU: NVIDIA GeForce RTX 2080 Ti
  • Backend: Vulkan

Additional context

I'm working in the Google code base and can share internal code to reproduce. I haven't tried building externally.

@romainguy romainguy added the bug Something isn't working label Mar 27, 2024
@romainguy
Copy link
Collaborator

@pixelflinger isn't that a change you made recently?

@pixelflinger
Copy link
Collaborator

I feel like I fixed this recently. Can you confirm this is with a recent version?

@nimrod-gileadi
Copy link
Contributor Author

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 ./samples/lightbulb -m -d -p -i ../../third_party/environments/lightroom_14b.hdr ../../assets/models/monkey/monkey.obj), I get the following logs, showing that on the first frame, the spot lights don't cast a shadow, but on the second and third frame they do:

Render 1, pass 0(shadowType = 0) visibleShadows=1
Render 1, pass 1(shadowType = 1) visibleShadows=0
Render 1, pass 2(shadowType = 1) visibleShadows=0
Render 2, pass 0(shadowType = 0) visibleShadows=1
Render 2, pass 1(shadowType = 1) visibleShadows=1
Render 2, pass 2(shadowType = 1) visibleShadows=1
Render 3, pass 0(shadowType = 0) visibleShadows=1
Render 3, pass 1(shadowType = 1) visibleShadows=1
Render 3, pass 2(shadowType = 1) visibleShadows=1

In the original bug I mentioned point lights specifically, but this seems to apply to spot lights too.

@nimrod-gileadi nimrod-gileadi changed the title No point light shadows on the first rendered frame No point or spot light shadows on the first rendered frame Mar 28, 2024
@nimrod-gileadi
Copy link
Contributor Author

Or more visually, edit FilamentApp.cpp to stop rendering after the first 1 or 2 frames:

if (renderer->beginFrame(window->getSwapChain())) {

to:

        static int render_count = 0;
        constexpr int kFramesToRender = 1;
        render_count++;
        if (render_count <= kFramesToRender && renderer->beginFrame(window->getSwapChain())) {

First render vs second render (note the effect of the red FOCUSED_SPOT light):

first_render second_render

@pixelflinger
Copy link
Collaborator

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.

pixelflinger added a commit that referenced this issue Apr 1, 2024
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
pixelflinger added a commit that referenced this issue Apr 2, 2024
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants