Eevee: Render: Add ambient occlusion pass support.
This commit is contained in:
parent
39706a0a3d
commit
36b259fa88
@ -469,6 +469,8 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
|
||||
col.prop(view_layer, "use_pass_z")
|
||||
col.prop(view_layer, "use_pass_mist")
|
||||
col.prop(view_layer, "use_pass_normal")
|
||||
col.separator()
|
||||
col.prop(view_layer, "use_pass_ambient_occlusion")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Subsurface:")
|
||||
|
@ -123,6 +123,48 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
EEVEE_TextureList *txl = vedata->txl;
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
const float *viewport_size = DRW_viewport_size_get();
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
ViewLayer *view_layer = draw_ctx->view_layer;
|
||||
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
|
||||
|
||||
if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) {
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
DRWFboTexture tex_data = {&txl->ao_accum, DRW_TEX_R_32, 0};
|
||||
DRW_framebuffer_init(&fbl->ao_accum_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1],
|
||||
&tex_data, 1);
|
||||
|
||||
/* Clear texture. */
|
||||
DRW_framebuffer_bind(fbl->ao_accum_fb);
|
||||
DRW_framebuffer_clear(true, false, false, clear, 0.0f);
|
||||
|
||||
/* Accumulation pass */
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
|
||||
psl->ao_accum_ps = DRW_pass_create("AO Accum", state);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps);
|
||||
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
|
||||
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
|
||||
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
|
||||
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
|
||||
DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &txl->gtao_horizons);
|
||||
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
||||
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
||||
}
|
||||
else {
|
||||
/* Cleanup to release memory */
|
||||
DRW_TEXTURE_FREE_SAFE(txl->ao_accum);
|
||||
DRW_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb);
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
@ -228,6 +270,26 @@ void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_FramebufferList *fbl = vedata->fbl;
|
||||
EEVEE_PassList *psl = vedata->psl;
|
||||
|
||||
if (fbl->ao_accum_fb != NULL) {
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
/* Update the min_max/horizon buffers so the refracion materials appear in it. */
|
||||
EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
|
||||
EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1);
|
||||
|
||||
DRW_framebuffer_bind(fbl->ao_accum_fb);
|
||||
DRW_draw_pass(psl->ao_accum_ps);
|
||||
|
||||
/* Restore */
|
||||
DRW_framebuffer_bind(fbl->main);
|
||||
}
|
||||
}
|
||||
|
||||
void EEVEE_occlusion_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(e_data.gtao_sh);
|
||||
|
@ -160,6 +160,7 @@ typedef struct EEVEE_PassList {
|
||||
struct DRWPass *ao_horizon_search;
|
||||
struct DRWPass *ao_horizon_search_layer;
|
||||
struct DRWPass *ao_horizon_debug;
|
||||
struct DRWPass *ao_accum_ps;
|
||||
struct DRWPass *mist_accum_ps;
|
||||
struct DRWPass *motion_blur;
|
||||
struct DRWPass *bloom_blit;
|
||||
@ -232,6 +233,7 @@ typedef struct EEVEE_FramebufferList {
|
||||
struct GPUFrameBuffer *screen_tracing_fb;
|
||||
struct GPUFrameBuffer *refract_fb;
|
||||
struct GPUFrameBuffer *mist_accum_fb;
|
||||
struct GPUFrameBuffer *ao_accum_fb;
|
||||
|
||||
struct GPUFrameBuffer *update_noise_fb;
|
||||
|
||||
@ -254,6 +256,7 @@ typedef struct EEVEE_TextureList {
|
||||
struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */
|
||||
struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP - 1]; /* R16_G16_B16 */
|
||||
struct GPUTexture *mist_accum;
|
||||
struct GPUTexture *ao_accum;
|
||||
struct GPUTexture *sss_dir_accum;
|
||||
struct GPUTexture *sss_col_accum;
|
||||
struct GPUTexture *ssr_normal_input;
|
||||
@ -814,6 +817,8 @@ void EEVEE_bloom_free(void);
|
||||
|
||||
/* eevee_occlusion.c */
|
||||
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||
void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer);
|
||||
void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||
|
@ -318,6 +318,35 @@ static void eevee_render_result_mist(
|
||||
}
|
||||
}
|
||||
|
||||
static void eevee_render_result_occlusion(
|
||||
RenderResult *rr, const char *viewname,
|
||||
EEVEE_Data *vedata, EEVEE_ViewLayerData *UNUSED(sldata))
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
ViewLayer *view_layer = draw_ctx->view_layer;
|
||||
|
||||
if (vedata->fbl->ao_accum_fb == NULL) {
|
||||
/* AO is not enabled. */
|
||||
return;
|
||||
}
|
||||
|
||||
if ((view_layer->passflag & SCE_PASS_AO) != 0) {
|
||||
RenderLayer *rl = rr->layers.first;
|
||||
RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname);
|
||||
|
||||
IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
|
||||
float render_samples = (float)BKE_collection_engine_property_value_get_int(props, "taa_render_samples");
|
||||
|
||||
DRW_framebuffer_bind(vedata->fbl->ao_accum_fb);
|
||||
DRW_framebuffer_read_data(rr->xof, rr->yof, rr->rectx, rr->recty, 3, 0, rp->rect);
|
||||
|
||||
/* This is the accumulated color. Divide by the number of samples. */
|
||||
for (int i = 0; i < rr->rectx * rr->recty * 3; i += 3) {
|
||||
rp->rect[i] = rp->rect[i+1] = rp->rect[i+2] = min_ff(1.0f, rp->rect[i] / render_samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eevee_render_draw_background(EEVEE_Data *vedata)
|
||||
{
|
||||
EEVEE_TextureList *txl = vedata->txl;
|
||||
@ -373,6 +402,10 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
|
||||
EEVEE_mist_output_init(sldata, vedata);
|
||||
}
|
||||
|
||||
if ((view_layer->passflag & SCE_PASS_AO) != 0) {
|
||||
EEVEE_occlusion_output_init(sldata, vedata);
|
||||
}
|
||||
|
||||
/* Init render result. */
|
||||
const char *viewname = RE_GetActiveRenderView(engine->re);
|
||||
const float *render_size = DRW_viewport_size_get();
|
||||
@ -431,7 +464,10 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
|
||||
DRW_draw_pass(psl->refract_depth_pass);
|
||||
DRW_draw_pass(psl->refract_depth_pass_cull);
|
||||
DRW_draw_pass(psl->refract_pass);
|
||||
/* Subsurface output */
|
||||
EEVEE_subsurface_output_accumulate(sldata, vedata);
|
||||
/* Occlusion output */
|
||||
EEVEE_occlusion_output_accumulate(sldata, vedata);
|
||||
/* Result NORMAL */
|
||||
eevee_render_result_normal(rr, viewname, vedata, sldata);
|
||||
/* Volumetrics Resolve Opaque */
|
||||
@ -450,6 +486,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct D
|
||||
eevee_render_result_combined(rr, viewname, vedata, sldata);
|
||||
eevee_render_result_subsurface(rr, viewname, vedata, sldata);
|
||||
eevee_render_result_mist(rr, viewname, vedata, sldata);
|
||||
eevee_render_result_occlusion(rr, viewname, vedata, sldata);
|
||||
|
||||
RE_engine_end_result(engine, rr, false, false, false);
|
||||
}
|
||||
@ -471,6 +508,7 @@ void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *v
|
||||
CHECK_PASS(Z, 1, "Z");
|
||||
CHECK_PASS(MIST, 1, "Z");
|
||||
CHECK_PASS(NORMAL, 3, "XYZ");
|
||||
CHECK_PASS(AO, 3, "RGB");
|
||||
CHECK_PASS(SUBSURFACE_COLOR, 3, "RGB");
|
||||
CHECK_PASS(SUBSURFACE_DIRECT, 3, "RGB");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user