godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.14k stars 96 forks source link

Allow SDF Reflections or SDF GI to be used independently from each other #3012

Open WickedInsignia opened 3 years ago

WickedInsignia commented 3 years ago

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

SDFGI reflections look great, and in many cases so does the GI itself, but there are some situations where you may not want one or the other due to performance or artifacts.

I propose that we are able to choose whether SDF reflections, GI or both are used so where they are not optimal another method (such as lightmapped GI or reflection probes) may be utilized in its place.

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

The GI implementation increases in resolution as the player gets closer to distant objects. This live updating may sometimes not be desirable. The alternative would be to use backed GI with reflection probes, but probes have many limitations. Using SDF reflections alongside baked GI would be a great solution for this and potentially save performance.

In some other cases, SDF GI may need to be used but without the reflections, which can sometimes be blotchy/smudged, act strangely, or the accuracy is simply not needed at the performance cost. In these cases using SDF GI with reflection probes would be optimal.

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

Potentially a couple tick-boxes under the "SDFGI" tab in "World Environment". This could be renamed to "SDF", with GI or reflections an optional tickbox under the settings.

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

I doubt it, but not sure.

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

SDFGI is a core graphical function of Godot 4.

mrjustaguy commented 3 years ago

I don't see how this would make any worthwhile performance improvements by using only one of those instead of both, because really, if you're noticing a performance any non insignificant improvement, you don't have a GPU that can use SDF because changing cascades will take over 50ms to do, which means sub 20 FPS experience when switching cascades, and if any performance improvements would be visible, it'll be on those GPUs.

That said, Having SDF split into 2, the Reflections and GI does have some sense, as there are cases where it might not be desired to have both, however doing SDF Reflections without GI is just a horrible idea, due to the fact that you're getting the Performance penalty anyway, and the reflections are the worst aspect of SDFGI (least useful for the GPU horsepower required to not have a super stutter-crazy experience, unless there are optimizations that can smoothen out the experience, so smoothen out Cascade Transitions which cause the Stuttering)

WickedInsignia commented 3 years ago

@mrjustaguy to answer your concerns:

mrjustaguy commented 3 years ago

1) Cascades are the same for GI and Reflections so, No, you don't get ANY performance benefit from going with only one of the 2 there 2) Reflection Probes are better, SDF reflections are voxelized, so No they're not more physically accurate, but they Do need less work to use 3) Baked GI also has Reflections (Voxel GI), and Lightmap GI can be a Massive memory hog in larger scenes (same as Voxel GI) which is not the case for SDFGI which is designed for Large scenes. All the GI methods are overall roughly identical in Physical accuracy, each with Their ups and downs depending on the scenarios, and the SDFGI "fade-ins" can be reduced significantly by picking lower latency, and just having them happen further away from the camera 4) Yes Dynamic Lighting is a little costly, SDF Cascades on the other hand, are VERY Expensive, so moving will cause HEAVY stuttering on ANY system that has to consider the costs of Dynamic Lighting, as an example, SDFGI can run at 60 FPS stationary with 4 cascades on like a GTX 650, Moving Cascades takes 66ms (4 frames worth, and then another frame to actually render the frame) - So Dynamic Lighting, not a big deal, Switching Cascades - Unusable. If You're trying to cut corners to make things run slightly better, and are considering removing SDF GI from your SDF to improve performance enough to run it, you cannot use ANY SDF (unless you plan to not move the camera at all, which I mean, yea you could do that and move the world instead, heck might be one hell of a cheap SDF Hack to pull off lol, however I doubt that it'd actually work)

WickedInsignia commented 3 years ago
  1. You missed my point here. You can increase the quality of SDFGI by increasing cascade size (among other options). This has a performance penalty. Since you can not increase the GI quality separately to reflection quality, if low-quality SDF reflections are good enough for your scene but SDFGI is not you are sacrificing performance just to get the GI up to par. In this case, the option to use light-mapped GI instead would look great and save increasing quality unnecessarily.
  2. SDF reflects the voxelized geometry and sky without any offsets, while reflection probes need positioning and the reflected image can suffer major artifacts. Probes are objectively much worse due to their inability to read whether or not the sky reflection is being occluded.
  3. Yes, each has an advantage depending on scenario. That's why I'm proposing this. Not all techniques are equal though, that is blatantly wrong. GI Probe is highly inaccurate (this can be determined visually by even a layman) and does not compare to SDFGI, both techniques look vastly different in practice. In addition, light-mapped GI is raytraced and works on a much finer scale than the other solutions.
  4. Dynamic lighting is a performance hit, especially so if you want to reach light-mapped cleanliness. That is all that needs to be confirmed here. Regardless of how costly SDF is, there are benefits to using it without dynamic lighting.

