godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.07k stars 69 forks source link

Improve backlighting / Translucency #8665

Open WrobotGames opened 6 months ago

WrobotGames commented 6 months ago

Describe the project you are working on

3D scenes with foliage, and experiments with materials. Note: this proposal contains several issues, but the solutions are so close that it made sense to combine them.

Describe the problem or limitation you are having in your project

The backlight property in Godot currently has a few issues:

  1. Backlight is only affected by lights, not by GI or Cubemaps. If you have a scene with a backlit plane with just an HDRI, the underside of the backlit plane will be way to dark. https://github.com/godotengine/godot/issues/79859 (Opened up an issue about this earlier, but thought a proposal would fit better. )
  2. Backlighting has no effect on GI. For example, a tent: the inside of the tent isn't lit by the light passing though the tent itself. This makes scenes with a lot of backlit objects really dark (A dense forest right now is completely black, while it should be green-ish) shell-campingwithstyle-J8tD4HLJLSw-unsplash The green color of the backlit tent casting onto the objects on the table. (https://unsplash.com/photos/red-and-black-tent-near-green-grass-field-during-daytime-J8tD4HLJLSw)
  3. The model currently used for the backlight sample seems a bit odd, at least to me. Does it use the diffuse model selected (Like lambert or burley)? The current backlight model doesn't seem to use normals correctly. This issue makes models (Especially with normal maps) a lot less detailed looking, as basically all detail in the normals is lost. afbeelding Backlighting enabled (left) ---- disabled (right) Blender Eevee Backlight enabled: afbeelding

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

Possible solutions (for every problem):

  1. As far as I know, the backlight property should drive a full diffuse sample with reversed normals, and then tinted with the backlight color. This diffuse sample should not only include the lights, but also a cubemap sample and a gi sample (VoxelGI and DynamicGI).
  2. The solution would be to sample the backlight color just like the diffuse and add it to the GI. I do not know if there is any way to do this with an acceptable performance penalty, or if it will even cost anything.
  3. Just like solution 1, this issue should be fixed by performing a full diffuse sample for the backlight.

Used as source: https://academysoftwarefoundation.github.io/OpenPBR/#model/thin-walledcase The model in this paper also includes energy conservation, but this is more of an artistic decision. For more realistic graphics the artist can lower the albedo color to get the look they want.

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

(I am by all means not a shader expert) Mockup:

sample_diffuse() would be the combination of light diffuse (lambert, burley, toon) and gi and environment diffuse, just like how it is right now. Total_diffuse = sample_diffuse(albedo_color, normal) + backlight_color * sample_diffuse(albedo_color, -normal)`;

With 'realistic' energy conservation according to OpenPBR: With g = anisotrophy from -1 to 1 (default = 0) Total_diffuse = 0.5 * (1 - g) * sample_diffuse(albedo_color, normal) + 0.5 * (1+g) * backlight_color * sample_diffuse(albedo_color, -normal); This with g = 1 would just mean default sample with reversed normals, and g = -1 is default sample.

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

Part of the built in shader.

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

Part of the built in shader.

Calinou commented 6 months ago

Backlighting has no effect on GI.

As I understand it, this is difficult to do with real-time GI techniques, although it could be implemented for the lightmapper. I don't think raytraced GI even bothers with this, unless it's full pathtracing.

As far as I know, the backlight property should drive a full diffuse sample with reversed normals, and then tinted with the backlight color. This diffuse sample should not only include the lights, but also a cubemap sample and a gi sample (VoxelGI and DynamicGI).

Sampling GI twice would make it much more expensive, so I'm not sure if this is viable. Even sampling reflection probes isn't cheap if you have multiple overlapping reflection probes that have to be blended together.