Fix T77267: Render EEVEE AO pass when AO disabled.

In EEVEE the AO renderpass influenced other render passes. Until now the
pass wasn't selectable when AO was disabled in the scene to remove these
render artifacts.

This patch allows rendering EEVEE AO pass without enabling it in the
scene. It does this by binding a fallback texture that is used by the
surface shaders.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7956
This commit is contained in:
2020-08-17 11:09:16 +02:00
parent 3d47da9e4c
commit 68651534c2
6 changed files with 49 additions and 69 deletions

View File

@@ -111,9 +111,7 @@ class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_emit", text="Emission") col.prop(view_layer, "use_pass_emit", text="Emission")
col.prop(view_layer, "use_pass_environment") col.prop(view_layer, "use_pass_environment")
col.prop(view_layer, "use_pass_shadow") col.prop(view_layer, "use_pass_shadow")
row = col.row() col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
row.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
row.active = scene_eevee.use_gtao
class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel): class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):

View File

@@ -78,7 +78,8 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel); e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel);
} }
if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) { if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED ||
stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) {
const float *viewport_size = DRW_viewport_size_get(); const float *viewport_size = DRW_viewport_size_get();
const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -101,10 +102,11 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f; common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;
effects->gtao_horizons = DRW_texture_pool_query_2d( effects->gtao_horizons_renderpass = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type); fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config( GPU_framebuffer_ensure_config(
&fbl->gtao_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons)}); &fbl->gtao_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_renderpass)});
if (G.debug_value == 6) { if (G.debug_value == 6) {
effects->gtao_horizons_debug = DRW_texture_pool_query_2d( effects->gtao_horizons_debug = DRW_texture_pool_query_2d(
@@ -117,10 +119,15 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
effects->gtao_horizons_debug = NULL; effects->gtao_horizons_debug = NULL;
} }
effects->gtao_horizons = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) ?
effects->gtao_horizons_renderpass :
e_data.dummy_horizon_tx;
return EFFECT_GTAO | EFFECT_NORMAL_BUFFER; return EFFECT_GTAO | EFFECT_NORMAL_BUFFER;
} }
/* Cleanup */ /* Cleanup */
effects->gtao_horizons_renderpass = e_data.dummy_horizon_tx;
effects->gtao_horizons = e_data.dummy_horizon_tx; effects->gtao_horizons = e_data.dummy_horizon_tx;
GPU_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb); GPU_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
common_data->ao_settings = 0.0f; common_data->ao_settings = 0.0f;
@@ -136,10 +143,6 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
EEVEE_PassList *psl = vedata->psl; EEVEE_PassList *psl = vedata->psl;
EEVEE_EffectsInfo *effects = stl->effects; EEVEE_EffectsInfo *effects = stl->effects;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F; const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -157,6 +160,12 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
} }
/* Clear texture. */
if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
GPU_framebuffer_bind(fbl->ao_accum_fb);
GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
}
/* Accumulation pass */ /* Accumulation pass */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD;
DRW_PASS_CREATE(psl->ao_accum_ps, state); DRW_PASS_CREATE(psl->ao_accum_ps, state);
@@ -165,16 +174,10 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
/* Cleanup to release memory */
DRW_TEXTURE_FREE_SAFE(txl->ao_accum);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb);
}
} }
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
@@ -225,7 +228,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, quad, NULL); DRW_shgroup_call(grp, quad, NULL);

View File

@@ -681,6 +681,7 @@ typedef struct EEVEE_EffectsInfo {
int ao_depth_layer; int ao_depth_layer;
struct GPUTexture *ao_src_depth; /* pointer copy */ struct GPUTexture *ao_src_depth; /* pointer copy */
struct GPUTexture *gtao_horizons; /* Textures from pool */ struct GPUTexture *gtao_horizons; /* Textures from pool */
struct GPUTexture *gtao_horizons_renderpass; /* Texture when rendering render pass */
struct GPUTexture *gtao_horizons_debug; struct GPUTexture *gtao_horizons_debug;
/* Motion Blur */ /* Motion Blur */
float current_ndc_to_world[4][4]; float current_ndc_to_world[4][4];

View File

@@ -359,11 +359,6 @@ static void eevee_render_result_occlusion(RenderLayer *rl,
EEVEE_Data *vedata, EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata) EEVEE_ViewLayerData *sldata)
{ {
if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) == 0) {
/* AO is not enabled. */
return;
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) { 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);
eevee_render_color_result( eevee_render_color_result(

View File

@@ -90,11 +90,7 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
if (v3d) { if (v3d) {
const Scene *scene = draw_ctx->scene; const Scene *scene = draw_ctx->scene;
eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass; eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass;
if (render_pass == EEVEE_RENDER_PASS_AO && if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) {
render_pass = EEVEE_RENDER_PASS_COMBINED;
}
else if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
render_pass = EEVEE_RENDER_PASS_COMBINED; render_pass = EEVEE_RENDER_PASS_COMBINED;
} }
@@ -392,8 +388,6 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ? ((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ?
(stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) : (stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) :
stl->g_data->render_passes; stl->g_data->render_passes;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0; bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0;
bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 && bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 &&
@@ -405,12 +399,6 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
is_valid = false; is_valid = false;
} }
/* When SSS isn't available, but the pass is requested, we mark it as invalid */
if ((render_pass & EEVEE_RENDER_PASS_AO) != 0 &&
(scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
is_valid = false;
}
const int current_sample = stl->effects->taa_current_sample; const int current_sample = stl->effects->taa_current_sample;
const int total_samples = stl->effects->taa_total_sample; const int total_samples = stl->effects->taa_total_sample;
if ((render_pass & EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) && if ((render_pass & EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) &&
@@ -462,10 +450,10 @@ void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata)
tx = txl->color_double_buffer; tx = txl->color_double_buffer;
break; break;
case 6: case 6:
tx = effects->gtao_horizons; tx = effects->gtao_horizons_renderpass;
break; break;
case 7: case 7:
tx = effects->gtao_horizons; tx = effects->gtao_horizons_renderpass;
break; break;
case 8: case 8:
tx = effects->sss_irradiance; tx = effects->sss_irradiance;

View File

@@ -1297,15 +1297,13 @@ static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
{ {
Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
const bool ao_enabled = scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED;
const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED; const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED;
int totitem = 0; int totitem = 0;
EnumPropertyItem *result = NULL; EnumPropertyItem *result = NULL;
for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) { for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) {
const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i]; const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i];
if (!((!ao_enabled && item->value == EEVEE_RENDER_PASS_AO) || if (!((!bloom_enabled &&
(!bloom_enabled &&
(item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) { (item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) {
RNA_enum_item_add(&result, &totitem, item); RNA_enum_item_add(&result, &totitem, item);
} }
@@ -1321,9 +1319,6 @@ static int rna_3DViewShading_render_pass_get(PointerRNA *ptr)
eViewLayerEEVEEPassType result = shading->render_pass; eViewLayerEEVEEPassType result = shading->render_pass;
Scene *scene = rna_3DViewShading_scene(ptr); Scene *scene = rna_3DViewShading_scene(ptr);
if (result == EEVEE_RENDER_PASS_AO && ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) {
result = EEVEE_RENDER_PASS_COMBINED;
}
if (result == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { if (result == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
result = EEVEE_RENDER_PASS_COMBINED; result = EEVEE_RENDER_PASS_COMBINED;
} }