Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2021-03-04 13:59:49 +0300
committerClément Foucault <foucault.clem@gmail.com>2021-03-08 19:25:16 +0300
commitba75ea8012084aa84ba8c9ac088b88a8dcf4fb21 (patch)
tree32610751177961885185afee8f4c4773ccda4ced /source/blender/draw/engines/eevee/eevee_effects.c
parent6afe2d373a00a49a7a51cafec50d03ada0fe0743 (diff)
EEVEE: Use Fullscreen maxZBuffer instead of halfres
This removes the need for per mipmap scalling factor and trilinear interpolation issues. We pad the texture so that all mipmaps have pixels in the next mip. This simplifies the downsampling shader too. This also change the SSR radiance buffer as well in the same fashion.
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_effects.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c176
1 files changed, 82 insertions, 94 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 18d3e453c5d..25aedd2cdde 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -44,7 +44,7 @@ static struct {
#define SETUP_BUFFER(tex, fb, fb_color) \
{ \
eGPUTextureFormat format = (DRW_state_is_scene_render()) ? GPU_RGBA32F : GPU_RGBA16F; \
- DRW_texture_ensure_fullscreen_2d(&tex, format, DRW_TEX_FILTER | DRW_TEX_MIPMAP); \
+ DRW_texture_ensure_fullscreen_2d(&tex, format, DRW_TEX_FILTER); \
GPU_framebuffer_ensure_config(&fb, \
{ \
GPU_ATTACHMENT_TEXTURE(dtxl->depth), \
@@ -117,20 +117,27 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
/**
* MinMax Pyramid
*/
- const bool half_res_hiz = true;
- int size[2], div;
- common_data->hiz_mip_offset = (half_res_hiz) ? 1 : 0;
- div = (half_res_hiz) ? 2 : 1;
- size[0] = max_ii(size_fs[0] / div, 1);
- size[1] = max_ii(size_fs[1] / div, 1);
+ int div = 1 << MAX_SCREEN_BUFFERS_LOD_LEVEL;
+ effects->hiz_size[0] = divide_ceil_u(size_fs[0], div) * div;
+ effects->hiz_size[1] = divide_ceil_u(size_fs[1], div) * div;
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- /* Intel gpu seems to have problem rendering to only depth format */
- DRW_texture_ensure_2d(&txl->maxzbuffer, size[0], size[1], GPU_R32F, DRW_TEX_MIPMAP);
+ /* Intel gpu seems to have problem rendering to only depth hiz_format */
+ DRW_texture_ensure_2d(&txl->maxzbuffer, UNPACK2(effects->hiz_size), GPU_R32F, DRW_TEX_MIPMAP);
+ GPU_framebuffer_ensure_config(&fbl->maxzbuffer_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->maxzbuffer),
+ });
}
else {
DRW_texture_ensure_2d(
- &txl->maxzbuffer, size[0], size[1], GPU_DEPTH_COMPONENT24, DRW_TEX_MIPMAP);
+ &txl->maxzbuffer, UNPACK2(effects->hiz_size), GPU_DEPTH_COMPONENT24, DRW_TEX_MIPMAP);
+ GPU_framebuffer_ensure_config(&fbl->maxzbuffer_fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(txl->maxzbuffer),
+ GPU_ATTACHMENT_NONE,
+ });
}
if (fbl->downsample_fb == NULL) {
@@ -138,13 +145,35 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
}
/**
- * Compute Mipmap texel alignment.
+ * Compute hiZ texel alignment.
+ */
+ common_data->hiz_uv_scale[0] = viewport_size[0] / effects->hiz_size[0];
+ common_data->hiz_uv_scale[1] = viewport_size[1] / effects->hiz_size[1];
+ common_data->hiz_uv_scale[2] = 1.0f / effects->hiz_size[0];
+ common_data->hiz_uv_scale[3] = 1.0f / effects->hiz_size[1];
+
+ /* Compute pixel size. Size is multiplied by 2 because it is applied in NDC [-1..1] range. */
+ sldata->common_data.ssr_pixelsize[0] = 2.0f / size_fs[0];
+ sldata->common_data.ssr_pixelsize[1] = 2.0f / size_fs[1];
+
+ /**
+ * Color buffer with correct downsampling alignment.
+ * Used for SSReflections & SSRefractions.
*/
- for (int i = 0; i < 10; i++) {
- int mip_size[3];
- GPU_texture_get_mipmap_size(txl->color, i, mip_size);
- common_data->mip_ratio[i][0] = viewport_size[0] / (mip_size[0] * powf(2.0f, i));
- common_data->mip_ratio[i][1] = viewport_size[1] / (mip_size[1] * powf(2.0f, i));
+ if ((effects->enabled_effects & EFFECT_RADIANCE_BUFFER) != 0) {
+ DRW_texture_ensure_2d(&txl->filtered_radiance,
+ UNPACK2(effects->hiz_size),
+ GPU_R11F_G11F_B10F,
+ DRW_TEX_FILTER | DRW_TEX_MIPMAP);
+
+ GPU_framebuffer_ensure_config(&fbl->radiance_filtered_fb,
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->filtered_radiance),
+ });
+ }
+ else {
+ txl->filtered_radiance = NULL;
}
/**
@@ -210,7 +239,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- DRWState downsample_write = DRW_STATE_WRITE_DEPTH;
+ DRWState downsample_write = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
DRWShadingGroup *grp;
/* Intel gpu seems to have problem rendering to only depth format.
@@ -221,12 +250,17 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
- {
+ if (effects->enabled_effects & EFFECT_RADIANCE_BUFFER) {
+ DRW_PASS_CREATE(psl->color_copy_ps, DRW_STATE_WRITE_COLOR);
+ grp = DRW_shgroup_create(EEVEE_shaders_effect_color_copy_sh_get(), psl->color_copy_ps);
+ DRW_shgroup_uniform_texture_ref_ex(grp, "source", &e_data.color_src, GPU_SAMPLER_DEFAULT);
+ DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
+
DRW_PASS_CREATE(psl->color_downsample_ps, DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(EEVEE_shaders_effect_downsample_sh_get(), psl->color_downsample_ps);
- DRW_shgroup_uniform_texture_ref(grp, "source", &e_data.color_src);
- DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
- DRW_shgroup_call(grp, quad, NULL);
+ DRW_shgroup_uniform_texture_ex(grp, "source", txl->filtered_radiance, GPU_SAMPLER_FILTER);
+ DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
{
@@ -241,34 +275,21 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
/* Perform min/max down-sample. */
- DRW_PASS_CREATE(psl->maxz_downlevel_ps, downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ DRW_PASS_CREATE(psl->maxz_downlevel_ps, downsample_write);
grp = DRW_shgroup_create(EEVEE_shaders_effect_maxz_downlevel_sh_get(), psl->maxz_downlevel_ps);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &txl->maxzbuffer);
- DRW_shgroup_call(grp, quad, NULL);
-
- /* Copy depth buffer to halfres top level of HiZ */
-
- DRW_PASS_CREATE(psl->maxz_downdepth_ps, downsample_write | DRW_STATE_DEPTH_ALWAYS);
- grp = DRW_shgroup_create(EEVEE_shaders_effect_maxz_downdepth_sh_get(), psl->maxz_downdepth_ps);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
- DRW_shgroup_call(grp, quad, NULL);
-
- DRW_PASS_CREATE(psl->maxz_downdepth_layer_ps, downsample_write | DRW_STATE_DEPTH_ALWAYS);
- grp = DRW_shgroup_create(EEVEE_shaders_effect_maxz_downdepth_layer_sh_get(),
- psl->maxz_downdepth_layer_ps);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
- DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
+ DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &txl->maxzbuffer, GPU_SAMPLER_DEFAULT);
DRW_shgroup_call(grp, quad, NULL);
- DRW_PASS_CREATE(psl->maxz_copydepth_ps, downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ /* Copy depth buffer to top level of HiZ */
+ DRW_PASS_CREATE(psl->maxz_copydepth_ps, downsample_write);
grp = DRW_shgroup_create(EEVEE_shaders_effect_maxz_copydepth_sh_get(), psl->maxz_copydepth_ps);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
+ DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &e_data.depth_src, GPU_SAMPLER_DEFAULT);
DRW_shgroup_call(grp, quad, NULL);
- DRW_PASS_CREATE(psl->maxz_copydepth_layer_ps, downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ DRW_PASS_CREATE(psl->maxz_copydepth_layer_ps, downsample_write);
grp = DRW_shgroup_create(EEVEE_shaders_effect_maxz_copydepth_layer_sh_get(),
psl->maxz_copydepth_layer_ps);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
+ DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &e_data.depth_src, GPU_SAMPLER_DEFAULT);
DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
DRW_shgroup_call(grp, quad, NULL);
}
@@ -331,12 +352,6 @@ static void max_downsample_cb(void *vedata, int UNUSED(level))
DRW_draw_pass(psl->maxz_downlevel_ps);
}
-static void simple_downsample_cb(void *vedata, int UNUSED(level))
-{
- EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
- DRW_draw_pass(psl->color_downsample_ps);
-}
-
static void simple_downsample_cube_cb(void *vedata, int level)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
@@ -348,58 +363,22 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int l
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_FramebufferList *fbl = vedata->fbl;
- EEVEE_TextureList *txl = vedata->txl;
e_data.depth_src = depth_src;
e_data.depth_src_layer = layer;
-#if 0 /* Not required for now */
- DRW_stats_group_start("Min buffer");
- /* Copy depth buffer to min texture top level */
- GPU_framebuffer_texture_attach(fbl->downsample_fb, stl->g_data->minzbuffer, 0, 0);
- GPU_framebuffer_bind(fbl->downsample_fb);
- if (layer >= 0) {
- DRW_draw_pass(psl->minz_downdepth_layer_ps);
- }
- else {
- DRW_draw_pass(psl->minz_downdepth_ps);
- }
- GPU_framebuffer_texture_detach(stl->g_data->minzbuffer);
-
- /* Create lower levels */
- GPU_framebuffer_recursive_downsample(
- fbl->downsample_fb, stl->g_data->minzbuffer, 8, &min_downsample_cb, vedata);
- DRW_stats_group_end();
-#endif
- int minmax_size[3], depth_size[3];
- GPU_texture_get_mipmap_size(depth_src, 0, depth_size);
- GPU_texture_get_mipmap_size(txl->maxzbuffer, 0, minmax_size);
- bool is_full_res_minmaxz = equals_v2v2_int(minmax_size, depth_size);
-
DRW_stats_group_start("Max buffer");
/* Copy depth buffer to max texture top level */
- GPU_framebuffer_texture_attach(fbl->downsample_fb, txl->maxzbuffer, 0, 0);
- GPU_framebuffer_bind(fbl->downsample_fb);
+ GPU_framebuffer_bind(fbl->maxzbuffer_fb);
if (layer >= 0) {
- if (is_full_res_minmaxz) {
- DRW_draw_pass(psl->maxz_copydepth_layer_ps);
- }
- else {
- DRW_draw_pass(psl->maxz_downdepth_layer_ps);
- }
+ DRW_draw_pass(psl->maxz_copydepth_layer_ps);
}
else {
- if (is_full_res_minmaxz) {
- DRW_draw_pass(psl->maxz_copydepth_ps);
- }
- else {
- DRW_draw_pass(psl->maxz_downdepth_ps);
- }
+ DRW_draw_pass(psl->maxz_copydepth_ps);
}
-
/* Create lower levels */
- GPU_framebuffer_recursive_downsample(fbl->downsample_fb, 8, &max_downsample_cb, vedata);
- GPU_framebuffer_texture_detach(fbl->downsample_fb, txl->maxzbuffer);
+ GPU_framebuffer_recursive_downsample(
+ fbl->maxzbuffer_fb, MAX_SCREEN_BUFFERS_LOD_LEVEL, &max_downsample_cb, vedata);
DRW_stats_group_end();
/* Restore */
@@ -412,19 +391,28 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int l
}
}
+static void downsample_radiance_cb(void *vedata, int UNUSED(level))
+{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ DRW_draw_pass(psl->color_downsample_ps);
+}
+
/**
* Simple down-sampling algorithm. Reconstruct mip chain up to mip level.
*/
-void EEVEE_downsample_buffer(EEVEE_Data *vedata, GPUTexture *texture_src, int level)
+void EEVEE_effects_downsample_radiance_buffer(EEVEE_Data *vedata, GPUTexture *texture_src)
{
+ EEVEE_PassList *psl = vedata->psl;
EEVEE_FramebufferList *fbl = vedata->fbl;
+
e_data.color_src = texture_src;
+ DRW_stats_group_start("Downsample Radiance");
- /* Create lower levels */
- DRW_stats_group_start("Downsample buffer");
- GPU_framebuffer_texture_attach(fbl->downsample_fb, texture_src, 0, 0);
- GPU_framebuffer_recursive_downsample(fbl->downsample_fb, level, &simple_downsample_cb, vedata);
- GPU_framebuffer_texture_detach(fbl->downsample_fb, texture_src);
+ GPU_framebuffer_bind(fbl->radiance_filtered_fb);
+ DRW_draw_pass(psl->color_copy_ps);
+
+ GPU_framebuffer_recursive_downsample(
+ fbl->radiance_filtered_fb, MAX_SCREEN_BUFFERS_LOD_LEVEL, &downsample_radiance_cb, vedata);
DRW_stats_group_end();
}