diff options
16 files changed, 184 insertions, 245 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(); } diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 7688039d0a8..0ce94b8f1b1 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -112,19 +112,20 @@ static struct GPUTexture *create_hammersley_sample_texture(int samples) static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) { EEVEE_TextureList *txl = vedata->txl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_EffectsInfo *fx = stl->effects; /* XXX TODO OPTIMIZATION: This is a complete waist of texture memory. * Instead of allocating each planar probe for each viewport, * only alloc them once using the biggest viewport resolution. */ - const float *viewport_size = DRW_viewport_size_get(); /* TODO get screen percentage from layer setting */ // const DRWContextState *draw_ctx = DRW_context_state_get(); // ViewLayer *view_layer = draw_ctx->view_layer; - float screen_percentage = 1.0f; + int screen_divider = 1; - int width = max_ii(1, (int)(viewport_size[0] * screen_percentage)); - int height = max_ii(1, (int)(viewport_size[1] * screen_percentage)); + int width = max_ii(1, fx->hiz_size[0] / screen_divider); + int height = max_ii(1, fx->hiz_size[1] / screen_divider); /* Fix case were the pool was allocated width the dummy size (1,1,1). */ if (txl->planar_pool && (num_planar_ref > 0) && @@ -139,12 +140,12 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) if (num_planar_ref > 0) { txl->planar_pool = DRW_texture_create_2d_array(width, height, - max_ii(1, num_planar_ref), + num_planar_ref, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); txl->planar_depth = DRW_texture_create_2d_array( - width, height, max_ii(1, num_planar_ref), GPU_DEPTH_COMPONENT24, 0, NULL); + width, height, num_planar_ref, GPU_DEPTH_COMPONENT24, 0, NULL); } else if (num_planar_ref == 0) { /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still @@ -674,10 +675,12 @@ static void lightbake_planar_ensure_view(EEVEE_PlanarReflection *eplanar, const DRWView *main_view, DRWView **r_planar_view) { - float winmat[4][4], viewmat[4][4]; + float winmat[4][4], viewmat[4][4], persmat[4][4]; DRW_view_viewmat_get(main_view, viewmat, false); /* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */ DRW_view_winmat_get(main_view, winmat, false); + DRW_view_persmat_get(main_view, persmat, false); + /* Invert X to avoid flipping the triangle facing direction. */ winmat[0][0] = -winmat[0][0]; winmat[1][0] = -winmat[1][0]; @@ -729,7 +732,6 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved /* For shading, save max level of the octahedron map */ sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len; - sldata->common_data.prb_lod_planar_max = (float)MAX_PLANAR_LOD_LEVEL; sldata->common_data.prb_irradiance_vis_size = light_cache->vis_res; sldata->common_data.prb_irradiance_smooth = square_f(scene_eval->eevee.gi_irradiance_smoothing); sldata->common_data.prb_num_render_cube = max_ii(1, light_cache->cube_len); @@ -1220,7 +1222,7 @@ static void EEVEE_lightbake_filter_planar(EEVEE_Data *vedata) {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->planar_pool)}); GPU_framebuffer_recursive_downsample( - fbl->planar_downsample_fb, MAX_PLANAR_LOD_LEVEL, &downsample_planar, vedata); + fbl->planar_downsample_fb, MAX_SCREEN_BUFFERS_LOD_LEVEL, &downsample_planar, vedata); DRW_stats_group_end(); } diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 9d74d916265..bc7db4b5df6 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -128,7 +128,7 @@ void EEVEE_material_bind_resources(DRWShadingGroup *shgrp, DRW_shgroup_uniform_float_copy( shgrp, "refractionDepth", (refract_depth) ? *refract_depth : 0.0); if (use_ssrefraction) { - DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->refract_color); + DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->filtered_radiance); } } if (use_alpha_blend) { diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 4e32854dedc..45afee31591 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -161,7 +161,7 @@ BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d) ((v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER) == 0)))) #define MIN_CUBE_LOD_LEVEL 3 -#define MAX_PLANAR_LOD_LEVEL 9 +#define MAX_SCREEN_BUFFERS_LOD_LEVEL 6 /* All the renderpasses that use the GPUMaterial for accumulation */ #define EEVEE_RENDERPASSES_MATERIAL \ @@ -308,6 +308,7 @@ typedef struct EEVEE_PassList { struct DRWPass *sss_blur_ps; struct DRWPass *sss_resolve_ps; struct DRWPass *sss_translucency_ps; + struct DRWPass *color_copy_ps; struct DRWPass *color_downsample_ps; struct DRWPass *color_downsample_cube_ps; struct DRWPass *velocity_object; @@ -320,13 +321,7 @@ typedef struct EEVEE_PassList { struct DRWPass *alpha_checker; /* HiZ */ - struct DRWPass *minz_downlevel_ps; struct DRWPass *maxz_downlevel_ps; - struct DRWPass *minz_downdepth_ps; - struct DRWPass *maxz_downdepth_ps; - struct DRWPass *minz_downdepth_layer_ps; - struct DRWPass *maxz_downdepth_layer_ps; - struct DRWPass *minz_copydepth_ps; struct DRWPass *maxz_copydepth_ps; struct DRWPass *maxz_copydepth_layer_ps; @@ -362,6 +357,7 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *gtao_fb; struct GPUFrameBuffer *gtao_debug_fb; struct GPUFrameBuffer *downsample_fb; + struct GPUFrameBuffer *maxzbuffer_fb; struct GPUFrameBuffer *bloom_blit_fb; struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP]; struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1]; @@ -394,7 +390,6 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *volumetric_integ_fb; struct GPUFrameBuffer *volumetric_accum_fb; struct GPUFrameBuffer *screen_tracing_fb; - struct GPUFrameBuffer *refract_fb; struct GPUFrameBuffer *mist_accum_fb; struct GPUFrameBuffer *material_accum_fb; struct GPUFrameBuffer *renderpass_fb; @@ -412,6 +407,7 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *main_color_fb; struct GPUFrameBuffer *effect_fb; struct GPUFrameBuffer *effect_color_fb; + struct GPUFrameBuffer *radiance_filtered_fb; struct GPUFrameBuffer *double_buffer_fb; struct GPUFrameBuffer *double_buffer_color_fb; struct GPUFrameBuffer *double_buffer_depth_fb; @@ -436,7 +432,6 @@ typedef struct EEVEE_TextureList { struct GPUTexture *ssr_accum; struct GPUTexture *shadow_accum; struct GPUTexture *cryptomatte; - struct GPUTexture *refract_color; struct GPUTexture *taa_history; /* Could not be pool texture because of mipmapping. */ struct GPUTexture *dof_reduced_color; @@ -460,6 +455,7 @@ typedef struct EEVEE_TextureList { struct GPUTexture *planar_depth; struct GPUTexture *maxzbuffer; + struct GPUTexture *filtered_radiance; struct GPUTexture *renderpass; @@ -618,7 +614,7 @@ typedef struct EEVEE_LightProbesInfo { float roughness; float firefly_fac; float lodfactor; - float lod_rt_max, lod_cube_max, lod_planar_max; + float lod_rt_max, lod_cube_max; float visibility_range; float visibility_blur; float intensity_fac; @@ -708,8 +704,9 @@ typedef enum EEVEE_EffectsFlag { EFFECT_REFRACT = (1 << 6), EFFECT_GTAO = (1 << 7), EFFECT_TAA = (1 << 8), - EFFECT_POST_BUFFER = (1 << 9), /* Not really an effect but a feature */ - EFFECT_NORMAL_BUFFER = (1 << 10), /* Not really an effect but a feature */ + EFFECT_POST_BUFFER = (1 << 9), /* Not really an effect but a feature */ + EFFECT_NORMAL_BUFFER = (1 << 10), /* Not really an effect but a feature */ + EFFECT_RADIANCE_BUFFER = (1 << 10), /* Not really an effect but a feature */ EFFECT_SSS = (1 << 11), EFFECT_VELOCITY_BUFFER = (1 << 12), /* Not really an effect but a feature */ EFFECT_TAA_REPROJECT = (1 << 13), /* should be mutually exclusive with EFFECT_TAA */ @@ -817,11 +814,10 @@ typedef struct EEVEE_EffectsInfo { struct GPUTexture *dof_scatter_src_tx; struct GPUTexture *dof_reduce_input_coc_tx; /* Just references to actual textures. */ struct GPUTexture *dof_reduce_input_color_tx; - /* Alpha Checker */ - float color_checker_dark[4]; - float color_checker_light[4]; /* Other */ float prev_persmat[4][4]; + /* Size used by all fullscreen buffers using mipmaps. */ + int hiz_size[2]; /* Lookdev */ int sphere_size; eDRWLevelOfDetail sphere_lod; @@ -859,7 +855,7 @@ typedef struct EEVEE_EffectsInfo { * - sizeof(bool) == sizeof(int) in GLSL so use int in C */ typedef struct EEVEE_CommonUniformBuffer { float prev_persmat[4][4]; /* mat4 */ - float mip_ratio[10][4]; /* vec2[10] */ + float hiz_uv_scale[4]; /* vec4 */ /* Ambient Occlusion */ /* -- 16 byte aligned -- */ float ao_dist, pad1, ao_factor, pad2; /* vec4 */ @@ -899,15 +895,15 @@ typedef struct EEVEE_CommonUniformBuffer { int prb_irradiance_vis_size; /* int */ float prb_irradiance_smooth; /* float */ float prb_lod_cube_max; /* float */ - float prb_lod_planar_max; /* float */ /* Misc */ - int hiz_mip_offset; /* int */ int ray_type; /* int */ float ray_depth; /* float */ float alpha_hash_offset; /* float */ float alpha_hash_scale; /* float */ float pad7; /* float */ float pad8; /* float */ + float pad9; /* float */ + float pad10; /* float */ } EEVEE_CommonUniformBuffer; BLI_STATIC_ASSERT_ALIGN(EEVEE_CommonUniformBuffer, 16) @@ -1201,6 +1197,7 @@ struct GPUShader *EEVEE_shaders_depth_of_field_gather_get(EEVEE_DofGatherPass pa struct GPUShader *EEVEE_shaders_depth_of_field_filter_get(void); struct GPUShader *EEVEE_shaders_depth_of_field_scatter_get(bool is_foreground, bool bokeh_tx); struct GPUShader *EEVEE_shaders_depth_of_field_resolve_get(bool use_bokeh_tx, bool use_hq_gather); +struct GPUShader *EEVEE_shaders_effect_color_copy_sh_get(void); struct GPUShader *EEVEE_shaders_effect_downsample_sh_get(void); struct GPUShader *EEVEE_shaders_effect_downsample_cube_sh_get(void); struct GPUShader *EEVEE_shaders_effect_minz_downlevel_sh_get(void); @@ -1472,8 +1469,8 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, const bool minimal); void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_effects_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_effects_downsample_radiance_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src); void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer); -void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src, int level); void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src, int level); void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index f9e22f5c08d..80a1c9fcbe5 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -42,29 +42,15 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; EEVEE_StorageList *stl = vedata->stl; EEVEE_FramebufferList *fbl = vedata->fbl; - EEVEE_TextureList *txl = vedata->txl; EEVEE_EffectsInfo *effects = stl->effects; const float *viewport_size = DRW_viewport_size_get(); const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - /* Compute pixel size, (shared with contact shadows) */ - copy_v2_v2(common_data->ssr_pixelsize, viewport_size); - invert_v2(common_data->ssr_pixelsize); - if (scene_eval->eevee.flag & SCE_EEVEE_SSR_ENABLED) { const bool use_refraction = (scene_eval->eevee.flag & SCE_EEVEE_SSR_REFRACTION) != 0; - if (use_refraction) { - /* TODO: Opti: Could be shared. */ - DRW_texture_ensure_fullscreen_2d( - &txl->refract_color, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP); - - GPU_framebuffer_ensure_config( - &fbl->refract_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->refract_color)}); - } - const bool is_persp = DRW_view_is_persp_get(NULL); if (effects->ssr_was_persp != is_persp) { effects->ssr_was_persp = is_persp; @@ -117,8 +103,7 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output), GPU_ATTACHMENT_TEXTURE(effects->ssr_pdf_output)}); - /* Enable double buffering to be able to read previous frame color */ - return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_DOUBLE_BUFFER | + return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_RADIANCE_BUFFER | EFFECT_DOUBLE_BUFFER | ((use_refraction) ? EFFECT_REFRACT : 0); } @@ -189,7 +174,7 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth); DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output); DRW_shgroup_uniform_texture_ref(grp, "pdfBuffer", &effects->ssr_pdf_output); - DRW_shgroup_uniform_texture_ref(grp, "prevColorBuffer", &txl->color_double_buffer); + DRW_shgroup_uniform_texture_ref(grp, "prevColorBuffer", &txl->filtered_radiance); DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool); DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); @@ -216,8 +201,7 @@ void EEVEE_refraction_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v EEVEE_EffectsInfo *effects = stl->effects; if ((effects->enabled_effects & EFFECT_REFRACT) != 0) { - GPU_framebuffer_blit(fbl->main_fb, 0, fbl->refract_fb, 0, GPU_COLOR_BIT); - EEVEE_downsample_buffer(vedata, txl->refract_color, 9); + EEVEE_effects_downsample_radiance_buffer(vedata, txl->color); /* Restore */ GPU_framebuffer_bind(fbl->main_fb); @@ -242,7 +226,7 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v GPU_framebuffer_bind(fbl->screen_tracing_fb); DRW_draw_pass(psl->ssr_raytrace); - EEVEE_downsample_buffer(vedata, txl->color_double_buffer, 9); + EEVEE_effects_downsample_radiance_buffer(vedata, txl->color_double_buffer); /* Resolve at fullres */ int samp = (DRW_state_is_image_render()) ? effects->taa_render_sample : diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index a3e9236dc79..74c4803928a 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -103,7 +103,8 @@ static struct { struct GPUShader *minz_copydepth_sh; struct GPUShader *maxz_copydepth_sh; - /* Simple Down-sample */ + /* Simple Down-sample. */ + struct GPUShader *color_copy_sh; struct GPUShader *downsample_sh; struct GPUShader *downsample_cube_sh; @@ -452,10 +453,20 @@ GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void) /** \name Down-sampling * \{ */ +GPUShader *EEVEE_shaders_effect_color_copy_sh_get(void) +{ + if (e_data.color_copy_sh == NULL) { + e_data.color_copy_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_downsample_frag_glsl, e_data.lib, "#define COPY_SRC\n"); + } + return e_data.color_copy_sh; +} + GPUShader *EEVEE_shaders_effect_downsample_sh_get(void) { if (e_data.downsample_sh == NULL) { - e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL); + e_data.downsample_sh = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_downsample_frag_glsl, e_data.lib, NULL); } return e_data.downsample_sh; } @@ -1537,6 +1548,7 @@ void EEVEE_shaders_free(void) MEM_SAFE_FREE(e_data.surface_geom_barycentric); DRW_SHADER_FREE_SAFE(e_data.lookdev_background); DRW_SHADER_FREE_SAFE(e_data.update_noise_sh); + DRW_SHADER_FREE_SAFE(e_data.color_copy_sh); DRW_SHADER_FREE_SAFE(e_data.downsample_sh); DRW_SHADER_FREE_SAFE(e_data.downsample_cube_sh); DRW_SHADER_FREE_SAFE(e_data.minz_downlevel_sh); diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index 473990e1683..0b01b186b1b 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -94,8 +94,7 @@ float search_horizon(vec3 vI, vec2 uv = uv_start + uv_dir * t; float lod = min(MAX_LOD, max(i - noise, 0.0) * aoQuality); - int mip = int(lod) + hizMipOffset; - float depth = textureLod(depth_tx, uv * mipRatio[mip].xy, floor(lod)).r; + float depth = textureLod(depth_tx, uv * hizUvScale.xy, floor(lod)).r; /* Bias depth a bit to avoid self shadowing issues. */ const float bias = 2.0 * 2.4e-7; diff --git a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl index a6c9eebaff2..24de4520207 100644 --- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl @@ -2,7 +2,7 @@ layout(std140) uniform common_block { mat4 pastViewProjectionMatrix; - vec2 mipRatio[10]; /* To correct mip level texel misalignment */ + vec4 hizUvScale; /* To correct mip level texel misalignment */ /* Ambient Occlusion */ vec4 aoParameters[2]; /* Volumetric */ @@ -37,15 +37,15 @@ layout(std140) uniform common_block int prbIrradianceVisSize; float prbIrradianceSmooth; float prbLodCubeMax; - float prbLodPlanarMax; /* Misc*/ - int hizMipOffset; int rayType; float rayDepth; float alphaHashOffset; float alphaHashScale; + float pad6; float pad7; float pad8; + float pad9; }; /* rayType (keep in sync with ray_type) */ @@ -69,9 +69,3 @@ layout(std140) uniform common_block #define ssrQuality ssrParameters.x #define ssrThickness ssrParameters.y #define ssrPixelSize ssrParameters.zw - -vec2 mip_ratio_interp(float mip) -{ - float low_mip = floor(mip); - return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip); -} diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl index 88d83cd913a..3ad3c90d27a 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl @@ -62,12 +62,6 @@ const vec2 quad_offsets[4] = vec2[4]( #define dof_coc_from_zdepth(d) calculate_coc(linear_depth(d)) -vec4 safe_color(vec4 c) -{ - /* Clamp to avoid black square artifacts if a pixel goes NaN. */ - return clamp(c, vec4(0.0), vec4(1e20)); /* 1e20 arbitrary. */ -} - float dof_hdr_color_weight(vec4 color) { /* From UE4. Very fast "luma" weighting. */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl index a4637b9df91..5bf850fe229 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl @@ -1,5 +1,9 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + /** - * Simple down-sample shader. Takes the average of the 4 texels of lower mip. + * Simple down-sample shader. + * Do a gaussian filter using 4 bilinear texture samples. */ uniform sampler2D source; @@ -14,24 +18,25 @@ float brightness(vec3 c) void main() { -#if 0 - /* Reconstructing Target uvs like this avoid missing pixels if NPO2 */ - vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0)); + vec2 texel_size = 1.0 / vec2(textureSize(source, 0)); + vec2 uvs = gl_FragCoord.xy * texel_size; +#ifdef COPY_SRC FragColor = textureLod(source, uvs, 0.0); + FragColor = safe_color(FragColor); + + /* Clamped brightness. */ + float luma = max(1e-8, brightness(FragColor.rgb)); + FragColor *= 1.0 - max(0.0, luma - fireflyFactor) / luma; + #else - vec2 texel_size = 1.0 / vec2(textureSize(source, 0)); - vec2 uvs = gl_FragCoord.xy * 2.0 * texel_size; vec4 ofs = texel_size.xyxy * vec4(0.75, 0.75, -0.75, -0.75); + uvs *= 2.0; FragColor = textureLod(source, uvs + ofs.xy, 0.0); FragColor += textureLod(source, uvs + ofs.xw, 0.0); FragColor += textureLod(source, uvs + ofs.zy, 0.0); FragColor += textureLod(source, uvs + ofs.zw, 0.0); FragColor *= 0.25; - - /* Clamped brightness. */ - float luma = max(1e-8, brightness(FragColor.rgb)); - FragColor *= 1.0 - max(0.0, luma - fireflyFactor) / luma; #endif } diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl index b99037b1e80..ccb65d2e5a6 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl @@ -2,6 +2,9 @@ * Shader that down-sample depth buffer, * saving min and max value of each texel in the above mipmaps. * Adapted from http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/ + * + * Major simplification has been made since we pad the buffer to always be bigger than input to + * avoid mipmapping misalignement. */ #ifdef LAYERED @@ -12,10 +15,10 @@ uniform sampler2D depthBuffer; #endif #ifdef LAYERED -# define sampleLowerMip(t) texelFetch(depthBuffer, ivec3(t, depthLayer), 0).r +# define sampleLowerMip(t) texture(depthBuffer, vec3(t, depthLayer)).r # define gatherLowerMip(t) textureGather(depthBuffer, vec3(t, depthLayer)) #else -# define sampleLowerMip(t) texelFetch(depthBuffer, t, 0).r +# define sampleLowerMip(t) texture(depthBuffer, t).r # define gatherLowerMip(t) textureGather(depthBuffer, t) #endif @@ -37,54 +40,27 @@ out vec4 fragColor; void main() { - ivec2 texelPos = ivec2(gl_FragCoord.xy); - ivec2 mipsize = textureSize(depthBuffer, 0).xy; - -#ifndef COPY_DEPTH - texelPos *= 2; -#endif + vec2 texel = gl_FragCoord.xy; + vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0).xy); #ifdef COPY_DEPTH - float val = sampleLowerMip(texelPos); + vec2 uv = texel * texel_size; + + float val = sampleLowerMip(uv); #else + vec2 uv = texel * 2.0 * texel_size; + vec4 samp; # ifdef GPU_ARB_texture_gather - /* + 1.0 to gather at the center of target 4 texels. */ - samp = gatherLowerMip((vec2(texelPos) + 1.0) / vec2(mipsize)); + samp = gatherLowerMip(uv); # else - samp.x = sampleLowerMip(texelPos); - samp.y = sampleLowerMip(texelPos + ivec2(1, 0)); - samp.z = sampleLowerMip(texelPos + ivec2(1, 1)); - samp.w = sampleLowerMip(texelPos + ivec2(0, 1)); + samp.x = sampleLowerMip(uv + vec2(-0.5, -0.5) * texel_size); + samp.y = sampleLowerMip(uv + vec2(-0.5, 0.5) * texel_size); + samp.z = sampleLowerMip(uv + vec2(0.5, -0.5) * texel_size); + samp.w = sampleLowerMip(uv + vec2(0.5, 0.5) * texel_size); # endif float val = minmax4(samp.x, samp.y, samp.z, samp.w); - - /* if we are reducing an odd-width texture then fetch the edge texels */ - if (((mipsize.x & 1) != 0) && (texelPos.x == mipsize.x - 3)) { - /* if both edges are odd, fetch the top-left corner texel */ - if (((mipsize.y & 1) != 0) && (texelPos.y == mipsize.y - 3)) { - samp.x = sampleLowerMip(texelPos + ivec2(2, 2)); - val = minmax2(val, samp.x); - } -# ifdef GPU_ARB_texture_gather - samp = gatherLowerMip((vec2(texelPos) + vec2(2.0, 1.0)) / vec2(mipsize)); -# else - samp.y = sampleLowerMip(texelPos + ivec2(2, 0)); - samp.z = sampleLowerMip(texelPos + ivec2(2, 1)); -# endif - val = minmax3(val, samp.y, samp.z); - } - /* if we are reducing an odd-height texture then fetch the edge texels */ - if (((mipsize.y & 1) != 0) && (texelPos.y == mipsize.y - 3)) { -# ifdef GPU_ARB_texture_gather - samp = gatherLowerMip((vec2(texelPos) + vec2(1.0, 2.0)) / vec2(mipsize)); -# else - samp.x = sampleLowerMip(texelPos + ivec2(0, 2)); - samp.y = sampleLowerMip(texelPos + ivec2(1, 2)); -# endif - val = minmax3(val, samp.x, samp.y); - } #endif #if defined(GPU_INTEL) || defined(GPU_ATI) diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl index ecff28dcd38..f2117d8ee67 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -104,6 +104,11 @@ void do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 vP, float a2, vec4 rand) pdfData = min(1024e32, pdf_ggx_reflect(NH, a2)); /* Theoretical limit of 16bit float */ + /* TODO(fclem) This bias should use depth precision and the dot product between + * ray direction and geom normal. */ + float rays_bias = 0.005; + vP = vP + vNg * rays_bias; + vec3 hit_pos = raycast(-1, vP, R * 1e16, ssrThickness, rand.y, ssrQuality, a2, true); hitData = encode_hit_data(hit_pos.xy, (hit_pos.z > 0.0), false); @@ -325,10 +330,10 @@ vec3 get_hit_vector(vec3 hit_pos, vec3 get_scene_color(vec2 ref_uvs, float mip, float planar_index, bool is_planar) { if (is_planar) { - return textureLod(probePlanars, vec3(ref_uvs, planar_index), min(mip, prbLodPlanarMax)).rgb; + return textureLod(probePlanars, vec3(ref_uvs, planar_index), mip).rgb; } else { - return textureLod(prevColorBuffer, ref_uvs, mip).rgb; + return textureLod(prevColorBuffer, ref_uvs * hizUvScaleBias.xy + hizUvScaleBias.zw, mip).rgb; } } @@ -403,12 +408,6 @@ vec4 get_ssr_samples(vec4 hit_pdf, vec4 mip = log2(cone_footprint * max_v2(vec2(textureSize(depthBuffer, 0)))); mip = clamp(mip, 0.0, MAX_MIP); - /* Correct UVs for mipmaping mis-alignment */ - hit_co[0].xy *= mip_ratio_interp(mip.x); - hit_co[0].zw *= mip_ratio_interp(mip.y); - hit_co[1].xy *= mip_ratio_interp(mip.z); - hit_co[1].zw *= mip_ratio_interp(mip.w); - /* Slide 54 */ vec4 bsdf; bsdf.x = bsdf_ggx(N, hit_pos[0], V, roughnessSquared); diff --git a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl index 28947e971d2..165aed2a46f 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl @@ -10,12 +10,6 @@ uniform mat4 prevViewProjectionMatrix; out vec4 FragColor; -vec4 safe_color(vec4 c) -{ - /* Clamp to avoid black square artifacts if a pixel goes NaN. */ - return clamp(c, vec4(0.0), vec4(1e20)); /* 1e20 arbitrary. */ -} - #ifdef USE_REPROJECTION /** diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index aebd1c3aef3..fbc13d832bd 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -16,10 +16,7 @@ float sample_depth(vec2 uv, int index, float lod) } else { #endif - lod = clamp(floor(lod), 0.0, 8.0); - /* Correct UVs for mipmaping mis-alignment */ - uv *= mipRatio[int(lod) + hizMipOffset]; - return textureLod(maxzBuffer, uv, lod).r; + return textureLod(maxzBuffer, uv * hizUvScale.xy, floor(lod)).r; #ifdef PLANAR_PROBE_RAYTRACE } #endif @@ -37,10 +34,10 @@ vec4 sample_depth_grouped(vec4 uv1, vec4 uv2, int index, float lod) } else { #endif - depths.x = textureLod(maxzBuffer, uv1.xy, lod).r; - depths.y = textureLod(maxzBuffer, uv1.zw, lod).r; - depths.z = textureLod(maxzBuffer, uv2.xy, lod).r; - depths.w = textureLod(maxzBuffer, uv2.zw, lod).r; + depths.x = textureLod(maxzBuffer, uv1.xy * hizUvScale.xy, lod).r; + depths.y = textureLod(maxzBuffer, uv1.zw * hizUvScale.xy, lod).r; + depths.z = textureLod(maxzBuffer, uv2.xy * hizUvScale.xy, lod).r; + depths.w = textureLod(maxzBuffer, uv2.zw * hizUvScale.xy, lod).r; #ifdef PLANAR_PROBE_RAYTRACE } #endif @@ -131,9 +128,6 @@ void prepare_raycast(vec3 ray_origin, #endif ss_ray = ss_start * m.xyyy + 0.5; ss_step *= m.xyyy; - - /* take the center of the texel. */ - // ss_ray.xy += sign(ss_ray.xy) * m * ssrPixelSize * (1.0 + hizMipOffset); } /* See times_and_deltas. */ @@ -175,9 +169,7 @@ vec3 raycast(int index, bool hit = false; float iter; for (iter = 1.0; !hit && (ray_time < max_time) && (iter < MAX_STEP); iter++) { - /* Minimum stride of 2 because we are using half res minmax zbuffer. */ - /* WORKAROUND: Factor is a bit higher than 2 to avoid some banding. To investigate. */ - float stride = max(1.0, iter * trace_quality) * (2.0 + 0.05); + float stride = max(1.01, iter * trace_quality); float lod = log2(stride * 0.5 * trace_quality) * lod_fac; ray_time += stride; diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl index 15c28efe622..907a9cf17f8 100644 --- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl @@ -68,10 +68,7 @@ vec4 screen_space_refraction(vec3 vP, vec3 N, vec3 V, float ior, float roughness vec2 texture_size = vec2(textureSize(colorBuffer, 0).xy); float mip = clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, 9.0); - /* Correct UVs for mipmaping mis-alignment */ - hit_uvs *= mip_ratio_interp(mip); - - vec3 spec = textureLod(colorBuffer, hit_uvs, mip).xyz; + vec3 spec = textureLod(colorBuffer, hit_uvs * hizUvScale.xy, mip).xyz; float mask = screen_border_mask(hit_uvs); return vec4(spec, mask); diff --git a/source/blender/draw/intern/shaders/common_math_lib.glsl b/source/blender/draw/intern/shaders/common_math_lib.glsl index d02fd27f35f..0344b977139 100644 --- a/source/blender/draw/intern/shaders/common_math_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_lib.glsl @@ -128,6 +128,12 @@ vec3 normalize_len(vec3 v, out float len) return v / len; } +vec4 safe_color(vec4 c) +{ + /* Clamp to avoid black square artifacts if a pixel goes NaN. */ + return clamp(c, vec4(0.0), vec4(1e20)); /* 1e20 arbitrary. */ +} + /** \} */ /* ---------------------------------------------------------------------- */ |