diff options
5 files changed, 71 insertions, 21 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index da1f5317dab..8893a8c62e9 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -58,7 +58,6 @@ static void eevee_scene_layer_data_free(void *storage) DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_fb); DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_filter_fb); DRW_TEXTURE_FREE_SAFE(sldata->probe_rt); - DRW_TEXTURE_FREE_SAFE(sldata->probe_depth_rt); DRW_TEXTURE_FREE_SAFE(sldata->probe_pool); DRW_TEXTURE_FREE_SAFE(sldata->irradiance_pool); DRW_TEXTURE_FREE_SAFE(sldata->irradiance_rt); diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index b02109960c5..4191c21eea1 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -69,6 +69,8 @@ static struct { struct GPUShader *dof_downsample_sh; struct GPUShader *dof_scatter_sh; struct GPUShader *dof_resolve_sh; + + struct GPUTexture *minmmaxz_depth_src; } e_data = {NULL}; /* Engine data */ extern char datatoc_effect_minmaxz_frag_glsl[]; @@ -440,12 +442,12 @@ void EEVEE_effects_cache_init(EEVEE_Data *vedata) psl->minmaxz_downdepth = DRW_pass_create("HiZ Down Depth", DRW_STATE_WRITE_COLOR); grp = DRW_shgroup_create(e_data.minmaxz_downdepth_sh, psl->minmaxz_downdepth); - DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.minmmaxz_depth_src); DRW_shgroup_call_add(grp, quad, NULL); psl->minmaxz_copydepth = DRW_pass_create("HiZ Copy Depth", DRW_STATE_WRITE_COLOR); grp = DRW_shgroup_create(e_data.minmaxz_copydepth_sh, psl->minmaxz_copydepth); - DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth); + DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.minmmaxz_depth_src); DRW_shgroup_call_add(grp, quad, NULL); } @@ -566,12 +568,14 @@ static void minmax_downsample_cb(void *vedata, int UNUSED(level)) DRW_draw_pass(psl->minmaxz_downlevel); } -void EEVEE_create_minmax_buffer(EEVEE_Data *vedata) +void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src) { EEVEE_PassList *psl = vedata->psl; EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_StorageList *stl = vedata->stl; + e_data.minmmaxz_depth_src = depth_src; + /* Copy depth buffer to minmax texture top level */ DRW_framebuffer_texture_attach(fbl->minmaxz_fb, stl->g_data->minmaxz, 0, 0); DRW_framebuffer_bind(fbl->minmaxz_fb); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 62edfa642eb..394e284c63b 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -150,7 +150,7 @@ static void EEVEE_draw_scene(void *vedata) DRW_draw_pass(psl->depth_pass_cull); /* Create minmax texture */ - EEVEE_create_minmax_buffer(vedata); + EEVEE_create_minmax_buffer(vedata, dtxl->depth); /* Restore main FB */ DRW_framebuffer_bind(fbl->main); diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 114d5824a8b..552bf8080d4 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -61,7 +61,10 @@ static struct { struct GPUTexture *hammersley; struct GPUTexture *planar_depth; + struct GPUTexture *planar_minmaxz; struct GPUTexture *planar_pool_placeholder; + struct GPUTexture *cube_face_depth; + struct GPUTexture *cube_face_minmaxz; bool update_world; bool world_ready_to_shade; @@ -152,14 +155,20 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) * DRW_framebuffer_init binds the whole texture making the framebuffer invalid. * To overcome this, we bind the planar pool ourselves later */ + /* Note: this is not the configuration used when rendering. */ DRWFboTexture tex = {&e_data.planar_depth, DRW_TEX_DEPTH_24, DRW_TEX_TEMP}; DRW_framebuffer_init(&fbl->planarref_fb, &draw_engine_eevee_type, width, height, &tex, 1); + + DRWFboTexture tex_minmaxz = {&e_data.planar_minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP}; + + DRW_framebuffer_init(&fbl->planarref_fb, &draw_engine_eevee_type, + width / 2, height / 2, &tex_minmaxz, 1); } } -void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(vedata)) +void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) { /* Shaders */ if (!e_data.probe_filter_glossy_sh) { @@ -260,17 +269,23 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(ved /* Setup Render Target Cubemap */ if (!sldata->probe_rt) { sldata->probe_rt = DRW_texture_create_cube(PROBE_RT_SIZE, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); - sldata->probe_depth_rt = DRW_texture_create_cube(PROBE_RT_SIZE, DRW_TEX_DEPTH_24, DRW_TEX_FILTER, NULL); } - DRWFboTexture tex_probe[2] = {{&sldata->probe_depth_rt, DRW_TEX_DEPTH_24, DRW_TEX_FILTER}, - {&sldata->probe_rt, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP}}; + /* Highjacking the minmaxz_fb but that's ok because it's reconfigured before usage. */ + DRWFboTexture tex_cubeface_depth = {&e_data.cube_face_depth, DRW_TEX_DEPTH_24, DRW_TEX_TEMP}; + DRW_framebuffer_init(&vedata->fbl->minmaxz_fb, &draw_engine_eevee_type, PROBE_RT_SIZE, PROBE_RT_SIZE, &tex_cubeface_depth, 1); - DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, PROBE_RT_SIZE, PROBE_RT_SIZE, tex_probe, 2); + DRWFboTexture tex_probe = {&sldata->probe_rt, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP}; + DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, PROBE_RT_SIZE, PROBE_RT_SIZE, &tex_probe, 1); + + /* Minmaxz Pyramid */ + /* Highjacking the minmaxz_fb but that's ok because it's reconfigured before usage. */ + DRWFboTexture tex_minmaxz = {&e_data.cube_face_minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP}; + DRW_framebuffer_init(&vedata->fbl->minmaxz_fb, &draw_engine_eevee_type, PROBE_RT_SIZE / 2, PROBE_RT_SIZE / 2, &tex_minmaxz, 1); /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */ if (!e_data.planar_pool_placeholder) { - e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL); } } @@ -877,12 +892,15 @@ static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *p /* Render the scene to the probe_rt texture. */ static void render_scene_to_probe( - EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, + EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, const float pos[3], float clipsta, float clipend) { + EEVEE_TextureList *txl = vedata->txl; + EEVEE_PassList *psl = vedata->psl; + EEVEE_StorageList *stl = vedata->stl; EEVEE_LightProbesInfo *pinfo = sldata->probes; - float winmat[4][4], posmat[4][4]; + float winmat[4][4], posmat[4][4], tmp_ao_dist, tmp_ao_samples; unit_m4(posmat); @@ -892,22 +910,34 @@ static void render_scene_to_probe( /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */ sldata->probes->specular_toggle = false; + /* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */ + tmp_ao_dist = stl->effects->ao_dist; + tmp_ao_samples = stl->effects->ao_samples; + stl->effects->ao_dist = 0.0f; + stl->effects->ao_samples = 0.0f; + /* 1 - Render to each cubeface individually. * We do this instead of using geometry shader because a) it's faster, * b) it's easier than fixing the nodetree shaders (for view dependant effects). */ pinfo->layer = 0; perspective_m4(winmat, -clipsta, clipsta, -clipsta, clipsta, clipsta, clipend); + /* Avoid using the texture attached to framebuffer when rendering. */ + /* XXX */ + GPUTexture *tmp_planar_pool = txl->planar_pool; + GPUTexture *tmp_minmaxz = stl->g_data->minmaxz; + txl->planar_pool = e_data.planar_pool_placeholder; + stl->g_data->minmaxz = e_data.cube_face_minmaxz; + /* Detach to rebind the right cubeface. */ DRW_framebuffer_bind(sldata->probe_fb); + DRW_framebuffer_texture_attach(sldata->probe_fb, e_data.cube_face_depth, 0, 0); DRW_framebuffer_texture_detach(sldata->probe_rt); - DRW_framebuffer_texture_detach(sldata->probe_depth_rt); for (int i = 0; i < 6; ++i) { float viewmat[4][4], persmat[4][4]; float viewinv[4][4], persinv[4][4]; DRW_framebuffer_cubeface_attach(sldata->probe_fb, sldata->probe_rt, 0, i, 0); - DRW_framebuffer_cubeface_attach(sldata->probe_fb, sldata->probe_depth_rt, 0, i, 0); DRW_framebuffer_viewport_size(sldata->probe_fb, 0, 0, PROBE_RT_SIZE, PROBE_RT_SIZE); DRW_framebuffer_clear(false, true, false, NULL, 1.0); @@ -930,15 +960,19 @@ static void render_scene_to_probe( DRW_draw_pass(psl->depth_pass); DRW_draw_pass(psl->depth_pass_cull); + EEVEE_create_minmax_buffer(vedata, e_data.cube_face_depth); + + /* Rebind Planar FB */ + DRW_framebuffer_bind(sldata->probe_fb); + /* Shading pass */ EEVEE_draw_default_passes(psl); DRW_draw_pass(psl->material_pass); DRW_framebuffer_texture_detach(sldata->probe_rt); - DRW_framebuffer_texture_detach(sldata->probe_depth_rt); } DRW_framebuffer_texture_attach(sldata->probe_fb, sldata->probe_rt, 0, 0); - DRW_framebuffer_texture_attach(sldata->probe_fb, sldata->probe_depth_rt, 0, 0); + DRW_framebuffer_texture_detach(e_data.cube_face_depth); DRW_viewport_matrix_override_unset(DRW_MAT_PERS); DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV); @@ -948,6 +982,10 @@ static void render_scene_to_probe( /* Restore */ sldata->probes->specular_toggle = true; + txl->planar_pool = tmp_planar_pool; + stl->g_data->minmaxz = tmp_minmaxz; + stl->effects->ao_dist = tmp_ao_dist; + stl->effects->ao_samples = tmp_ao_samples; } static void render_scene_to_planar( @@ -958,6 +996,7 @@ static void render_scene_to_planar( EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_PassList *psl = vedata->psl; + EEVEE_StorageList *stl = vedata->stl; float viewinv[4][4]; float persinv[4][4]; @@ -973,8 +1012,11 @@ static void render_scene_to_planar( DRW_framebuffer_clear(false, true, false, NULL, 1.0); /* Avoid using the texture attached to framebuffer when rendering. */ + /* XXX */ GPUTexture *tmp_planar_pool = txl->planar_pool; + GPUTexture *tmp_minmaxz = stl->g_data->minmaxz; txl->planar_pool = e_data.planar_pool_placeholder; + stl->g_data->minmaxz = e_data.planar_minmaxz; DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); @@ -993,6 +1035,11 @@ static void render_scene_to_planar( DRW_draw_pass(psl->depth_pass_clip); DRW_draw_pass(psl->depth_pass_clip_cull); + EEVEE_create_minmax_buffer(vedata, e_data.planar_depth); + + /* Rebind Planar FB */ + DRW_framebuffer_bind(fbl->planarref_fb); + /* Shading pass */ EEVEE_draw_default_passes(psl); DRW_draw_pass(psl->material_pass); @@ -1002,6 +1049,7 @@ static void render_scene_to_planar( /* Restore */ txl->planar_pool = tmp_planar_pool; + stl->g_data->minmaxz = tmp_minmaxz; DRW_viewport_matrix_override_unset(DRW_MAT_PERS); DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV); DRW_viewport_matrix_override_unset(DRW_MAT_VIEW); @@ -1109,7 +1157,7 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) float pos[3]; lightprobe_cell_location_get(egrid, cell_id, pos); - render_scene_to_probe(sldata, psl, pos, prb->clipsta, prb->clipend); + render_scene_to_probe(sldata, vedata, pos, prb->clipsta, prb->clipend); diffuse_filter_probe(sldata, psl, egrid->offset + cell_id); /* Restore */ @@ -1151,7 +1199,7 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) if (ped->need_update) { LightProbe *prb = (LightProbe *)ob->data; - render_scene_to_probe(sldata, psl, ob->obmat[3], prb->clipsta, prb->clipend); + render_scene_to_probe(sldata, vedata, ob->obmat[3], prb->clipsta, prb->clipend); glossy_filter_probe(sldata, psl, i); ped->need_update = false; diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 2f96da1cf4f..0d620fcf8fb 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -346,7 +346,6 @@ typedef struct EEVEE_SceneLayerData { struct GPUFrameBuffer *probe_filter_fb; struct GPUTexture *probe_rt; - struct GPUTexture *probe_depth_rt; struct GPUTexture *probe_pool; struct GPUTexture *irradiance_pool; struct GPUTexture *irradiance_rt; @@ -440,7 +439,7 @@ void EEVEE_lightprobes_free(void); /* eevee_effects.c */ void EEVEE_effects_init(EEVEE_Data *vedata); void EEVEE_effects_cache_init(EEVEE_Data *vedata); -void EEVEE_create_minmax_buffer(EEVEE_Data *vedata); +void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src); void EEVEE_draw_effects(EEVEE_Data *vedata); void EEVEE_effects_free(void); |