Screen Space Reflection (SSR) not working for OpenGL render
Open, ConfirmedPublic

Description

Blender Version

Broken: HEAD (f4beb64020)

Description of the problem

Simple files work fine, but more complex files don't show SSR for the final OpenGL render.

Exact steps for others to reproduce the error

Open the wanderer.blend, turn on SSR, and compare the result between viewport and the OpenGL render.

Note: If anyone wants to help isolating this, it will help a lot.

Details

Type
Bug

Here is a patch that makes the TAA of opengl render look similar to that of the viewport:

1diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
2index 86d767df313..9d504c08381 100644
3--- a/source/blender/draw/engines/eevee/eevee_effects.c
4+++ b/source/blender/draw/engines/eevee/eevee_effects.c
5@@ -441,8 +441,7 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
6​ SWAP_DOUBLE_BUFFERS();
7
8​ if (!stl->g_data->valid_double_buffer &&
9- ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) &&
10- (DRW_state_is_image_render() == false))
11+ ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0))
12​ {
13​ /* If history buffer is not valid request another frame.
14​ * This fix black reflections on area resize. */
15@@ -451,11 +450,6 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
16
17​ /* Record pers matrix for the next frame. */
18​ DRW_viewport_matrix_get(stl->g_data->prev_persmat, DRW_MAT_PERS);
19-
20- /* Update double buffer status if render mode. */
21- if (DRW_state_is_image_render()) {
22- stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL);
23- }
24​ }
25
26​ void EEVEE_effects_free(void)
27diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
28index 4ca59aaa39e..f99b29d73e4 100644
29--- a/source/blender/draw/engines/eevee/eevee_engine.c
30+++ b/source/blender/draw/engines/eevee/eevee_engine.c
31@@ -169,21 +169,9 @@ static void EEVEE_draw_scene(void *vedata)
32​ /* Default framebuffer and texture */
33​ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
34
35- /* Number of iteration: needed for all temporal effect (SSR, TAA)
36- * when using opengl render. */
37- int loop_ct = DRW_state_is_image_render() ? 4 : 1;
38-
39​ static float rand = 0.0f;
40
41- /* XXX temp for denoising render. TODO plug number of samples here */
42- if (DRW_state_is_image_render()) {
43- rand += 1.0f / 16.0f;
44- rand = rand - floorf(rand);
45-
46- /* Set jitter offset */
47- EEVEE_update_util_texture(rand);
48- }
49- else if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) && (stl->effects->taa_current_sample > 1)) {
50+ if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) && (stl->effects->taa_current_sample > 1)) {
51​ double r;
52​ BLI_halton_1D(2, 0.0, stl->effects->taa_current_sample - 1, &r);
53
54@@ -192,7 +180,7 @@ static void EEVEE_draw_scene(void *vedata)
55​ EEVEE_update_util_texture((float)r);
56​ }
57
58- while (loop_ct--) {
59+ {
60
61​ /* Refresh Probes */
62​ DRW_stats_group_start("Probes Refresh");
63diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
64index 672149b9e43..c0bad0bac8a 100644
65--- a/source/blender/draw/intern/draw_manager.c
66+++ b/source/blender/draw/intern/draw_manager.c
67@@ -3437,10 +3437,18 @@ void DRW_draw_render_loop_offscreen(
68​ rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
69​ }
70
71- /* Reset before using it. */
72- memset(&DST, 0x0, sizeof(DST));
73- DST.options.is_image_render = true;
74- DRW_draw_render_loop_ex(graph, engine, ar, v3d, NULL);
75+ bool is_request_redraw = GPU_viewport_do_update(rv3d->viewport);
76+ do {
77+ /* Reset before using it. */
78+ memset(&DST, 0x0, sizeof(DST));
79+ DST.options.is_image_render = true;
80+
81+ DRW_draw_render_loop_ex(graph, engine, ar, v3d, NULL);
82+ } while (GPU_viewport_do_update(rv3d->viewport));
83+
84+ if (is_request_redraw) {
85+ DRW_viewport_request_redraw();
86+ }
87
88​ /* restore */
89​ {

The idea is to call the DRW_draw_render_loop_ex every time the DRW_viewport_request_redraw is called.
It solves the problem, but may not be the best solution.