godotengine / godotengine/godot

Global illumination doesn't update when force drawing a `SubViewport` if main viewport is disabled

Open
#97,658 2 comments 0 reactions 0 assignees View on GitHub
bug topic:3d topic:rendering
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

- 4.4.dev
- 4.3.1.rc

### System information

Godot v4.4.dev (e3213aaef) - Windows 11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 (NVIDIA; 31.0.15.4633)

### Issue description

SDFGI takes some frames to converge the global illumination (setting `rendering/global_illumination/sdfgi/frames_to_converge`).
However, when force drawing a `SubViewport` like the below example, global illumination doesn't update if the main viewport is disabled.

```gdscript
func _render_subviewport(subviewport: SubViewport, iterations: int = 30, disable_main = true) -> Image:
var scene_tree = Engine.get_main_loop() as SceneTree
var root_viewport = scene_tree.root.get_viewport_rid()
if disable_main:
# Disable main viewport so it doesn't redrawn
RenderingServer.viewport_set_active(root_viewport, false)

# Render SubViewport
for i in iterations:
await RenderingServer.frame_pre_draw
RenderingServer.viewport_set_update_mode(render.get_viewport_rid(), RenderingServer.VIEWPORT_UPDATE_ONCE)
RenderingServer.force_draw(true, 1.0 / iterations)
await RenderingServer.frame_post_draw

if disable_main:
# Enable main viewport again
RenderingServer.viewport_set_active(root_viewport, true)
await RenderingServer.frame_post_draw # image data doesn't updates correctly without this..

return subviewport.get_texture().get_image()
```
Left: expected. Right: result of multiple `force_draw()`, lighting didn't iterate and it always looks like the first iteration.

![image](https://github.com/user-attachments/assets/56f4923a-4a75-4fa6-a608-b73dae1a6101)

It only updates correclty when the main viewport is enabled during `force_draw()`.

![image](https://github.com/user-attachments/assets/73c3bf23-9bf0-42b3-a3ac-8eb01a3b417d)

But it slows down rendering since `force_draw()` draws all active viewports although I don't need the main viewport.

### Steps to reproduce

* Open the MRP. It contains the test project of the images above.
* Run the project. The left is a realtime `SubViewport`. The right creates a `SubViewport` dynamically, force draw multiple times and shows a `TextureRect` with the resulting image.
* Toggle "Disable main viewport".
* Rendering only looks correct when the main viewport is enabled.

### Minimal reproduction project (MRP)

[sdfgi-update.zip](https://github.com/user-attachments/files/17194488/sdfgi-update.zip)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.