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

Allow ReflectionProbes to recognize when the sky is occluded #3013

Open
Tracked by #66628
WickedInsignia opened this issue Jul 19, 2021 · 18 comments
Open
Tracked by #66628

Allow ReflectionProbes to recognize when the sky is occluded #3013

WickedInsignia opened this issue Jul 19, 2021 · 18 comments

Comments

@WickedInsignia
Copy link

WickedInsignia commented Jul 19, 2021

Describe the project you are working on

3D showcase testing environments in preparation for realtime applications. Mostly used to test the validity of Godot in my own projects.

Describe the problem or limitation you are having in your project

As of 3.3.2 and 4.0 nightly builds, reflection probes are limited to "Interior" or "Exterior" modes.
Exterior mode takes the sky into account even when it is being occluded by objects. Interior will not take the world sky into account at all.
This becomes problematic when you have an environment with a window to the outside, such as in this example:
Godot_ReflectionProbeInside_01
In the above example an emission plane is used to fake the skylight. Baked lighting is being used for GI to save performance.
Here is the same environment with no emission plane and Interior mode switched on:
Godot_ReflectionProbeInside_02
Here is the same environment with Exterior mode (Interior mode switched off). It looks entirely unrealistic since skylight is reflected regardless of whether it should be occluded by the wall or objects:
Godot_ReflectionProbeInside_03

Blending of Interior and Exterior probes does not resolve the problem.
Here is another environment with an Interior probe (in the room) touching an Exterior probe (just near the opening). The blend is too sudden and does not result in adequate reflections:
Godot_ReflectionProbeOutside_01
Here is the same environment with an Interior probe inside of an Exterior probe that envelops the room and everything outside. The sky is reflected on all surfaces, but slightly dimmer than usual. This is still unconvincing:
Godot_ReflectionProbeOutside_02

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

Allow reflection probes to recognize and reflect the sky while taking into account when it is occluded by interior objects. This would be extremely useful for environments that have a mix of interior and exterior spaces. Emission planes are a viable workaround but do not accurately reflect the outside world into a room.

This is not resolved by screen space reflections since they are costly and cannot reflect past a very limited distance.

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

I do not know the code for the reflection probes so I can't offer any. This would ideally be the default state of a reflection probe.

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

No. There is no code workaround to "force" reflection of the sky in "inside" mode as far as I'm aware.

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

Reflection Probes are a core functionality of Godot.

@Calinou Calinou changed the title Allow Reflection Probes to recognize when the sky is occluded Allow ReflectionProbes to recognize when the sky is occluded Jul 19, 2021
@clayjohn
Copy link
Member

Here is where reflection probes blend the sky in when not set to "interior" mode:
https://github.com/godotengine/godot/blob/471aae3b76f96e431a2fa3c539497527f278d76b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl#L913-L918
https://github.com/godotengine/godot/blob/471aae3b76f96e431a2fa3c539497527f278d76b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl#L941-L943

It looks like it currently blends the reflection from the probe based on how far away the pixel is from the centre of the probe. So objects close to the probe should receive no light from the sky while objects far away from the probe receive more light from the sky.

I think to really solve the problem in this proposal, the reflection probes would need to store their depth maps and do some sort of occlusion testing at render time. I am not sure exactly what that would look like or how accurate it would be.

@atirut-w
Copy link

I think a simpler solution would be to do it like Unity where the default sky reflections are reflection probes with the sky as the reflections.

@Calinou
Copy link
Member

Calinou commented Aug 26, 2021

I think a simpler solution would be to do it like Unity where the default sky reflections are reflection probes with the sky as the reflections.

This is how reflections work right now 🙂

@atirut-w
Copy link

Then make it so that actual reflection probes replaces the sky's reflection completely with it's own and have the reflection probe also render the sky in the background? I think that's how they work in Unity.

@clayjohn
Copy link
Member

@atirut-w I think you are misunderstanding what we are discussing here. The problem is light leaking at the edges of reflection probes. Probe-based lighting needs to blend smoothly with sky-only lighting otherwise you would have sharp discontinuities at the edges of probes. The problem here is that, where the sky is blending in, it is adding unwanted light.

The user proposes that we add depth maps to the probes so that we can blend based on visibility from the probe instead of distance. To the probe.

I think that is an excellent idea, but we need to discuss how it can be properly added to the engine.

@atirut-w
Copy link

atirut-w commented Aug 27, 2021

The user proposes that we add depth maps to the probes so that we can blend based on visibility from the probe instead of distance. To the probe.

I think this solution is overkill.

A simpler one is that the probe also render the sky behind things while baking like normal cameras before baking. This completely eliminate the unwanted sky reflection with interior disabled because other things can properly occlude the sky. This might event fix the blending issue.

As of currently, Godot does not seem to properly occlude the sky when baking reflection probes with interior disabled.

@clayjohn
Copy link
Member

