Add Always Incremental update mode + queue_update() in ReflectionProbe#55929
Add Always Incremental update mode + queue_update() in ReflectionProbe#55929Calinou wants to merge 1 commit into
queue_update() in ReflectionProbe#55929Conversation
The Always Incremental update mode behaves like the Once update mode, but it always updates even when its parameters aren't changed. Since it updates one cubemap face per frame, it will update at 10 Hz when running at 60 FPS. This is not quite as smooth for fast-moving objects such as cars, but it can be sufficient for slower-moving objects and when targeting low-end configurations. Always Incremental update mode also uses higher-quality roughness filtering compared to the Always Full update mode. `queue_update()` can be used to manually force an update on a ReflectionProbe without having to move it for at least one frame. This is useful when modifying a nearby object to ensure the ReflectionProbe has up-to-date reflections.
5b7b775 to
ac9b281
Compare
|
We need to do a proposal for time slicing of reflection probes. While I am certain this is an improvement over the previous options. I am not sure it will be ideal in practice. The reason for that is that the performance tradeoffs involved will change depending on the complexity of the scene. For a relatively simple scene we can almost ignore the cost of updating the base layer of the reflection map. But for a complex project, rendering the base layer may be even more expensive than updating the roughness mipmaps. With this PR updates are done as follows:
I have a feeling we need to untie the rendering update from the roughness map processing. So that users can choose what tradeoffs they would like to make. |
Indeed, I was thinking about this while working on this PR. Maybe we should have 3 properties: Filter Mode:
Update Policy:
Update Slicing:
From my understanding, the real-time roughness filter needs all 6 faces of the cubemap to be available at the same time. Therefore, choosing it would ignore the Update Slicing property's value. If this sounds good to you, I can close godotengine/godot-proposals#2934 and open another proposal to describe the changes proposed here. The sky radiance map generation could also be reworked to use similar properties (with the exception of the Always update policy, which doesn't make sense for the environment sky as the of |
|
That mostly sounds good to me. One thing to keep in mind is that the roughness mips get updated after the base reflection is updated regardless. Accordingly, you don't need to ignore update slicing when using the "real-time" roughness filter. For example, if you set time slice to 6, it will take seven frames to update when using real time filtering. For update policy, we should connect it to the objects it draws so that it only updates when objects within its range update. I think shadows do this to some extent. So update policy should be "once, on change, always" (there might not be a reason to update always) I am also not sure about update_once. I think it may become unnecessary if we allow a separate sky for reflections. With respect to the update slicing options, we probably don't need the granularity of 1, 2, 3, and 6. I took a peak at Unity, and they only allow 3 options. All update in one frame, update base in one frame and roughness over 8, and update base over 6 frames and roughness over 8. It may be best for us to just offer 1 and 6. But I don't feel strongly about that. Let's see what users would prefer. |
Indeed, I agree that with the workaround presented in godotengine/godot-proposals#3593 (comment), there isn't much need to support |
|
Will this make it into 4.0? If not, could we at least split off the |
|
I've redone this PR from scratch following #55929 (comment), which adds many new options to choose from. |
The Always Incremental update mode behaves like the Once update mode, but it always updates even when its parameters aren't changed. Since it updates one cubemap face per frame, it will update at 10 Hz when running at 60 FPS. This is not quite as smooth for fast-moving objects such as cars, but it can be sufficient for slower-moving objects and when targeting low-end configurations.
Always Incremental update mode also uses higher-quality roughness filtering compared to the Always Full update mode.
queue_update()can be used to manually force an update on a ReflectionProbe without having to move it for at least one frame. This is useful when modifying a nearby object to ensure the ReflectionProbe has up-to-date reflections.This change can be backported to
3.xif desired (both GLES3 and GLES2).This closes #26292. See also godotengine/godot-proposals#2934.
Testing project: test_reflection_probe_queue_update.zip
Press C to cycle between ReflectionProbe update modes, F to force a ReflectionProbe update (only relevant when using the Once update mode) and Space to toggle the dynamic object's visibility.
Performance
OS: Fedora 34
CPU: Intel Core i7-6700K
GPU: GeForce GTX 1080
Preview
Update Mode: Once
simplescreenrecorder-2021-12-14_15.16.35.mp4
Update Mode: Always Incremental
simplescreenrecorder-2021-12-14_15.16.45.mp4
Update Mode: Always Full
simplescreenrecorder-2021-12-14_15.16.56.mp4