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

Fix directional LightmapGI being too dark with static lights #61910

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented Jun 10, 2022

The brightness now matches dynamic lights (indirect light baked only) when Directional is enabled. Thanks @techiepriyansh for the suggestion 🙂

The brightness of lightmapping for lights marked as dynamic is unchanged by this PR.

I ended up using an even stronger multiplier ((24 / 3.0) = 8.0). Static directional lightmapping now matches dynamic directional lightmapping exactly.

This closes #49936.

Preview

Dynamic

No Directional With Directional
2022-06-10_19 19 35_dynamic_no_directional 2022-06-10_19 20 11_dynamic_with_directional

Static

No Directional With Directional (before PR) With Directional (after PR)
2022-06-10_19 21 00_static_no_directional 2022-06-10_19 21 18_static_with_directional 2022-06-10_19 35 21_static_with_directional_8

@Calinou Calinou requested a review from a team as a code owner June 10, 2022 17:42
@Calinou Calinou added this to the 4.0 milestone Jun 10, 2022
@clayjohn clayjohn requested a review from JFonS June 12, 2022 19:57
@clayjohn
Copy link
Member

I think we need to dig a little deeper into the meaning behind those coefficients. The lighting still doesn't match. In the image you posted you can see that with this PR the faces facing left are significantly brighter than when using dynamic lights. To me this indicates that the problem lies somewhere else and we need to do the work to uncover what the problem is a fix it at source.

CC @JFonS

@jcostello
Copy link
Contributor

jcostello commented Jun 16, 2022

Are the normals backed ni the right direction?

No lightmap
image

With Lightmap

image

@Calinou
Copy link
Member Author

Calinou commented Jun 16, 2022

@jcostello This is an unrelated issue. Please open a new issue with a minimal reproduction project attached.

@atirut-w
Copy link
Contributor

Static Directional seems to be just slightly brighter than Dynamic Directional.

@clayjohn clayjohn modified the milestones: 4.0, 4.x Feb 13, 2023
@clayjohn
Copy link
Member

Bumping to 4.x. I don't think this is the right fix and I don't want to introduce arbitrary scaling factors into the codebase without first investigating why they may be needed

@atirut-w

This comment was marked as off-topic.

@jcostello

This comment was marked as off-topic.

@jcostello
Copy link
Contributor

Without this we get this from

RealTime
image

To static bake (non-directional. Directional is still broken after the camera attributes changes)
image

@atirut-w
Copy link
Contributor

Is this PR dead? Or is it superseeded?

@jcostello
Copy link
Contributor

I belive directional light have to be fixed since beside it bakes darker, it has artifacts

@DarioSamo
Copy link
Contributor

I'd like to clarify at first I haven't exactly gotten the entire grasp of how the spherical harmonics encoding works, but I believe I have enough to justify this PR's choice of the 8.0 value enough so the fix is merged.

The two chunks of relevant code to evaluate here are:

#ifdef USE_SH_LIGHTMAPS
float c[4] = float[](
0.282095, //l0
0.488603 * light_dir.y, //l1n1
0.488603 * light_dir.z, //l1n0
0.488603 * light_dir.x //l1p1
);
for (uint j = 0; j < 4; j++) {
sh_accum[j].rgb += light * c[j] * (1.0 / 3.0);
}
#endif

#ifdef USE_SH_LIGHTMAPS
float c[4] = float[](
0.282095, //l0
0.488603 * ray_dir.y, //l1n1
0.488603 * ray_dir.z, //l1n0
0.488603 * ray_dir.x //l1p1
);
for (uint j = 0; j < 4; j++) {
sh_accum[j].rgb += light * c[j] * (8.0 / float(params.ray_count));
}
#endif

The first chunk belongs to the direct light computation step of the lightmapper. This is fairly straightforward: rays are not casted at random but rather traced directly to the light sources. The result is added with this coefficient of (1.0 / 3.0) along with the multipliers used for each component of the spherical harmonics.

The second chunk belongs to the indirect light (bounces) step of the lightmapper. Here an the average result is computed from rays traced at random, which is why it opts to multiply the additional light divided by params.ray_count. At first I thought it was a bit odd how it didn't match the behavior of the accumulated bounce light, but as it turns out there's an error in how the behavior for that works (which I'll leave for a different issue). The short version is, the division on this one is the intended result at least to average out all the light computed from all the rays.

That indicates however the resulting indirect light is added with a coefficient of 8.0, which doesn't match the (1.0 / 3.0) that was found before for the direct light step. In fact, the intensity is far stronger for the indirect component than the direct one. This PR is justified to use the 8.0 value as it comes directly from the other step, which brings them to the same range in intensity as they should be (and it's how the result from both direct and bounce light are added together when not using spherical harmonics).