I don't understand all the pushback here? Many of your points aren't at all consistent with how Godot actually works in use. @Calinou Is there someone closer to the engine who can weigh in on this?

mrjustaguy commented 3 years ago

I don't disagree that SDF GI&Reflections could be separate toggles under SDF, I'm just saying that using SDF for Reflections and then using some other GI method ain't really worth it, as SDF GI is good enough performance at that point (because you have a good enough GPU to not have to worry about cascade jumps, as the cascade jumps are like 10x the frame time required for the rendering of quality SDFGI itself) to just use both then and doesn't have significant visual deficits compared to other GI solutions.

SDF GI is very similar to Voxel GI, with the SDF GI being MUCH more demanding, but also Better and easier to use.. Lightmaps are the Fastest, but also being the overall worst, and while they can have the most Accurate GI in small scenes, this doesn't translate well to larger scenes, where the Accuracy falls off to allow for it to work, because it is very Memory demanding, due to all the high res Lightmaps you need to get that level of accuracy that makes it visually better compared to other methods

P.S. after reading on your follow up proposal to improve Reflection Probes, I think it's clear enough that your target pc would not be able to handle Cascade jumps without heavy stuttering if SSR is too much of a performance issue, which again means that SDF would be in general just too much to provide a satisfactory result.

WickedInsignia commented 3 years ago

It’s not about performance as much as it is artistic choice. I’m building environments right now that would benefit from SDF reflections with lightmapped GI, and are large enough to make cascade fade-in an issue and the quality deficit of lightmaps negligible. I have interior environments where SDF is far too splotchy to be usable, but the reflections would be useful due to their accuracy and ability to detect sky occlusion.

I’m sure there would be at least some frame-rate and overhead gains from disabling SDF reflections or GI and leaving the other intact. There are absolutely gains in reducing SDF quality. The assumption you seem to be making is that a game would be running with SDFGI at full pelt: in reality it should be tuned down to the best visual result with the least performance impact. There’s no solve-all solution so maximum flexibility to the artist is paramount.

You also misread my other proposal: SSR is severely limited due to distance constraints and not comparable to reflection probes. It also introduces a ton of aliasing artifacts and does not treat roughness as realistically. It was not about performance, although better reflection probes would make it negligible in the right situations.

mrjustaguy commented 3 years ago

Yeah, disabling one or the other might have a very slight performance improvement, but too tiny to observe in real world scenarios..

as far as SSR part in the other proposal, I interpreted SSR being costly as it being too much of a performance hit to use, But yeah I know that SSR has plenty of issues inherent in it's "SS" methodology that isn't really avoidable afaik.

Anyhow as far as Artistic choice, that's the main and only reason I can see for the separation, and I say go for it (allowing to decide which part of SDF you want, the GI or the Reflections or both) Also just a note about SDFR, they're just drawing SDFGI's Cascades, so switching in debug to SDFGI Cascades will show you what the reflections are drawing.. It's a neat debugging view of it.

Calinou commented 3 years ago

I think disabling SDF reflections will help improve performance if you have highly reflective materials, as some loops can be skipped in the material shader this way. This could also be worth doing in GIProbe.

However, SDFGI is planned to get a rework sometime after 4.0, so maybe this will be handled differently in the end.

mrjustaguy commented 3 years ago

OP actually wants the ability to chose what to do with the SDF, currently it's doing SDF GI and SDF Reflections at the same time, but it is desired to be able to be able to do just SDF Reflections or just SDF GI

Calinou commented 3 years ago