A simpler one is that the probe also render the sky behind things while baking like normal cameras before baking.

Godot already does this. And it is unrelated to this proposal.

@atirut-w
Copy link

atirut-w commented Aug 27, 2021 via email

@atirut-w
Copy link

atirut-w commented Aug 27, 2021

Looks familiar?

image

If this does not convince you my problem is related to OP's, I don't know what will..

@clayjohn
Copy link
Member

@atirut-w again you are misunderstanding the root of the problem. As a surface gets further away from a reflection probe the lighting from the probe is blended with the lighting from the sky. What you are seeing in your screenshot is a point along that blend.

OPs suggestion is to calculate a visibility map in the reflection probe so that blending can be based on visibility instead of just distance. That would effectively solve the light leaking as a result of probe blending.

To be clear, this has nothing to do with rendering the sky while rendering the probe reflections.

@atirut-w
Copy link

As a surface gets further away from a reflection probe the lighting from the probe is blended with the lighting from the sky. What you are seeing in your screenshot is a point along that blend.

I had to test it so here's my setup:
Screenshot from 2021-08-27 20-08-30

Result(sky still not properly occluded)
Screenshot from 2021-08-27 20-08-57

Even with a huge probe extent, the problem still shows up.
Screenshot from 2021-08-27 20-10-09

This is why I believe it's not a problem with the probe blending.

@atirut-w
Copy link

UPDATE: I increase the probe's vertical extend and now the sky is properly occluded, proving this is related to probe blending just as you said, @clayjohn. Sorry if I bothered or annoyed you.

@Calinou
Copy link
Member

Calinou commented May 25, 2022

This could be resolved by making probe fading more conservative, i.e. only start fading the reflection when getting closer to the edges. Instead of starting the fade from the origin, I'd try starting the fade at 50% of the distance between the origin and the probe's edges.

@atirut-w
Copy link

This could be resolved by making probe fading more conservative, i.e. only start fading the reflection when getting closer to the edges. Instead of starting the fade from the origin, I'd try starting the fade at 50% of the distance between the origin and the probe's edges.

I was gonna suggest tweaking the fade but forgot. Maybe the fading should be made adjustable?

@Calinou
Copy link
Member

Calinou commented May 25, 2022

Maybe the fading should be made adjustable?

This might be feasible, as the ReflectionData struct has some padding that can be used to store a fade_start property.

Edit: I started working on this and got it working, but it slightly worsens performance (+0.04 mspf on average with 4 ReflectionProbes on a GTX 1080 in 2560×1440): https://github.com/Calinou/godot/tree/reflectionprobe-add-fade-start
It's not a massive slowdown by any means, but it is present. The performance penalty may be due to the tweaked fade algorithm rather than the Fade Start property.

Edit 2: Version of the above PR without the blending formula change, which performs the same as master: godotengine/godot#61416

@Jamsers
Copy link

Jamsers commented Nov 24, 2022

Is there a way to force disable the ReflectionProbe blending in 3.x, artifacts be damned? I get the feeling this is never gonna get fixed even for 3.6. Probably only for 4.0, and even then I wouldn't be surprised if it took till 4.1 for it to get fixed 😅. I just ran into this issue independently in #69100 and to speak frankly, this issue makes Godot completely and utterly useless for making any outdoor scene with even a hint of correctness.

image

(To speak even more frankly, I'm bewildered why this behavior was considered a sensible default, let alone as the only option. Unity had adjustable edge blending of its reflection probes all the way back in Unity 5.x and probably earlier IIRC.)

@Calinou
Copy link
Member

Calinou commented Nov 24, 2022

Is there a way to force disable the ReflectionProbe blending in 3.x, artifacts be damned?

Not yet, see godotengine/godot#61416 (which would need to be redone for 3.x). Also, this proposal isn't about probe blending per se (that would be #4776).

If you need it for a project right now, it should be relatively easy to change the hardcoded blend factor in the 3.x source code then recompile custom editor and export template binaries.

(To speak even more frankly, I'm bewildered why this behavior was considered a sensible default, let alone as the only option.

Godot development is very user-driven, but we can't predict all use cases until we hear about them. Until recently, relatively few users were using Godot for 3D compared to 2D.

@Jamsers
Copy link

Jamsers commented Nov 24, 2022

If you need it for a project right now, it should be relatively easy to change the hardcoded blend factor in the 3.x source code

I see, I think that settles it for 3.x then. Hopefully 4.0 arrives soon! I should be able to hardcode the blending here then yeah?
https://github.com/godotengine/godot/blob/3.5/drivers/gles3/shaders/scene.glsl#L1450
I'm thinking blend = clamp(0.9 - blend * 0.9, 0.0, 1.0). 🤔

Until recently, relatively few users were using Godot for 3D compared to 2D.

Here's hoping 4.0 changes this! 😎

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

No branches or pull requests

5 participants