godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Implement multi-scatter GGX approximation to prevent rough metallic materials from being darker than they should be #4508

Open Calinou opened 2 years ago

Calinou commented 2 years ago

Describe the project you are working on

The Godot editor :slightly_smiling_face:

Describe the problem or limitation you are having in your project

Godot's current PBR model only simulates a single bounce within material microfacets. Since light in real life can bounce several times, this will darken rough materials, especially those with higher metallic values.

This is especially noticeable if most of your lighting comes from environment reflections. That said, even if you have other direct and indirect light sources, the brightness reduction in metallic rough materials is noticeable:

Burley (no DirectionalLight3D) Burley (with DirectionalLight3D)
2022-05-07_18 49 40_burley_no_light 2022-05-07_18 47 08_burley

This also occurs with alternative diffuse modes (all screenshots have a light):

Lambert Lambert Wrap Toon
2022-05-07_18 47 23_lambert 2022-05-07_18 48 24_lambert_wrap 2022-05-07_18 48 33_toon

If a good multiscattering approximation is implemented, the spheres would become almost invisible as their reflection would match the background sky (even when there is no DirectionalLight3D).

Testing project (master): test_multiscatter.zip

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Implement multiscattering in the GGX formula used by Godot materials.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Filament uses a fast approximation of multi-scatter GGX. See 4.7.2 Energy loss in specular reflectance in the Filament PBR documentation.

The long-term goal is to make Godot's PBR model as close as possible to Filament, as it provides a good balance between performance and physical accuracy.

Since this will change the visual appearance of some scenes, it's best to implement this feature before Godot 4.0 is released.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No.

Is there a reason why this should be core and not an add-on in the asset library?

PBR appearance is core rendering functionality. Other rendering engines such as Blender's Eevee now feature multi-scatter GGX, so it's important for Godot to stay on the same wavelength to ensure more consistent visuals across rendering engines.

Keywords for easier searching: multiscatter, multiscattering, multi-scattering

clayjohn commented 2 years ago

For reference, this proposal would require replacing: https://github.com/godotengine/godot/blob/563690347a6b9da4882bca15ebd9f3d79f30d3e6/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl#L1326-L1338

with a more accurate DFG LUT.