However, there's likely some underlying meaning to these coefficients chosen so I'll be taking a look at the resources @reduz used for implementing this to try to understand their origin better. However, as far as fixing things in the short term, I think we're good to merge this PR for now. As it stands there's some other fundamental core issues with the lightmapper that will take a longer time to fix and it'd be preferrable to at least make this feature not broken for now.

@DarioSamo
Copy link
Contributor

DarioSamo commented Sep 19, 2023

As an addendum, I'd probably take out the comment entirely as there's no need to do this empirically, as the same constant can be found elsewhere in the code or link back to this PR instead.

@clayjohn clayjohn modified the milestones: 4.x, 4.2 Sep 21, 2023
The brightness now matches dynamic lights (indirect light baked only)
when Directional is enabled.

Co-authored-by: Priyansh Rathi <techiepriyansh@gmail.com>
@Calinou Calinou force-pushed the lightmapgi-static-directional-fix-brightness branch from b543bba to 7831eed Compare September 21, 2023 16:04
@Calinou
Copy link
Member Author

Calinou commented Sep 21, 2023

Rebased and tested again, it works as expected:

Directional OFF Directional ON (master) Directional ON (this PR)
Screenshot_20230921_180145 webp Screenshot_20230921_180238 webp Screenshot_20230921_180204 webp
Directional OFF Directional ON (this PR)
Screenshot_20230921_180511 webp Screenshot_20230921_180457 webp
Directional OFF Directional ON (this PR)
Screenshot_20230921_180720 webp Screenshot_20230921_180708 webp

Testing project: test_lightmap_preview_bake_4.x_2.zip

@jcostello
Copy link
Contributor

Seems that the directional bake introduces artifacts because fo the normal calculations. I can't remember if there is an issue for that

@clayjohn
Copy link
Member

Seems that the directional bake introduces artifacts because fo the normal calculations. I can't remember if there is an issue for that

The picture you posted above does indeed look pretty buggy. If there isn't already a bug report, can you open one?

Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me given the discussion in the PR!

I didn't flag for cherrypicking as it will result in a very obvious physical change

@Calinou
Copy link
Member Author

Calinou commented Sep 21, 2023

The picture you posted above does indeed look pretty buggy. If there isn't already a bug report, can you open one?

To be fair, the imported scene's normals themselves are weird (likely due to Godot's OBJ importer - I think the source OBJ file itself is fine). Directional lightmaps just make that issue more noticeable.

@jcostello
Copy link
Contributor

Seems that the directional bake introduces artifacts because fo the normal calculations. I can't remember if there is an issue for that

The picture you posted above does indeed look pretty buggy. If there isn't already a bug report, can you open one?

I will open a Issue. Directional generate this weird alien like artifacts

image

@atirut-w
Copy link
Contributor

Testing project: test_lightmap_preview_bake_4.x_2.zip

If you don't mind, where did you get the original model?

@Calinou
Copy link
Member Author

Calinou commented Sep 22, 2023

If you don't mind, where did you get the original model?

https://github.com/Calinou/game-maps-obj/blob/master/redeclipse/octavus.obj

@akien-mga akien-mga merged commit 6094738 into godotengine:master Sep 22, 2023
16 checks passed
@akien-mga
Copy link
Member

Thanks!

@Calinou Calinou deleted the lightmapgi-static-directional-fix-brightness branch September 22, 2023 20:26
@atirut-w
Copy link
Contributor

Directional generate this weird alien like artifacts

Have you opened the issue yet? If not, I'll open it, as the issue seem to have also cropped up in the Abandoned Spaceship demo.

@jcostello
Copy link
Contributor

@atirut-w I didnt yet. If you can open up an issue for me. I tried to replicate it in a small MRP but I couldn't. It only happen to me in bigger scenes like sponza

@Calinou
Copy link
Member Author

Calinou commented Sep 25, 2023

Please continue the discussion about the bug in #82307.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Vulkan: LightmapGI's Directional property only works correctly when lights' bake mode is Dynamic, not Static
8 participants