diff options
Diffstat (limited to 'source/blender/draw')
7 files changed, 251 insertions, 53 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index 5c4ee015c86..47068d0b843 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -240,6 +240,9 @@ void EEVEE_view_layer_data_free(void *storage) DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.spec_light); DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.emit); DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.environment); + for (int aov_index = 0; aov_index < MAX_AOVS; aov_index++) { + DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]); + } if (sldata->material_cache) { BLI_memblock_destroy(sldata->material_cache, NULL); diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 58f182ecf8d..c7a8f7729eb 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -244,31 +244,31 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, /* Create RenderPass UBO */ if (sldata->renderpass_ubo.combined == NULL) { EEVEE_RenderPassData data; - data = (EEVEE_RenderPassData){true, true, true, true, true, false, false}; + data = (EEVEE_RenderPassData){true, true, true, true, true, false, false, false, 0}; sldata->renderpass_ubo.combined = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.combined"); - data = (EEVEE_RenderPassData){true, false, false, false, false, true, false}; + data = (EEVEE_RenderPassData){true, false, false, false, false, true, false, false, 0}; sldata->renderpass_ubo.diff_color = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.diff_color"); - data = (EEVEE_RenderPassData){true, true, false, false, false, false, false}; + data = (EEVEE_RenderPassData){true, true, false, false, false, false, false, false, 0}; sldata->renderpass_ubo.diff_light = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.diff_light"); - data = (EEVEE_RenderPassData){false, false, true, false, false, false, false}; + data = (EEVEE_RenderPassData){false, false, true, false, false, false, false, false, 0}; sldata->renderpass_ubo.spec_color = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.spec_color"); - data = (EEVEE_RenderPassData){false, false, true, true, false, false, false}; + data = (EEVEE_RenderPassData){false, false, true, true, false, false, false, false, 0}; sldata->renderpass_ubo.spec_light = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.spec_light"); - data = (EEVEE_RenderPassData){false, false, false, false, true, false, false}; + data = (EEVEE_RenderPassData){false, false, false, false, true, false, false, false, 0}; sldata->renderpass_ubo.emit = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.emit"); - data = (EEVEE_RenderPassData){true, true, true, true, true, false, true}; + data = (EEVEE_RenderPassData){true, true, true, true, true, false, true, false, 0}; sldata->renderpass_ubo.environment = GPU_uniformbuf_create_ex( sizeof(data), &data, "renderpass_ubo.environment"); } @@ -276,6 +276,51 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, /* Used combined pass by default. */ g_data->renderpass_ubo = sldata->renderpass_ubo.combined; + { + g_data->num_aovs_used = 0; + if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) { + EEVEE_RenderPassData data = {true, true, true, true, true, false, false, true, 0}; + if (stl->g_data->aov_hash == EEVEE_AOV_HASH_ALL) { + ViewLayer *view_layer = draw_ctx->view_layer; + int aov_index = 0; + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + if ((aov->flag & AOV_CONFLICT) != 0) { + continue; + } + if (aov_index == MAX_AOVS) { + break; + } + data.renderPassAOVActive = EEVEE_renderpasses_aov_hash(aov); + if (sldata->renderpass_ubo.aovs[aov_index]) { + GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[aov_index], &data); + } + else { + sldata->renderpass_ubo.aovs[aov_index] = GPU_uniformbuf_create_ex( + sizeof(data), &data, "renderpass_ubo.aovs"); + } + aov_index++; + } + g_data->num_aovs_used = aov_index; + } + else { + /* Rendering a single AOV in the 3d viewport */ + data.renderPassAOVActive = stl->g_data->aov_hash; + if (sldata->renderpass_ubo.aovs[0]) { + GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[0], &data); + } + else { + sldata->renderpass_ubo.aovs[0] = GPU_uniformbuf_create_ex( + sizeof(data), &data, "renderpass_ubo.aovs"); + } + g_data->num_aovs_used = 1; + } + } + /* Free AOV UBO's that are not in use. */ + for (int aov_index = g_data->num_aovs_used; aov_index < MAX_AOVS; aov_index++) { + DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]); + } + } + /* HACK: EEVEE_material_get can create a new context. This can only be * done when there is no active framebuffer. We do this here otherwise * `EEVEE_renderpasses_output_init` will fail. It cannot be done in @@ -949,6 +994,11 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) { material_renderpass_init(fbl, &txl->spec_color_accum, texture_format, do_clear); } + if (pd->render_passes & EEVEE_RENDER_PASS_AOV) { + for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) { + material_renderpass_init(fbl, &txl->aov_surface_accum[aov_index], texture_format, do_clear); + } + } if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) { material_renderpass_init(fbl, &txl->spec_light_accum, texture_format, do_clear); @@ -960,6 +1010,7 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl, DRWPass *renderpass, + DRWPass *renderpass2, EEVEE_PrivateData *pd, GPUTexture *output_tx, struct GPUUniformBuf *renderpass_option_ubo) @@ -969,6 +1020,9 @@ static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl, pd->renderpass_ubo = renderpass_option_ubo; DRW_draw_pass(renderpass); + if (renderpass2) { + DRW_draw_pass(renderpass2); + } GPU_framebuffer_texture_detach(fbl->material_accum_fb, output_tx); } @@ -983,38 +1037,69 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v if (fbl->material_accum_fb != NULL) { DRWPass *material_accum_ps = psl->material_accum_ps; + DRWPass *background_accum_ps = psl->background_accum_ps; if (pd->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) { material_renderpass_accumulate( - fbl, psl->background_accum_ps, pd, txl->env_accum, sldata->renderpass_ubo.environment); + fbl, background_accum_ps, NULL, pd, txl->env_accum, sldata->renderpass_ubo.environment); } if (pd->render_passes & EEVEE_RENDER_PASS_EMIT) { material_renderpass_accumulate( - fbl, material_accum_ps, pd, txl->emit_accum, sldata->renderpass_ubo.emit); + fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit); } if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_COLOR) { - material_renderpass_accumulate( - fbl, material_accum_ps, pd, txl->diff_color_accum, sldata->renderpass_ubo.diff_color); + material_renderpass_accumulate(fbl, + material_accum_ps, + NULL, + pd, + txl->diff_color_accum, + sldata->renderpass_ubo.diff_color); } if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) { - material_renderpass_accumulate( - fbl, material_accum_ps, pd, txl->diff_light_accum, sldata->renderpass_ubo.diff_light); + material_renderpass_accumulate(fbl, + material_accum_ps, + NULL, + pd, + txl->diff_light_accum, + sldata->renderpass_ubo.diff_light); if (effects->enabled_effects & EFFECT_SSS) { EEVEE_subsurface_output_accumulate(sldata, vedata); } } if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) { - material_renderpass_accumulate( - fbl, material_accum_ps, pd, txl->spec_color_accum, sldata->renderpass_ubo.spec_color); + material_renderpass_accumulate(fbl, + material_accum_ps, + NULL, + pd, + txl->spec_color_accum, + sldata->renderpass_ubo.spec_color); } if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) { - material_renderpass_accumulate( - fbl, material_accum_ps, pd, txl->spec_light_accum, sldata->renderpass_ubo.spec_light); + material_renderpass_accumulate(fbl, + material_accum_ps, + NULL, + pd, + txl->spec_light_accum, + sldata->renderpass_ubo.spec_light); if (effects->enabled_effects & EFFECT_SSR) { EEVEE_reflection_output_accumulate(sldata, vedata); } } + if (pd->render_passes & EEVEE_RENDER_PASS_AOV) { + for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) { + material_renderpass_accumulate(fbl, + material_accum_ps, + background_accum_ps, + pd, + txl->aov_surface_accum[aov_index], + sldata->renderpass_ubo.aovs[aov_index]); + } + } + /* Free unused aov textures. */ + for (int aov_index = pd->num_aovs_used; aov_index < MAX_AOVS; aov_index++) { + DRW_TEXTURE_FREE_SAFE(txl->aov_surface_accum[aov_index]); + } /* Restore default. */ pd->renderpass_ubo = sldata->renderpass_ubo.combined; diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index f5cef8f3c25..1385721a569 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -53,6 +53,7 @@ extern struct DrawEngineType draw_engine_eevee_type; #define MAX_SHADOW_CASCADE 8 #define MAX_SHADOW_CUBE (MAX_SHADOW - MAX_CASCADE_NUM * MAX_SHADOW_CASCADE) #define MAX_BLOOM_STEP 16 +#define MAX_AOVS 64 // #define DEBUG_SHADOW_DISTRIBUTION @@ -163,8 +164,9 @@ BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d) #define EEVEE_RENDERPASSES_MATERIAL \ (EEVEE_RENDER_PASS_EMIT | EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_DIFFUSE_LIGHT | \ EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_SPECULAR_LIGHT | \ - EEVEE_RENDER_PASS_ENVIRONMENT) - + EEVEE_RENDER_PASS_ENVIRONMENT | EEVEE_RENDER_PASS_AOV) +#define EEVEE_AOV_HASH_ALL -1 +#define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1 /* Material shader variations */ enum { VAR_MAT_MESH = (1 << 0), @@ -376,6 +378,7 @@ typedef struct EEVEE_TextureList { struct GPUTexture *diff_light_accum; struct GPUTexture *spec_color_accum; struct GPUTexture *spec_light_accum; + struct GPUTexture *aov_surface_accum[MAX_AOVS]; struct GPUTexture *emit_accum; struct GPUTexture *bloom_accum; struct GPUTexture *ssr_accum; @@ -430,7 +433,9 @@ typedef struct EEVEE_RenderPassData { int renderPassEmit; int renderPassSSSColor; int renderPassEnvironment; - int _pad[1]; + int renderPassAOV; + int renderPassAOVActive; + int _pad[3]; } EEVEE_RenderPassData; /* ************ LIGHT UBO ************* */ @@ -860,6 +865,7 @@ typedef struct EEVEE_ViewLayerData { struct GPUUniformBuf *spec_color; struct GPUUniformBuf *spec_light; struct GPUUniformBuf *emit; + struct GPUUniformBuf *aovs[MAX_AOVS]; } renderpass_ubo; /* Common Uniform Buffer */ @@ -959,6 +965,9 @@ typedef struct EEVEE_PrivateData { /* Renderpasses */ /* Bitmask containing the active render_passes */ eViewLayerEEVEEPassType render_passes; + int aov_hash; + int num_aovs_used; + /* Uniform references that are referenced inside the `renderpass_pass`. They are updated * to reuse the drawing pass and the shading group. */ int renderpass_type; @@ -1284,10 +1293,12 @@ void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, bool post_effect); void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, - eViewLayerEEVEEPassType renderpass_type); + eViewLayerEEVEEPassType renderpass_type, + int aov_index); void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata); bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata); +int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov); /* eevee_temporal_sampling.c */ void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata); diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 504e4e1d336..32e6eac2402 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -301,7 +301,7 @@ static void eevee_render_result_normal(RenderLayer *rl, } if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) { - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL); + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL, 0); eevee_render_color_result( rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata); } @@ -321,7 +321,7 @@ static void eevee_render_result_z(RenderLayer *rl, } if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_Z) != 0) { - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z); + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z, 0); eevee_render_color_result( rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata); } @@ -334,7 +334,7 @@ static void eevee_render_result_mist(RenderLayer *rl, EEVEE_ViewLayerData *sldata) { if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) { - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST); + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST, 0); eevee_render_color_result( rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata); } @@ -347,7 +347,7 @@ static void eevee_render_result_shadow(RenderLayer *rl, EEVEE_ViewLayerData *sldata) { if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) { - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW); + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW, 0); eevee_render_color_result( rl, viewname, rect, RE_PASSNAME_SHADOW, 3, vedata->fbl->renderpass_fb, vedata); } @@ -360,7 +360,7 @@ static void eevee_render_result_occlusion(RenderLayer *rl, EEVEE_ViewLayerData *sldata) { if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) { - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO); + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO, 0); eevee_render_color_result( rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata); } @@ -378,7 +378,7 @@ static void eevee_render_result_bloom(RenderLayer *rl, } if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0) { - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM); + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM, 0); eevee_render_color_result( rl, viewname, rect, RE_PASSNAME_BLOOM, 3, vedata->fbl->renderpass_fb, vedata); } @@ -386,7 +386,7 @@ static void eevee_render_result_bloom(RenderLayer *rl, #define EEVEE_RENDER_RESULT_MATERIAL_PASS(pass_name, eevee_pass_type) \ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_##eevee_pass_type) != 0) { \ - EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type); \ + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type, 0); \ eevee_render_color_result( \ rl, viewname, rect, RE_PASSNAME_##pass_name, 3, vedata->fbl->renderpass_fb, vedata); \ } @@ -462,6 +462,35 @@ static void eevee_render_result_volume_transmittance(RenderLayer *rl, EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_TRANSMITTANCE, VOLUME_TRANSMITTANCE) } +static void eevee_render_result_aovs(RenderLayer *rl, + const char *viewname, + const rcti *rect, + EEVEE_Data *vedata, + EEVEE_ViewLayerData *sldata) +{ + if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) { + const DRWContextState *draw_ctx = DRW_context_state_get(); + ViewLayer *view_layer = draw_ctx->view_layer; + int aov_index = 0; + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + if ((aov->flag & AOV_CONFLICT) != 0) { + continue; + } + EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AOV, aov_index); + switch (aov->type) { + case AOV_TYPE_COLOR: + eevee_render_color_result( + rl, viewname, rect, aov->name, 4, vedata->fbl->renderpass_fb, vedata); + break; + case AOV_TYPE_VALUE: + eevee_render_color_result( + rl, viewname, rect, aov->name, 1, vedata->fbl->renderpass_fb, vedata); + } + aov_index++; + } + } +} + #undef EEVEE_RENDER_RESULT_MATERIAL_PASS static void eevee_render_draw_background(EEVEE_Data *vedata) @@ -641,6 +670,7 @@ void EEVEE_render_read_result(EEVEE_Data *vedata, eevee_render_result_bloom(rl, viewname, rect, vedata, sldata); eevee_render_result_volume_scatter(rl, viewname, rect, vedata, sldata); eevee_render_result_volume_transmittance(rl, viewname, rect, vedata, sldata); + eevee_render_result_aovs(rl, viewname, rect, vedata, sldata); } void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) @@ -675,6 +705,22 @@ void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *v CHECK_PASS_EEVEE(VOLUME_TRANSMITTANCE, SOCK_RGBA, 3, "RGB"); CHECK_PASS_EEVEE(BLOOM, SOCK_RGBA, 3, "RGB"); + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + if ((aov->flag & AOV_CONFLICT) != 0) { + continue; + } + switch (aov->type) { + case AOV_TYPE_COLOR: + RE_engine_register_pass(engine, scene, view_layer, aov->name, 4, "RGBA", SOCK_RGBA); + break; + case AOV_TYPE_VALUE: + RE_engine_register_pass(engine, scene, view_layer, aov->name, 1, "X", SOCK_FLOAT); + break; + default: + break; + } + } + #undef CHECK_PASS_LEGACY #undef CHECK_PASS_EEVEE } diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c index be73225b348..3f75f10b204 100644 --- a/source/blender/draw/engines/eevee/eevee_renderpasses.c +++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c @@ -27,6 +27,7 @@ #include "BKE_global.h" /* for G.debug_value */ +#include "BLI_hash.h" #include "BLI_string_utils.h" #include "DEG_depsgraph_query.h" @@ -36,12 +37,13 @@ typedef enum eRenderPassPostProcessType { PASS_POST_UNDEFINED = 0, PASS_POST_ACCUMULATED_COLOR = 1, - PASS_POST_ACCUMULATED_LIGHT = 2, - PASS_POST_ACCUMULATED_VALUE = 3, - PASS_POST_DEPTH = 4, - PASS_POST_AO = 5, - PASS_POST_NORMAL = 6, - PASS_POST_TWO_LIGHT_BUFFERS = 7, + PASS_POST_ACCUMULATED_COLOR_ALPHA = 2, + PASS_POST_ACCUMULATED_LIGHT = 3, + PASS_POST_ACCUMULATED_VALUE = 4, + PASS_POST_DEPTH = 5, + PASS_POST_AO = 6, + PASS_POST_NORMAL = 7, + PASS_POST_TWO_LIGHT_BUFFERS = 8, } eRenderPassPostProcessType; /* bitmask containing all renderpasses that need post-processing */ @@ -70,6 +72,15 @@ bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata) return (g_data->render_passes & ~EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) == 0; } +/* Calculate the hash for an AOV. The least significant bit is used to store the AOV + * type the rest of the bits are used for the name hash. */ +int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov) +{ + int hash = BLI_hash_string(aov->name); + SET_FLAG_FROM_TEST(hash, aov->type == AOV_TYPE_COLOR, EEVEE_AOV_HASH_COLOR_TYPE_MASK); + return hash; +} + void EEVEE_renderpasses_init(EEVEE_Data *vedata) { const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -81,10 +92,24 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata) if (v3d) { const Scene *scene = draw_ctx->scene; eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass; + g_data->aov_hash = 0; + if (render_pass == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { render_pass = EEVEE_RENDER_PASS_COMBINED; } + if (render_pass == EEVEE_RENDER_PASS_AOV) { + ViewLayerAOV *aov = BLI_findstring( + &view_layer->aovs, v3d->shading.aov_name, offsetof(ViewLayerAOV, name)); + if (aov != NULL) { + g_data->aov_hash = EEVEE_renderpasses_aov_hash(aov); + } + else { + /* AOV not found in view layer. */ + render_pass = EEVEE_RENDER_PASS_COMBINED; + } + } + g_data->render_passes = render_pass; } else { @@ -110,10 +135,14 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata) ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT) #undef ENABLE_FROM_LEGACY + if (DRW_state_is_image_render() && !BLI_listbase_is_empty(&view_layer->aovs)) { + enabled_render_passes |= EEVEE_RENDER_PASS_AOV; + g_data->aov_hash = EEVEE_AOV_HASH_ALL; + } + g_data->render_passes = (enabled_render_passes & EEVEE_RENDERPASSES_ALL) | EEVEE_RENDER_PASS_COMBINED; } - EEVEE_material_renderpasses_init(vedata); } @@ -216,7 +245,8 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve * After invoking this function the active frame-buffer is set to `vedata->fbl->renderpass_fb`. */ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, - eViewLayerEEVEEPassType renderpass_type) + eViewLayerEEVEEPassType renderpass_type, + int aov_index) { EEVEE_PassList *psl = vedata->psl; EEVEE_TextureList *txl = vedata->txl; @@ -311,6 +341,11 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata), } break; } + case EEVEE_RENDER_PASS_AOV: { + g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR_ALPHA; + g_data->renderpass_input = txl->aov_surface_accum[aov_index]; + break; + } case EEVEE_RENDER_PASS_BLOOM: { g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR; g_data->renderpass_input = txl->bloom_accum; @@ -392,7 +427,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) } if (is_valid) { - EEVEE_renderpasses_postprocess(sldata, vedata, render_pass); + EEVEE_renderpasses_postprocess(sldata, vedata, render_pass, 0); GPU_framebuffer_bind(dfbl->default_fb); DRW_transform_none(txl->renderpass); } diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl index 36cf3cecf40..3e0a5e76d00 100644 --- a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl @@ -1,3 +1,4 @@ +#define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1 /* ---------------------------------------------------------------------- */ /** \name Resources @@ -12,6 +13,8 @@ layout(std140) uniform renderpass_block bool renderPassEmit; bool renderPassSSSColor; bool renderPassEnvironment; + bool renderPassAOV; + int renderPassAOVActive; }; /** \} */ @@ -40,4 +43,14 @@ vec3 render_pass_emission_mask(vec3 emission_light) return renderPassEmit ? emission_light : vec3(0.0); } +bool render_pass_aov_is_color() +{ + return (renderPassAOVActive & EEVEE_AOV_HASH_COLOR_TYPE_MASK) != 0; +} + +int render_pass_aov_hash() +{ + return renderPassAOVActive & ~EEVEE_AOV_HASH_COLOR_TYPE_MASK; +} + /** \} */ diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl index 89a411bc7cb..eb6ca4b9de8 100644 --- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl @@ -4,12 +4,13 @@ #define PASS_POST_UNDEFINED 0 #define PASS_POST_ACCUMULATED_COLOR 1 -#define PASS_POST_ACCUMULATED_LIGHT 2 -#define PASS_POST_ACCUMULATED_VALUE 3 -#define PASS_POST_DEPTH 4 -#define PASS_POST_AO 5 -#define PASS_POST_NORMAL 6 -#define PASS_POST_TWO_LIGHT_BUFFERS 7 +#define PASS_POST_ACCUMULATED_COLOR_ALPHA 2 +#define PASS_POST_ACCUMULATED_LIGHT 3 +#define PASS_POST_ACCUMULATED_VALUE 4 +#define PASS_POST_DEPTH 5 +#define PASS_POST_AO 6 +#define PASS_POST_NORMAL 7 +#define PASS_POST_TWO_LIGHT_BUFFERS 8 uniform int postProcessType; uniform int currentSample; @@ -55,7 +56,7 @@ vec3 safe_divide_even_color(vec3 a, vec3 b) void main() { - vec3 color; + vec4 color = vec4(0.0, 0.0, 0.0, 1.0); ivec2 texel = ivec2(gl_FragCoord.xy); if (postProcessType == PASS_POST_DEPTH) { @@ -66,11 +67,11 @@ void main() else { depth = -get_view_z_from_depth(depth); } - color = vec3(depth); + color.rgb = vec3(depth); } else if (postProcessType == PASS_POST_AO) { float ao_accum = texelFetch(inputBuffer, texel, 0).r; - color = vec3(min(1.0, ao_accum / currentSample)); + color.rgb = vec3(min(1.0, ao_accum / currentSample)); } else if (postProcessType == PASS_POST_NORMAL) { float depth = texelFetch(depthBuffer, texel, 0).r; @@ -80,35 +81,39 @@ void main() if (depth != 1.0 && any(notEqual(encoded_normal, vec2(0.0)))) { vec3 decoded_normal = normal_decode(texelFetch(inputBuffer, texel, 0).rg, vec3(0.0)); vec3 world_normal = mat3(ViewMatrixInverse) * decoded_normal; - color = world_normal; + color.rgb = world_normal; } else { - color = vec3(0.0); + color.rgb = vec3(0.0); } } else if (postProcessType == PASS_POST_ACCUMULATED_VALUE) { float accumulated_value = texelFetch(inputBuffer, texel, 0).r; - color = vec3(accumulated_value / currentSample); + color.rgb = vec3(accumulated_value / currentSample); } else if (postProcessType == PASS_POST_ACCUMULATED_COLOR) { vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb; + color.rgb = (accumulated_color / currentSample); + } + else if (postProcessType == PASS_POST_ACCUMULATED_COLOR_ALPHA) { + vec4 accumulated_color = texelFetch(inputBuffer, texel, 0); color = (accumulated_color / currentSample); } else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) { vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb; vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb; - color = safe_divide_even_color(accumulated_light, accumulated_color); + color.rgb = safe_divide_even_color(accumulated_light, accumulated_color); } else if (postProcessType == PASS_POST_TWO_LIGHT_BUFFERS) { vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb + texelFetch(inputSecondLightBuffer, texel, 0).rgb; vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb; - color = safe_divide_even_color(accumulated_light, accumulated_color); + color.rgb = safe_divide_even_color(accumulated_light, accumulated_color); } else { /* Output error color: Unknown how to post process this pass. */ - color = vec3(1.0, 0.0, 1.0); + color.rgb = vec3(1.0, 0.0, 1.0); } - fragColor = vec4(color, 1.0); + fragColor = color; } |