Fix border rendering for eevee + stop passing render result around
[blender.git] / source / blender / draw / engines / eevee / eevee_render.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file eevee_render.c
23  *  \ingroup draw_engine
24  */
25
26 /**
27  * Render functions for final render outputs.
28  */
29
30 #include "DRW_engine.h"
31 #include "DRW_render.h"
32
33 #include "DNA_node_types.h"
34
35 #include "BLI_rand.h"
36 #include "BLI_rect.h"
37
38 #include "DEG_depsgraph_query.h"
39
40 #include "GPU_framebuffer.h"
41 #include "GPU_glew.h"
42
43 #include "RE_pipeline.h"
44
45 #include "eevee_private.h"
46
47 void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph)
48 {
49         EEVEE_Data *vedata = (EEVEE_Data *)ved;
50         EEVEE_PassList *psl = vedata->psl;
51         EEVEE_StorageList *stl = vedata->stl;
52         EEVEE_TextureList *txl = vedata->txl;
53         EEVEE_FramebufferList *fbl = vedata->fbl;
54         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
55         Scene *scene = DEG_get_evaluated_scene(depsgraph);
56         const float *viewport_size = DRW_viewport_size_get();
57
58         /* Init default FB and render targets:
59          * In render mode the default framebuffer is not generated
60          * because there is no viewport. So we need to manually create it or
61          * not use it. For code clarity we just allocate it make use of it. */
62         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
63         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
64
65         /* NOTE : use 32 bit format for precision in render mode. */
66         DRWFboTexture dtex = {&dtxl->depth, DRW_TEX_DEPTH_24_STENCIL_8, 0};
67         DRW_framebuffer_init(&dfbl->default_fb, &draw_engine_eevee_type,
68                              (int)viewport_size[0], (int)viewport_size[1],
69                              &dtex, 1);
70
71         DRWFboTexture tex = {&txl->color, DRW_TEX_RGBA_32, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
72         DRW_framebuffer_init(&fbl->main, &draw_engine_eevee_type,
73                              (int)viewport_size[0], (int)viewport_size[1],
74                              &tex, 1);
75
76         /* Alloc transient data. */
77         if (!stl->g_data) {
78                 stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
79         }
80         EEVEE_PrivateData *g_data = stl->g_data;
81         g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f;
82         g_data->valid_double_buffer = 0;
83
84         /* Alloc common ubo data. */
85         if (sldata->common_ubo == NULL) {
86                 sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), &sldata->common_data);
87         }
88
89         /* Set the pers & view matrix. */
90         struct Object *camera = RE_GetCamera(engine->re);
91         float frame = BKE_scene_frame_get(scene);
92         RE_GetCameraWindow(engine->re, camera, frame, g_data->winmat);
93         RE_GetCameraModelMatrix(engine->re, camera, g_data->viewinv);
94
95         invert_m4_m4(g_data->viewmat, g_data->viewinv);
96         mul_m4_m4m4(g_data->persmat, g_data->winmat, g_data->viewmat);
97         invert_m4_m4(g_data->persinv, g_data->persmat);
98         invert_m4_m4(g_data->wininv, g_data->winmat);
99
100         DRW_viewport_matrix_override_set(g_data->persmat, DRW_MAT_PERS);
101         DRW_viewport_matrix_override_set(g_data->persinv, DRW_MAT_PERSINV);
102         DRW_viewport_matrix_override_set(g_data->winmat, DRW_MAT_WIN);
103         DRW_viewport_matrix_override_set(g_data->wininv, DRW_MAT_WININV);
104         DRW_viewport_matrix_override_set(g_data->viewmat, DRW_MAT_VIEW);
105         DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV);
106
107         /* EEVEE_effects_init needs to go first for TAA */
108         EEVEE_effects_init(sldata, vedata, camera);
109         EEVEE_materials_init(sldata, stl, fbl);
110         EEVEE_lights_init(sldata);
111         EEVEE_lightprobes_init(sldata, vedata);
112
113         /* INIT CACHE */
114         EEVEE_bloom_cache_init(sldata, vedata);
115         EEVEE_depth_of_field_cache_init(sldata, vedata);
116         EEVEE_effects_cache_init(sldata, vedata);
117         EEVEE_lightprobes_cache_init(sldata, vedata);
118         EEVEE_lights_cache_init(sldata, psl);
119         EEVEE_materials_cache_init(vedata);
120         EEVEE_motion_blur_cache_init(sldata, vedata);
121         EEVEE_occlusion_cache_init(sldata, vedata);
122         EEVEE_screen_raytrace_cache_init(sldata, vedata);
123         EEVEE_subsurface_cache_init(sldata, vedata);
124         EEVEE_temporal_sampling_cache_init(sldata, vedata);
125         EEVEE_volumes_cache_init(sldata, vedata);
126 }
127
128 void EEVEE_render_cache(
129         void *vedata, struct Object *ob,
130         struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
131 {
132         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
133
134         if (DRW_check_object_visible_within_active_context(ob) == false) {
135                 return;
136         }
137
138         if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
139                 EEVEE_materials_cache_populate(vedata, sldata, ob);
140
141                 const bool cast_shadow = true;
142
143                 if (cast_shadow) {
144                         EEVEE_lights_cache_shcaster_object_add(sldata, ob);
145                 }
146         }
147         else if (ob->type == OB_LIGHTPROBE) {
148                 EEVEE_lightprobes_cache_add(sldata, ob);
149         }
150         else if (ob->type == OB_LAMP) {
151                 EEVEE_lights_cache_add(sldata, ob);
152         }
153 }
154
155 static void eevee_render_result_combined(
156         RenderLayer *rl, const char *viewname, const rcti *rect,
157         EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
158 {
159         RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
160
161         DRW_framebuffer_bind(vedata->stl->effects->final_fb);
162         DRW_framebuffer_read_data(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 4, 0, rp->rect);
163 }
164
165 static void eevee_render_result_subsurface(
166         RenderLayer *rl, const char *viewname, const rcti *rect,
167         EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
168 {
169         const DRWContextState *draw_ctx = DRW_context_state_get();
170         ViewLayer *view_layer = draw_ctx->view_layer;
171
172         if (vedata->fbl->sss_accum_fb == NULL) {
173                 /* SSS is not enabled. */
174                 return;
175         }
176
177         if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) {
178                 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname);
179
180                 IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
181                 float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
182
183                 DRW_framebuffer_bind(vedata->fbl->sss_accum_fb);
184                 DRW_framebuffer_read_data(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 3, 1, rp->rect);
185
186                 /* This is the accumulated color. Divide by the number of samples. */
187                 for (int i = 0; i < rp->rectx * rp->recty * 3; i++) {
188                         rp->rect[i] /= render_samples;
189                 }
190         }
191
192         if ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
193                 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname);
194
195                 IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
196                 float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
197
198                 DRW_framebuffer_bind(vedata->fbl->sss_accum_fb);
199                 DRW_framebuffer_read_data(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 3, 0, rp->rect);
200
201                 /* This is the accumulated color. Divide by the number of samples. */
202                 for (int i = 0; i < rp->rectx * rp->recty * 3; i++) {
203                         rp->rect[i] /= render_samples;
204                 }
205         }
206
207         if ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
208                 /* Do nothing as all the lighting is in the direct pass.
209                  * TODO : Separate Direct from indirect lighting. */
210         }
211 }
212
213 static void eevee_render_result_normal(
214         RenderLayer *rl, const char *viewname, const rcti *rect,
215         EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
216 {
217         const DRWContextState *draw_ctx = DRW_context_state_get();
218         ViewLayer *view_layer = draw_ctx->view_layer;
219         EEVEE_StorageList *stl = vedata->stl;
220         EEVEE_PrivateData *g_data = stl->g_data;
221
222         /* Only read the center texel. */
223         if (stl->effects->taa_current_sample > 1)
224                 return;
225
226         if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) {
227                 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname);
228
229                 DRW_framebuffer_read_data(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 3, 1, rp->rect);
230
231                 /* Convert Eevee encoded normals to Blender normals. */
232                 for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) {
233                         if (rp->rect[i] == 0.0f && rp->rect[i + 1] == 0.0f) {
234                                 /* If normal is not correct then do not produce NANs.  */
235                                 continue;
236                         }
237
238                         float fenc[2];
239                         fenc[0] = rp->rect[i+0] * 4.0f - 2.0f;
240                         fenc[1] = rp->rect[i+1] * 4.0f - 2.0f;
241
242                         float f = dot_v2v2(fenc, fenc);
243                         float g = sqrtf(1.0f - f / 4.0f);
244
245                         rp->rect[i + 0] = fenc[0] * g;
246                         rp->rect[i + 1] = fenc[1] * g;
247                         rp->rect[i + 2] = 1.0f - f / 2.0f;
248
249                         mul_mat3_m4_v3(g_data->viewinv, &rp->rect[i]);
250                 }
251         }
252 }
253
254 static void eevee_render_result_z(
255         RenderLayer *rl, const char *viewname, const rcti *rect,
256         EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata)
257 {
258         const DRWContextState *draw_ctx = DRW_context_state_get();
259         ViewLayer *view_layer = draw_ctx->view_layer;
260         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
261         EEVEE_StorageList *stl = vedata->stl;
262         EEVEE_PrivateData *g_data = stl->g_data;
263
264         /* Only read the center texel. */
265         if (stl->effects->taa_current_sample > 1)
266                 return;
267
268         if ((view_layer->passflag & SCE_PASS_Z) != 0) {
269                 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
270
271                 DRW_framebuffer_read_depth(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), rp->rect);
272
273                 bool is_persp = DRW_viewport_is_persp_get();
274
275                 /* Convert ogl depth [0..1] to view Z [near..far] */
276                 for (int i = 0; i < rp->rectx * rp->recty; ++i) {
277                         if (rp->rect[i] == 1.0f ) {
278                                 rp->rect[i] = 1e10f; /* Background */
279                         }
280                         else {
281                                 if (is_persp) {
282                                         rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
283                                         rp->rect[i] = g_data->winmat[3][2] / (rp->rect[i] + g_data->winmat[2][2]);
284                                 }
285                                 else {
286                                         rp->rect[i] = -common_data->view_vecs[0][2] + rp->rect[i] * -common_data->view_vecs[1][2];
287                                 }
288                         }
289                 }
290         }
291 }
292
293 static void eevee_render_result_mist(
294         RenderLayer *rl, const char *viewname, const rcti *rect,
295         EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
296 {
297         const DRWContextState *draw_ctx = DRW_context_state_get();
298         ViewLayer *view_layer = draw_ctx->view_layer;
299
300         if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
301                 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname);
302
303                 IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
304                 float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
305
306                 DRW_framebuffer_bind(vedata->fbl->mist_accum_fb);
307                 DRW_framebuffer_read_data(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 1, 0, rp->rect);
308
309                 /* This is the accumulated color. Divide by the number of samples. */
310                 for (int i = 0; i < rp->rectx * rp->recty; i++) {
311                         rp->rect[i] /= render_samples;
312                 }
313         }
314 }
315
316 static void eevee_render_result_occlusion(
317         RenderLayer *rl, const char *viewname, const rcti *rect,
318         EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
319 {
320         const DRWContextState *draw_ctx = DRW_context_state_get();
321         ViewLayer *view_layer = draw_ctx->view_layer;
322
323         if (vedata->fbl->ao_accum_fb == NULL) {
324                 /* AO is not enabled. */
325                 return;
326         }
327
328         if ((view_layer->passflag & SCE_PASS_AO) != 0) {
329                 RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname);
330
331                 IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
332                 float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
333
334                 DRW_framebuffer_bind(vedata->fbl->ao_accum_fb);
335                 DRW_framebuffer_read_data(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), 3, 0, rp->rect);
336
337                 /* This is the accumulated color. Divide by the number of samples. */
338                 for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) {
339                         rp->rect[i] = rp->rect[i + 1] = rp->rect[i+2] = min_ff(1.0f, rp->rect[i] / render_samples);
340                 }
341         }
342 }
343
344 static void eevee_render_draw_background(EEVEE_Data *vedata)
345 {
346         EEVEE_TextureList *txl = vedata->txl;
347         EEVEE_FramebufferList *fbl = vedata->fbl;
348         EEVEE_PassList *psl = vedata->psl;
349
350         /* Prevent background to write to data buffers.
351          * NOTE : This also make sure the textures are bound
352          *        to the right double buffer. */
353         if (txl->ssr_normal_input != NULL) {
354                 DRW_framebuffer_texture_detach(txl->ssr_normal_input);
355         }
356         if (txl->ssr_specrough_input != NULL) {
357                 DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
358         }
359         DRW_framebuffer_bind(fbl->main);
360
361         DRW_draw_pass(psl->background_pass);
362
363         if (txl->ssr_normal_input != NULL) {
364                 DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
365         }
366         if (txl->ssr_specrough_input != NULL) {
367                 DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
368         }
369         DRW_framebuffer_bind(fbl->main);
370 }
371
372 void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl, const rcti *rect)
373 {
374         const DRWContextState *draw_ctx = DRW_context_state_get();
375         ViewLayer *view_layer = draw_ctx->view_layer;
376         const char *viewname = RE_GetActiveRenderView(engine->re);
377         EEVEE_PassList *psl = vedata->psl;
378         EEVEE_StorageList *stl = vedata->stl;
379         EEVEE_FramebufferList *fbl = vedata->fbl;
380         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
381         EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
382         EEVEE_PrivateData *g_data = stl->g_data;
383
384         /* FINISH CACHE */
385         EEVEE_materials_cache_finish(vedata);
386         EEVEE_lights_cache_finish(sldata);
387         EEVEE_lightprobes_cache_finish(sldata, vedata);
388
389         /* Sort transparents before the loop. */
390         DRW_pass_sort_shgroup_z(psl->transparent_pass);
391
392         /* Push instances attribs to the GPU. */
393         DRW_render_instance_buffer_finish();
394
395         if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR |
396                                      SCE_PASS_SUBSURFACE_DIRECT |
397                                      SCE_PASS_SUBSURFACE_INDIRECT)) != 0)
398         {
399                 EEVEE_subsurface_output_init(sldata, vedata);
400         }
401
402         if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
403                 EEVEE_mist_output_init(sldata, vedata);
404         }
405
406         if ((view_layer->passflag & SCE_PASS_AO) != 0) {
407                 EEVEE_occlusion_output_init(sldata, vedata);
408         }
409
410         IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
411         unsigned int render_samples = BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
412
413         while (render_samples-- > 0) {
414                 float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
415                 unsigned int primes[3] = {2, 3, 7};
416                 double offset[3] = {0.0, 0.0, 0.0};
417                 double r[3];
418
419                 /* Restore winmat before jittering again. */
420                 copy_m4_m4(stl->effects->overide_winmat, g_data->winmat);
421
422                 BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r);
423                 EEVEE_update_noise(psl, fbl, r);
424                 EEVEE_temporal_sampling_matrices_calc(stl->effects, g_data->viewmat, g_data->persmat, r);
425                 EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1);
426                 EEVEE_materials_init(sldata, stl, fbl);
427
428                 /* Refresh Probes */
429                 while (EEVEE_lightprobes_all_probes_ready(sldata, vedata) == false) {
430                         EEVEE_lightprobes_refresh(sldata, vedata);
431                 }
432                 EEVEE_lightprobes_refresh_planar(sldata, vedata);
433                 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
434                 /* Set matrices. */
435                 DRW_viewport_matrix_override_set(stl->effects->overide_persmat, DRW_MAT_PERS);
436                 DRW_viewport_matrix_override_set(stl->effects->overide_persinv, DRW_MAT_PERSINV);
437                 DRW_viewport_matrix_override_set(stl->effects->overide_winmat, DRW_MAT_WIN);
438                 DRW_viewport_matrix_override_set(stl->effects->overide_wininv, DRW_MAT_WININV);
439                 DRW_viewport_matrix_override_set(g_data->viewmat, DRW_MAT_VIEW);
440                 DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV);
441                 /* Refresh Shadows */
442                 EEVEE_draw_shadows(sldata, psl);
443
444                 DRW_framebuffer_texture_detach(dtxl->depth);
445                 DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
446                 DRW_framebuffer_bind(fbl->main);
447                 DRW_framebuffer_clear(true, true, true, clear_col, 1.0f);
448                 /* Depth prepass */
449                 DRW_draw_pass(psl->depth_pass);
450                 DRW_draw_pass(psl->depth_pass_cull);
451                 /* Create minmax texture */
452                 EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
453                 EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1);
454                 EEVEE_volumes_compute(sldata, vedata);
455                 /* Shading pass */
456                 eevee_render_draw_background(vedata);
457                 DRW_framebuffer_bind(fbl->main);
458                 EEVEE_draw_default_passes(psl);
459                 DRW_draw_pass(psl->material_pass);
460                 EEVEE_subsurface_data_render(sldata, vedata);
461                 /* Effects pre-transparency */
462                 EEVEE_subsurface_compute(sldata, vedata);
463                 EEVEE_reflection_compute(sldata, vedata);
464                 EEVEE_refraction_compute(sldata, vedata);
465                 /* Opaque refraction */
466                 DRW_draw_pass(psl->refract_depth_pass);
467                 DRW_draw_pass(psl->refract_depth_pass_cull);
468                 DRW_draw_pass(psl->refract_pass);
469                 /* Subsurface output */
470                 EEVEE_subsurface_output_accumulate(sldata, vedata);
471                 /* Occlusion output */
472                 EEVEE_occlusion_output_accumulate(sldata, vedata);
473                 /* Result NORMAL */
474                 eevee_render_result_normal(rl, viewname, rect, vedata, sldata);
475                 /* Volumetrics Resolve Opaque */
476                 EEVEE_volumes_resolve(sldata, vedata);
477                 /* Mist output */
478                 EEVEE_mist_output_accumulate(sldata, vedata);
479                 /* Transparent */
480                 DRW_draw_pass(psl->transparent_pass);
481                 /* Result Z */
482                 eevee_render_result_z(rl, viewname, rect, vedata, sldata);
483                 /* Post Process */
484                 EEVEE_draw_effects(sldata, vedata);
485         }
486
487         eevee_render_result_combined(rl, viewname, rect, vedata, sldata);
488         eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata);
489         eevee_render_result_mist(rl, viewname, rect, vedata, sldata);
490         eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata);
491 }
492
493 void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
494 {
495         int type;
496
497         RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
498
499 #define CHECK_PASS(name, channels, chanid) \
500         if (view_layer->passflag & (SCE_PASS_ ## name)) { \
501                 if (channels == 4) type = SOCK_RGBA; \
502                 else if (channels == 3) type = SOCK_VECTOR; \
503                 else type = SOCK_FLOAT; \
504                 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_ ## name, channels, chanid, type); \
505         }
506
507         CHECK_PASS(Z,           1, "Z");
508         CHECK_PASS(MIST,        1, "Z");
509         CHECK_PASS(NORMAL,      3, "XYZ");
510         CHECK_PASS(AO,          3, "RGB");
511         CHECK_PASS(SUBSURFACE_COLOR,     3, "RGB");
512         CHECK_PASS(SUBSURFACE_DIRECT,    3, "RGB");
513
514 #undef CHECK_PASS
515 }