godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.27k stars 21.04k forks source link

Directional LightmapGI denoising exhibits artifacts on surfaces close to emissive surface #86815

Open TidB opened 9 months ago

TidB commented 9 months ago

Tested versions

System information

Godot v4.2.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated Radeon RX 580 Series (Advanced Micro Devices, Inc.; 31.0.21902.5) - 12th Gen Intel(R) Core(TM) i5-12400 (12 Threads)

Issue description

I often place emissive meshes near other geometry (e.g. TV screens), which makes the following artifacts apparent: image

The artifacts seem to arise from the denoiser step, as the un-denoised results (taken without the denoiser option) look similar enough: image

While the denoised results show the artifacting (or perhaps, the lack of reducing the noise?): image

I've only taken the topmost part of the directional lightmap file, but the other parts exhibit similar artifacting. Even though the example images were taken with a non-normal-mapped mesh, the result with a normal map is the same (you can try it out by using wall_mat instead of flat_mat inside the MRP).

This seems related to the introduction of the JNLM denoiser (#81659), as going back to OIDN inside the same 4.2 version produces this result: image

Moving the emissive mesh a bit away (usually 1 m distance is enough) makes the artifacts disappear: image image

Steps to reproduce

  1. Create two meshes set up for LightmapGI, one of them emissive
  2. Position the emissive object close to the other mesh (less than 50 cm away, the closer the more noticeable)
  3. Activate LightmapGI's directional option and bake lightmaps

Minimal reproduction project (MRP)

directional-lightmap.zip

The main scene test-dir-denois contains the other scenes dir and non-dir, both of which have their own LightmapGI instance.

Calinou commented 9 months ago

Small but strong emissive objects will result in visible noise due to the high amount of discrepancy between rays. JNLM is showing its limits here, so using OIDN will lead to better results. You can still use OIDN after Godot 4.2 using its executable. Alternatively, you can increase bake quality in LightmapGI at the cost of longer bake times. Implementing support for adaptive sampling could be helpful to improve bake times with higher bake quality settings.

@DarioSamo may have an idea on how to improve this to an extent (perhaps increasing denoiser strength for bright pixels that are far away enough from a light node), but I doubt much can be done.

DarioSamo commented 9 months ago

Yeah this is basically the edge case JNLM can't handle unless you increase the denoiser strength, as the algorithm will limit itself to only denoising a certain range of luminance. Of course doing that will denoise other stuff more aggressively so there is a trade-off. The banding you're seeing is basically where that threshold shows up, which is controlled by the strength.

If the strength isn't enough to solve it, I'd encourage you to use OIDN here as well as the included version was far too slow due to being single threaded, so you'll get much faster results from using the new executable approach.