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

Backport new 3D point light attenuation as an option (3.x) #52918

Merged
merged 1 commit into from
Oct 8, 2021

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented Sep 21, 2021

This provides more realistic lighting with a very small performance cost. The option is available in both GLES3 and GLES2, and can be enabled in the Project Settings. This goes well with the ACES Fitted tonemapping mode that was recently added.

When enabled, this also makes upgrading Godot 3.x projects to Godot 4.0 easier, since lighting in 3.x will better match how it'll look in Godot 4.0.

Testing project: test_light_attenuation_3.x.zip

Testing project 2 (use for testing CPU lightmapper attenuation backport): test_light_attenuation_lightmap_3.x.zip

Preview

Note: The difference in brightness between the GLES3 and GLES2 images is expected, as GLES2 does not use HDR internally.

Lights in the middle have their attenuation set to 1.0 (the default). Lights on the right have their attenuation set to 0.5 ("Out" preset). The red light in the distance has its attenuation set to 2 ("In" preset).

GLES3 fragment shading

Before After
light_attenuation_gles3_fragment_old light_attenuation_gles3_fragment_new

GLES2 fragment shading

Before After
light_attenuation_gles2_fragment_old light_attenuation_gles2_fragment_new

GLES3 vertex shading

Note: Vertex shading looks broken here due to the floor's low vertex count.

Before After
light_attenuation_gles3_vertex_old light_attenuation_gles3_vertex_new

GLES2 vertex shading

Note: Vertex shading looks broken here due to the floor's low vertex count.

Before After
light_attenuation_gles2_vertex_old light_attenuation_gles2_vertex_new

TODO

  • Adapt the CPU lightmapper code to take the new option into account.
  • Test on mobile and HTML5 to make it sure it looks as expected. Check if there's a noticeable performance impact on mobile (and if so, document it).

@Calinou Calinou requested review from a team as code owners September 21, 2021 23:11
@Calinou Calinou added this to the 3.4 milestone Sep 21, 2021
@Calinou Calinou changed the title Backport new 3D point light attenuation as an option Backport new 3D point light attenuation as an option (3.x) Sep 21, 2021
Copy link
Member

@lawnjelly lawnjelly left a comment

Choose a reason for hiding this comment

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

Have looked through the code and tested it in GLES2 and GLES3. It looks a shedload better than the old attenuation imo (or at least more realistic). 👍

I don't know whether @clayjohn wants to give it a once over too.

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 great! I'm sure many users will find this very useful.

drivers/gles3/rasterizer_storage_gles3.cpp Outdated Show resolved Hide resolved
drivers/gles2/rasterizer_storage_gles2.cpp Outdated Show resolved Hide resolved
@Calinou Calinou force-pushed the add-new-light-attenuation-3.x branch from 3830e97 to 4c94ad8 Compare October 4, 2021 12:49
@Calinou Calinou marked this pull request as draft October 4, 2021 12:54
@Calinou Calinou force-pushed the add-new-light-attenuation-3.x branch from 4c94ad8 to 31b9d08 Compare October 4, 2021 13:18
@Calinou
Copy link
Member Author

Calinou commented Oct 4, 2021

The CPU lightmapper now takes the new light attenuation option into account.

Fully baked light (with bounces disabled) on the left, real-time light on the right:

GLES3

Note: The lightmap's colors appear washed out unless Hdr As Srgb is manually enabled on the texture's import settings. Enabling this import setting makes the colors correct, but the resulting lightmap becomes too dark compared to the real-time rendering. This doesn't happen in GLES2. We should look into this in a separate issue.

Old attenuation New attenuation
gles3_attenuation_old gles3_attenuation_new

GLES2

Old attenuation New attenuation
gles2_attenuation_old gles2_attenuation_new

@Calinou
Copy link
Member Author

Calinou commented Oct 4, 2021

As for the mobile part, I tested this PR on a OnePlus 6. It looks correct, and the performance is pretty much identical.

Visual comparison

GLES3

Note: HDR was enabled on mobile to get a similar appearance as on desktop platforms.*

image

GLES2

image

Performance comparison

GLES3

Note: HDR was enabled on mobile to get a similar appearance as on desktop platforms.

Old attenuation New attenuation
2021-10-04_16 21 36 2021-10-04_16 22 07

GLES2

Don't mind the different image sizes. The rendering resolution is identical (2280×1080), but I accidentally downsized one of the images.

Old attenuation New attenuation
2021-10-04_16 20 49 2021-10-04_16 20 11

FPS fluctuates between 46 and 48 with both settings.

@Calinou Calinou marked this pull request as ready for review October 4, 2021 14:26
Copy link
Contributor

@JFonS JFonS left a comment

Choose a reason for hiding this comment

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

I think there are a couple of leftover debug prints, other than that it looks good :)

modules/lightmapper_cpu/lightmapper_cpu.cpp Outdated Show resolved Hide resolved
This provides more realistic lighting with a very small performance cost.
The option is available in both GLES3 and GLES2, and can be enabled in
the Project Settings. This goes well with the ACES Fitted tonemapping mode
that was recently added.

When enabled, this also makes upgrading Godot 3.x projects to Godot 4.0 easier,
since lighting in 3.x will better match how it'll look in Godot 4.0.
@Calinou Calinou force-pushed the add-new-light-attenuation-3.x branch from 78d47a4 to 85e080f Compare October 8, 2021 20:15
@akien-mga akien-mga merged commit 302ad4e into godotengine:3.x Oct 8, 2021
@akien-mga
Copy link
Member

Thanks!

@Calinou Calinou deleted the add-new-light-attenuation-3.x branch October 8, 2021 21:17
@Giwayume
Copy link
Contributor

Unreal 4 allows both physically based and legacy light attenuation to be used in the same scene, because it is recognized that some lights may require an artistic approach even if most are physically based. Can you make it a setting per-light instead of a project-wide setting?

@clayjohn
Copy link
Member

@Giwayume this still allows tweaking the falloff curve for artistic purposes just like it used to! The difference is now the default curve uses proper inverse squared law.

@Giwayume
Copy link
Contributor

Giwayume commented Oct 17, 2021

I'm aware,

https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/Lighting/4_1/

Exponential Falloff can often get close to realism, but will generally be best for stylized visuals.

https://docs.unrealengine.com/4.27/en-US/Resources/ContentExamples/Lighting/4_2/

Inverse Square Falloff is a different type of light falloff that most closely replicates the behavior of light in the real world.

Unreal intentionally keeps both falloff implementations because they recognize some games need it. Indeed I have seen Unreal 4 games that liberally use a combination of both. It's just a check box on the individual light to switch between the two types.

image

@Giwayume
Copy link
Contributor

image

"Disabling inverse squared falloff can be useful when placing fill lights (don't want a super bright spot near the light)."

@Calinou
Copy link
Member Author

Calinou commented Oct 17, 2021

Adding a per-light toggle will inevitably increase the performance demands (and configuration complexity), so I'd prefer not to do it.

You can use a zero or slightly negative attenuation curve for fill lights (right-click the easing curve to show presets). This will prevent them from reaching high levels of brightness 🙂

@Giwayume
Copy link
Contributor

I think if Unreal 4 can manage it, it's not a big performance it.

@Giwayume
Copy link
Contributor

image

light_params[3] (shadow enabled) is basically used as a boolean right now. Could easily store extra data in that field. Though I know float comparison in glsl has its quirks.

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.

6 participants