I've found that you can comment out the following lines to disable sharp reflections in SDFGI: https://github.com/godotengine/godot/blob/e95fa21b455a5e2c512fe6e054f86df1f01e5bd3/servers/rendering/renderer_rd/shaders/gi.glsl#L334-L438

This only speeds up rendering if you have materials with a roughness lower than 0.2 that have significant screen coverage. Nonetheless, this may still be worth exposing as a project setting.

Sharp reflections enabled (default, slower)

image

Sharp reflections disabled (faster)

image

I'm not sure if the rough reflections can be disabled entirely (or whether there would be a performance advantage to doing so).

jcostello commented 3 years ago

@Calinou reflection should be able to be disabled in Voxel GI to avoid inconsistency when using ReflectionProbes.

image

Calinou commented 3 years ago

@jcostello ReflectionProbes are blended together with VoxelGI by design. To make this less visible in your test scene, increase the extents of the ReflectionProbe so the reflective surfaces aren't so close to the ReflectionProbe's edges.

jcostello commented 3 years ago

@Calinou that could help but its not a good solution because in complex scene you will use several reflection probes in restricted spaces like several rooms. I don't see any use of having both reflection enabled at the same time.

Calinou commented 3 years ago

I don't see any use of having both reflection enabled at the same time.

Having both reflections enabled at the same time helps you use ReflectionProbes more sparingly. ReflectionProbes are not always suited to every room layout in a 3D scene, so it's good to have VoxelGI take over smoothly in this case. The same concept also applies to SDFGI.

guerro323 commented 10 months ago
I've done a quick proof of concept by allowing lightmapped objects to receive GI reflections from SDFGI or HDDAGI: Lightmap only Lightmap + RP Lightmap + SDFGI Lightmap + SDFGI + RP
japanese_street_lm japanese_street_lm_rp japanese_street_lm_sdfgi japanese_street_lm_rp_sdfgi
apartment_lm apartment_lm_rp apartment_lm_sdfgi apartment_lm_rp_sdfgi

It resolves this part:

I propose that we are able to choose whether SDF reflections, GI or both are used so where they are not optimal another method (such as lightmapped GI or reflection probes) may be utilized in its place.


This improves metallic and reflective materials by a lot!
It reduce the pain of needing to place reflection probes manually everywhere, though they also blend and benefits from it especially in interiors.
As those scenes were pretty much simple for reflection probes, complex scenes with lots of diagonals, rounded walls, etc... will be harder for reflection probes and so benefit with GI reflections.

If there are interest in it (as it only complete half of this proposal), I could clean it up and make it a PR.

jcostello commented 10 months ago

I like the result. Can you bechmark the impact of having SDFGI or HDDAGI reflections?

Calinou commented 10 months ago

If there are interest in it (as it only complete half of this proposal), I could clean it up and make it a PR.

I think this is a great start already 🙂

This will decrease performance in existing lightmapped scenes that have SDFGI or HDDAGI enabled though. I don't know how common that use case is right now, still.

guerro323 commented 10 months ago

I like the result. Can you bechmark the impact of having SDFGI or HDDAGI reflections?

(Tested from the first scene)

Lightmap Only

Render CPU Render GPU Main Thread Time
0.8819ms 2.861ms 778.2ms

Lightmap + SDFGI

Render CPU Render GPU Main Thread Time
0.7797ms 3.742ms 714.6ms

Lightmap + HDDAGI

Render CPU Render GPU Main Thread Time
0.8876ms 3.551ms 649.5ms

SDFGI Only

Render CPU Render GPU Main Thread Time
0.7812ms 4.504ms 687ms

While it's expected for Lightmapped + SDFGI to be slower but it's faster than only enabling SDFGI. It seems that the CPU time is also a little bit reduced here so it's actually not that slow when combining both.

I guess it would also be possible to optimize it further in the SDFGI code :thinking:


Benchmark code used from https://github.com/godotengine/godot-benchmarks/tree/main

jcostello commented 10 months ago

To me its a good tool to have. Reflection probes are good but having reflections from SDFGI or HDDAGI with lightmaps will be awesome, specially since reflections probes have problems with nested probes

WickedInsignia commented 10 months ago

Thanks for pursuing this @guerro323 , I'm glad this proposal is promising.