From 4ac8f2bc527923f5491d64c3fb007d43dbc8a7ba Mon Sep 17 00:00:00 2001 From: e2002e Date: Wed, 14 Sep 2022 22:14:00 +0200 Subject: [PATCH 1/2] patched with ssgi, see https://n0451.gumroad.com/l/PgyXc --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- .../startup/bl_ui/properties_render.py | 39 +++++- .../blenloader/intern/versioning_280.c | 51 +++++++ .../blenloader/intern/versioning_290.c | 32 +++++ source/blender/draw/CMakeLists.txt | 5 + .../draw/engines/eevee/eevee_effects.c | 2 +- .../draw/engines/eevee/eevee_private.h | 43 +++++- .../engines/eevee/eevee_screen_raytrace.c | 130 +++++++++++++++++- .../draw/engines/eevee/eevee_shaders.c | 58 ++++++++ .../eevee/shaders/closure_eval_lib.glsl | 3 +- .../shaders/closure_eval_translucent_lib.glsl | 2 + .../eevee/shaders/closure_type_lib.glsl | 41 ++++-- .../eevee/shaders/common_uniforms_lib.glsl | 22 +++ .../eevee/shaders/effect_reflection_lib.glsl | 29 ++++ .../effect_reflection_resolve_frag.glsl | 5 + .../shaders/effect_reflection_trace_frag.glsl | 4 + .../engines/eevee/shaders/lightprobe_lib.glsl | 56 ++++++++ .../engines/eevee/shaders/surface_frag.glsl | 9 +- .../engines/eevee/shaders/surface_lib.glsl | 2 +- .../material/gpu_shader_material_diffuse.glsl | 4 +- .../gpu_shader_material_eevee_specular.glsl | 2 +- .../material/gpu_shader_material_glass.glsl | 2 +- .../material/gpu_shader_material_glossy.glsl | 2 +- .../gpu_shader_material_principled.glsl | 5 +- ...shader_material_subsurface_scattering.glsl | 2 +- .../gpu_shader_material_translucent.glsl | 2 +- source/blender/makesdna/DNA_scene_defaults.h | 21 +++ source/blender/makesdna/DNA_scene_types.h | 24 +++- source/tools | 2 +- 31 files changed, 569 insertions(+), 36 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 6178bad247c6..7be7aff5a18c 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 6178bad247c69c9c4e1a98c5f35765752341b3ae +Subproject commit 7be7aff5a18c550465b3f7634539ed4168af7c51 diff --git a/release/scripts/addons b/release/scripts/addons index f6107e2fd9a9..d01818a74be4 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit f6107e2fd9a92b55ac110c7db941e287e2f6604a +Subproject commit d01818a74be4103a04069ffc27dd10b4ff14ff56 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 164676482825..95107484d076 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 16467648282500cc229c271f62201ef897f2c2c3 +Subproject commit 95107484d076bc965239942e857c83433bfa86d7 diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index d8d68c7efc89..72ce2502fa0b 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -417,7 +417,7 @@ def draw(self, context): class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel): - bl_label = "Screen Space Reflections" + bl_label = "Screen Space Ray Tracing 1.15 b" bl_options = {'DEFAULT_CLOSED'} COMPAT_ENGINES = {'BLENDER_EEVEE'} @@ -440,13 +440,46 @@ def draw(self, context): col = layout.column() col.active = props.use_ssr col.prop(props, "use_ssr_refraction", text="Refraction") - col.prop(props, "use_ssr_halfres") + #col.prop(props, "use_ssr_halfres") + col.prop(props, "ssr_border_fade") + + col.label(text="Specular:", text_ctxt="", translate=False, icon='NONE', icon_value=0) + col.prop(props, "ssr_quality") col.prop(props, "ssr_max_roughness") col.prop(props, "ssr_thickness") - col.prop(props, "ssr_border_fade") col.prop(props, "ssr_firefly_fac") + col.label(text="Diffuse:", text_ctxt="", translate=False, icon='NONE', icon_value=0) + col.prop(props, "ssr_diffuse_intensity") + col.prop(props, "ssr_diffuse_quality") + col.prop(props, "ssr_diffuse_thickness") + col.prop(props, "ssr_diffuse_resolve_bias") + col.prop(props, "ssr_diffuse_clamp") + col.prop(props, "ssr_diffuse_ao") + col.prop(props, "ssr_diffuse_ao_limit") + + col.label(text="Probe Tracing(WIP):", text_ctxt="", translate=False, icon='NONE', icon_value=0) + col.prop(props, "ssr_diffuse_probe_trace") + col.prop(props, "ssr_diffuse_probe_intensity") + col.prop(props, "ssr_diffuse_probe_clamp") + + col.label(text="Filter:", text_ctxt="", translate=False, icon='NONE', icon_value=0) + col.prop(props, "ssr_diffuse_filter") + col.prop(props, "ssr_diffuse_fsamples") + col.prop(props, "ssr_diffuse_fsize") + col.prop(props, "ssr_diffuse_fnweight") + col.prop(props, "ssr_diffuse_fdweight") + col.prop(props, "ssr_diffuse_faoweight") + + #col.label(text="Debug:", text_ctxt="", translate=False, icon='NONE', icon_value=0) + #col.prop(props, "ssr_diffuse_debug_a") + #col.prop(props, "ssr_diffuse_debug_b") + #col.prop(props, "ssr_diffuse_debug_c") + #col.prop(props, "ssr_diffuse_debug_d") + + #col.prop(props, "ssr_diffuse_versioning") + class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel): bl_label = "Shadows" diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 66087d31c192..0d93cc25a8c0 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -2240,6 +2240,32 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) scene->eevee.ssr_border_fade = 0.075f; scene->eevee.ssr_firefly_fac = 10.0f; + scene->eevee.ssr_diffuse_versioning = 1.15f; + + scene->eevee.ssr_diffuse_intensity = 1.0f; + scene->eevee.ssr_diffuse_thickness = 1.0f; + scene->eevee.ssr_diffuse_resolve_bias = 0.1f; + scene->eevee.ssr_diffuse_quality = 0.25f; + scene->eevee.ssr_diffuse_clamp = 1.0f; + scene->eevee.ssr_diffuse_ao = 1.0f; + scene->eevee.ssr_diffuse_ao_limit = 0.5f; + + scene->eevee.ssr_diffuse_probe_trace = 0; + scene->eevee.ssr_diffuse_probe_intensity = 1.0f; + scene->eevee.ssr_diffuse_probe_clamp = 1.0f; + + scene->eevee.ssr_diffuse_filter = 1.0f; + scene->eevee.ssr_diffuse_fsize = 32.0f; + scene->eevee.ssr_diffuse_fsamples = 1; + scene->eevee.ssr_diffuse_fnweight = 1.0f; + scene->eevee.ssr_diffuse_fdweight = 1.0f; + scene->eevee.ssr_diffuse_faoweight = 0.75f; + + scene->eevee.ssr_diffuse_debug_a = 1.0f; + scene->eevee.ssr_diffuse_debug_b = 1.0f; + scene->eevee.ssr_diffuse_debug_c = 1.0f; + scene->eevee.ssr_diffuse_debug_d = 1.0f; + scene->eevee.volumetric_start = 0.1f; scene->eevee.volumetric_end = 100.0f; scene->eevee.volumetric_tile_size = 8; @@ -2360,6 +2386,31 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) EEVEE_GET_FLOAT(props, ssr_border_fade); EEVEE_GET_FLOAT(props, ssr_firefly_fac); + EEVEE_GET_FLOAT(props, ssr_diffuse_versioning); + + EEVEE_GET_FLOAT(props, ssr_diffuse_intensity); + EEVEE_GET_FLOAT(props, ssr_diffuse_thickness); + EEVEE_GET_FLOAT(props, ssr_diffuse_resolve_bias); + EEVEE_GET_FLOAT(props, ssr_diffuse_quality); + EEVEE_GET_FLOAT(props, ssr_diffuse_clamp); + EEVEE_GET_FLOAT(props, ssr_diffuse_ao); + + EEVEE_GET_INT(props, ssr_diffuse_probe_trace); + EEVEE_GET_FLOAT(props, ssr_diffuse_probe_intensity); + EEVEE_GET_FLOAT(props, ssr_diffuse_probe_clamp); + + EEVEE_GET_FLOAT(props, ssr_diffuse_filter); + EEVEE_GET_FLOAT(props, ssr_diffuse_fsize); + EEVEE_GET_INT(props, ssr_diffuse_fsamples); + EEVEE_GET_FLOAT(props, ssr_diffuse_fnweight); + EEVEE_GET_FLOAT(props, ssr_diffuse_fdweight); + EEVEE_GET_FLOAT(props, ssr_diffuse_faoweight); + + EEVEE_GET_FLOAT(props, ssr_diffuse_debug_a); + EEVEE_GET_FLOAT(props, ssr_diffuse_debug_b); + EEVEE_GET_FLOAT(props, ssr_diffuse_debug_c); + EEVEE_GET_FLOAT(props, ssr_diffuse_debug_d); + EEVEE_GET_FLOAT(props, volumetric_start); EEVEE_GET_FLOAT(props, volumetric_end); EEVEE_GET_INT(props, volumetric_tile_size); diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 888bd2440077..f90777ad7e37 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -1780,6 +1780,38 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) FOREACH_NODETREE_END; } + /* using float property check for versioning since can't rely on blender version*/ + if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "diffuse_intensity")) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + if (scene->eevee.ssr_diffuse_versioning < 1.15f) { + scene->eevee.ssr_diffuse_versioning = 1.15f; + + scene->eevee.ssr_diffuse_intensity = 1.0f; + scene->eevee.ssr_diffuse_thickness = 1.0f; + scene->eevee.ssr_diffuse_resolve_bias = 0.1f; + scene->eevee.ssr_diffuse_quality = 0.25f; + scene->eevee.ssr_diffuse_clamp = 1.0f; + scene->eevee.ssr_diffuse_ao = 1.0f; + scene->eevee.ssr_diffuse_ao_limit = 0.5f; + + scene->eevee.ssr_diffuse_probe_trace = 0; + scene->eevee.ssr_diffuse_probe_intensity = 1.0f; + scene->eevee.ssr_diffuse_probe_clamp = 1.0f; + + scene->eevee.ssr_diffuse_filter = 1.0f; + scene->eevee.ssr_diffuse_fsize = 32.0f; + scene->eevee.ssr_diffuse_fsamples = 1; + scene->eevee.ssr_diffuse_fnweight = 1.0f; + scene->eevee.ssr_diffuse_fdweight = 1.0f; + scene->eevee.ssr_diffuse_faoweight = 0.75f; + + scene->eevee.ssr_diffuse_debug_a = 1.0f; + scene->eevee.ssr_diffuse_debug_b = 1.0f; + scene->eevee.ssr_diffuse_debug_c = 1.0f; + scene->eevee.ssr_diffuse_debug_d = 1.0f; + } + } + } if (!MAIN_VERSION_ATLEAST(bmain, 293, 9)) { if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "bokeh_overblur")) { LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 229737d228a4..4afe6a8070ad 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -277,6 +277,10 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_setup_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_reflection_lib.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_reflection_resolve_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_reflection_trace_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_ssgi_filter_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_ssgi_filter_sec_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_ssgi_resolve_frag.glsl SRC) +data_to_c_simple(engines/eevee/shaders/effect_ssgi_trace_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC) data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC) @@ -366,6 +370,7 @@ data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC) data_to_c_simple(intern/shaders/common_hair_refine_comp.glsl SRC) data_to_c_simple(intern/shaders/common_math_lib.glsl SRC) data_to_c_simple(intern/shaders/common_math_geom_lib.glsl SRC) +data_to_c_simple(intern/shaders/common_colorpacking_lib.glsl SRC) data_to_c_simple(intern/shaders/common_view_lib.glsl SRC) data_to_c_simple(intern/shaders/common_fxaa_lib.glsl SRC) data_to_c_simple(intern/shaders/common_smaa_lib.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 0e0f144737fd..698501775daa 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -263,7 +263,7 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) 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_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1); /* TODO SSGI */ DRW_shgroup_call_procedural_triangles(grp, NULL, 1); DRW_PASS_CREATE(psl->color_downsample_ps, DRW_STATE_WRITE_COLOR); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 79787b0fd961..c5b136b800a6 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -299,6 +299,10 @@ typedef struct EEVEE_PassList { struct DRWPass *volumetric_accum_ps; struct DRWPass *ssr_raytrace; struct DRWPass *ssr_resolve; + struct DRWPass *ssgi_raytrace; + struct DRWPass *ssgi_resolve; + struct DRWPass *ssgi_filter; + struct DRWPass *ssgi_filter_sec; struct DRWPass *sss_blur_ps; struct DRWPass *sss_resolve_ps; struct DRWPass *sss_translucency_ps; @@ -365,6 +369,7 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *cryptomatte_fb; struct GPUFrameBuffer *shadow_accum_fb; struct GPUFrameBuffer *ssr_accum_fb; + struct GPUFrameBuffer *ssgi_accum_fb; /* TODO - use */ struct GPUFrameBuffer *sss_blur_fb; struct GPUFrameBuffer *sss_blit_fb; struct GPUFrameBuffer *sss_resolve_fb; @@ -390,6 +395,7 @@ typedef struct EEVEE_FramebufferList { struct GPUFrameBuffer *volumetric_integ_fb; struct GPUFrameBuffer *volumetric_accum_fb; struct GPUFrameBuffer *screen_tracing_fb; + struct GPUFrameBuffer *screen_tracing_ssgi_fb; // Filter struct GPUFrameBuffer *mist_accum_fb; struct GPUFrameBuffer *material_accum_fb; struct GPUFrameBuffer *renderpass_fb; @@ -436,6 +442,7 @@ typedef struct EEVEE_TextureList { struct GPUTexture *emit_accum; struct GPUTexture *bloom_accum; struct GPUTexture *ssr_accum; + struct GPUTexture *ssgi_accum; /* TODO - use */ struct GPUTexture *shadow_accum; struct GPUTexture *cryptomatte; struct GPUTexture *taa_history; @@ -745,13 +752,18 @@ typedef struct EEVEE_EffectsInfo { struct GPUTexture *volume_scatter; struct GPUTexture *volume_transmit; /* SSR */ - bool reflection_trace_full; + bool reflection_trace_full; /* TODO SSGI separate res toggle */ bool ssr_was_persp; bool ssr_was_valid_double_buffer; struct GPUTexture *ssr_normal_input; /* Textures from pool */ struct GPUTexture *ssr_specrough_input; struct GPUTexture *ssr_hit_output; struct GPUTexture *ssr_hit_depth; + /* SSGI (shares ssr data) */ + struct GPUTexture *ssgi_hit_output; //trace + struct GPUTexture *ssgi_hit_depth; //trace + struct GPUTexture *ssgi_filter_input; //filter a + struct GPUTexture *ssgi_filter_sec_input; //filter b /* Temporal Anti Aliasing */ int taa_reproject_sample; int taa_current_sample; @@ -916,6 +928,31 @@ typedef struct EEVEE_CommonUniformBuffer { float pad8; /* float */ float pad9; /* float */ float pad10; /* float */ + /* SSGI */ + float ssr_diffuse_versioning; /* float */ + float ssr_diffuse_intensity; /* float *//* trace */ + float ssr_diffuse_thickness; /* float */ + float ssr_diffuse_resolve_bias; /* float */ + float ssr_diffuse_quality; /* float */ + float ssr_diffuse_clamp; /* float */ + float ssr_diffuse_ao; /* float */ + float ssr_diffuse_ao_limit; /* float */ + int ssr_diffuse_probe_trace; /* int */ /* probe */ + float ssr_diffuse_probe_intensity; /* float */ + float ssr_diffuse_probe_clamp; /* float */ + float ssr_diffuse_filter; /* float *//* filter */ + float ssr_diffuse_fsize; /* float */ + int ssr_diffuse_fsamples; /* int */ + float ssr_diffuse_fnweight; /* float */ + float ssr_diffuse_fdweight; /* float */ + float ssr_diffuse_faoweight; /* float */ + float ssr_diffuse_debug_a; /* float *//* debug */ + float ssr_diffuse_debug_b; /* float */ + float ssr_diffuse_debug_c; /* float */ + float ssr_diffuse_debug_d; /* float */ + float pad130; + float pad131; + float pad132; } EEVEE_CommonUniformBuffer; BLI_STATIC_ASSERT_ALIGN(EEVEE_CommonUniformBuffer, 16) @@ -1235,6 +1272,10 @@ struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_sh_get(void); struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void); struct GPUShader *EEVEE_shaders_effect_reflection_trace_sh_get(void); struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_ssgi_trace_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_ssgi_resolve_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_ssgi_filter_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_ssgi_filter_sec_sh_get(void); struct GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void); struct GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair); struct GPUShader *EEVEE_shaders_shadow_sh_get(void); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 17cc1a46e23b..a5fed6d70295 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -60,7 +60,9 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) } effects->ssr_was_valid_double_buffer = stl->g_data->valid_double_buffer; - effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0; + //effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0; + effects->reflection_trace_full = true; //Temp disable + common_data->ssr_thickness = scene_eval->eevee.ssr_thickness; common_data->ssr_border_fac = scene_eval->eevee.ssr_border_fade; common_data->ssr_firefly_fac = scene_eval->eevee.ssr_firefly_fac; @@ -68,37 +70,80 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) common_data->ssr_quality = 1.0f - 0.95f * scene_eval->eevee.ssr_quality; common_data->ssr_brdf_bias = 0.1f + common_data->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */ + /* SSGI */ + common_data->ssr_diffuse_versioning = scene_eval->eevee.ssr_diffuse_versioning; + /* trace */ + common_data->ssr_diffuse_intensity = scene_eval->eevee.ssr_diffuse_intensity; + common_data->ssr_diffuse_thickness = scene_eval->eevee.ssr_diffuse_thickness; + common_data->ssr_diffuse_resolve_bias = scene_eval->eevee.ssr_diffuse_resolve_bias; + common_data->ssr_diffuse_quality = scene_eval->eevee.ssr_diffuse_quality; + common_data->ssr_diffuse_clamp = scene_eval->eevee.ssr_diffuse_clamp; + common_data->ssr_diffuse_ao = scene_eval->eevee.ssr_diffuse_ao; + common_data->ssr_diffuse_ao_limit = scene_eval->eevee.ssr_diffuse_ao_limit; + /* probe */ + common_data->ssr_diffuse_probe_trace = scene_eval->eevee.ssr_diffuse_probe_trace; + common_data->ssr_diffuse_probe_intensity = scene_eval->eevee.ssr_diffuse_probe_intensity; + common_data->ssr_diffuse_probe_clamp = scene_eval->eevee.ssr_diffuse_probe_clamp; + /* filter */ + common_data->ssr_diffuse_filter = scene_eval->eevee.ssr_diffuse_filter; + common_data->ssr_diffuse_fsize = scene_eval->eevee.ssr_diffuse_fsize; + common_data->ssr_diffuse_fsamples = scene_eval->eevee.ssr_diffuse_fsamples; + common_data->ssr_diffuse_fnweight = scene_eval->eevee.ssr_diffuse_fnweight; + common_data->ssr_diffuse_fdweight = scene_eval->eevee.ssr_diffuse_fdweight; + common_data->ssr_diffuse_faoweight = scene_eval->eevee.ssr_diffuse_faoweight; + /* debug */ + common_data->ssr_diffuse_debug_a = scene_eval->eevee.ssr_diffuse_debug_a; + common_data->ssr_diffuse_debug_b = scene_eval->eevee.ssr_diffuse_debug_b; + common_data->ssr_diffuse_debug_c = scene_eval->eevee.ssr_diffuse_debug_c; + common_data->ssr_diffuse_debug_d = scene_eval->eevee.ssr_diffuse_debug_d; + if (common_data->ssr_firefly_fac < 1e-8f) { common_data->ssr_firefly_fac = FLT_MAX; } + if (common_data->ssr_diffuse_clamp < 1e-8f) { //TODO Fix + common_data->ssr_diffuse_clamp = FLT_MAX; + } void *owner = (void *)EEVEE_screen_raytrace_init; const int divisor = (effects->reflection_trace_full) ? 1 : 2; int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor}; const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]}; - const bool high_qual_input = true; /* TODO: dither low quality input. */ - const eGPUTextureFormat format = (high_qual_input) ? GPU_RGBA16F : GPU_RGBA8; + const bool high_qual_input = true; /* TODO dither low quality input */ + int gi_resolve_res[2] = {(int)viewport_size[0], (int)viewport_size[1]}; // const float *viewport_size = DRW_viewport_size_get(); + const eGPUTextureFormat format = GPU_RGBA32F; tracing_res[0] = max_ii(1, tracing_res[0]); tracing_res[1] = max_ii(1, tracing_res[1]); + gi_resolve_res [1] = max_ii(1, gi_resolve_res[1]); + gi_resolve_res [1] = max_ii(1, gi_resolve_res[1]); + common_data->ssr_uv_scale[0] = size_fs[0] / ((float)tracing_res[0] * divisor); common_data->ssr_uv_scale[1] = size_fs[1] / ((float)tracing_res[1] * divisor); /* MRT for the shading pass in order to output needed data for the SSR pass. */ effects->ssr_specrough_input = DRW_texture_pool_query_2d(UNPACK2(size_fs), format, owner); + /* TODO SSGI separate input */ GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_specrough_input, 2, 0); /* Ray-tracing output. */ effects->ssr_hit_output = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_RGBA16F, owner); effects->ssr_hit_depth = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_R16F, owner); + effects->ssgi_hit_output = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_RGBA16F, owner); + effects->ssgi_hit_depth = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_R16F, owner); + effects->ssgi_filter_input = DRW_texture_pool_query_2d(UNPACK2(gi_resolve_res), GPU_RGBA16F, owner); + effects->ssgi_filter_sec_input = DRW_texture_pool_query_2d(UNPACK2(gi_resolve_res), GPU_RGBA16F, owner); GPU_framebuffer_ensure_config(&fbl->screen_tracing_fb, { GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output), GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_depth), + GPU_ATTACHMENT_TEXTURE(effects->ssgi_hit_output), + GPU_ATTACHMENT_TEXTURE(effects->ssgi_hit_depth), + GPU_ATTACHMENT_TEXTURE(effects->ssgi_filter_input), + GPU_ATTACHMENT_TEXTURE(effects->ssgi_filter_sec_input) }); return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_RADIANCE_BUFFER | EFFECT_DOUBLE_BUFFER | @@ -109,6 +154,7 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) GPU_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb); effects->ssr_specrough_input = NULL; effects->ssr_hit_output = NULL; + effects->ssgi_hit_output = NULL; return 0; } @@ -124,9 +170,17 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v if ((effects->enabled_effects & EFFECT_SSR) != 0) { struct GPUShader *trace_shader = EEVEE_shaders_effect_reflection_trace_sh_get(); struct GPUShader *resolve_shader = EEVEE_shaders_effect_reflection_resolve_sh_get(); + struct GPUShader *ssgi_trace_shader = EEVEE_shaders_effect_ssgi_trace_sh_get(); + struct GPUShader *ssgi_resolve_shader = EEVEE_shaders_effect_ssgi_resolve_sh_get(); + struct GPUShader *ssgi_filter_shader = EEVEE_shaders_effect_ssgi_filter_sh_get(); + struct GPUShader *ssgi_filter_sec_shader = EEVEE_shaders_effect_ssgi_filter_sec_sh_get(); int hitbuf_size[3]; GPU_texture_get_mipmap_size(effects->ssr_hit_output, 0, hitbuf_size); + GPU_texture_get_mipmap_size(effects->ssgi_hit_output, 0, hitbuf_size); + int gi_resolve_res[3]; + GPU_texture_get_mipmap_size(effects->ssgi_filter_input, 0, gi_resolve_res); //TODO - correct res + GPU_texture_get_mipmap_size(effects->ssgi_filter_sec_input, 0, gi_resolve_res); //TODO - correct res /** Screen space raytracing overview * @@ -158,7 +212,22 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v grp, "randomScale", effects->reflection_trace_full ? 0.0f : 0.5f); DRW_shgroup_call_procedural_triangles(grp, NULL, 1); + DRW_PASS_CREATE(psl->ssgi_raytrace, DRW_STATE_WRITE_COLOR); + DRWShadingGroup *grp_ssgi = DRW_shgroup_create(ssgi_trace_shader, psl->ssgi_raytrace); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "specroughBuffer", &effects->ssr_specrough_input); /* TODO - separate input buffer */ + DRW_shgroup_uniform_texture_ref(grp_ssgi, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_texture(grp_ssgi, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp_ssgi, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp_ssgi, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp_ssgi, "renderpass_block", sldata->renderpass_ubo.combined); + DRW_shgroup_uniform_vec2_copy(grp_ssgi, "targetSize", (float[2]){hitbuf_size[0], hitbuf_size[1]}); + DRW_shgroup_uniform_float_copy( + grp_ssgi, "randomScale", effects->reflection_trace_full ? 0.0f : 0.5f); /* TODO - Separate toggle */ + DRW_shgroup_call_procedural_triangles(grp_ssgi, NULL, 1); + eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT; + eGPUSamplerState filter = GPU_SAMPLER_FILTER; // (GPU_SAMPLER_FILTER | GPU_SAMPLER_REPEAT_S); DRW_PASS_CREATE(psl->ssr_resolve, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD); grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve); @@ -184,6 +253,55 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1); DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); DRW_shgroup_call_procedural_triangles(grp, NULL, 1); + + DRW_PASS_CREATE(psl->ssgi_resolve, DRW_STATE_WRITE_COLOR); + grp_ssgi = DRW_shgroup_create(ssgi_resolve_shader, psl->ssgi_resolve); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "specroughBuffer", &effects->ssr_specrough_input); + DRW_shgroup_uniform_texture_ref_ex(grp_ssgi, "ssgiHitBuffer", &effects->ssgi_hit_output, no_filter); + DRW_shgroup_uniform_texture_ref_ex(grp_ssgi, "ssgiHitDepth", &effects->ssgi_hit_depth, no_filter); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "colorBuffer", &txl->filtered_radiance); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "shadowCubeTexture", &sldata->shadow_cube_pool); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "shadowCascadeTexture", &sldata->shadow_cascade_pool); + DRW_shgroup_uniform_texture(grp_ssgi, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp_ssgi, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp_ssgi, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_uniform_block(grp_ssgi, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp_ssgi, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp_ssgi, "renderpass_block", sldata->renderpass_ubo.combined); + DRW_shgroup_uniform_int(grp_ssgi, "samplePoolOffset", &effects->taa_current_sample, 1); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "horizonBuffer", &effects->gtao_horizons); + DRW_shgroup_call_procedural_triangles(grp_ssgi, NULL, 1); + + + /* TODO cleanup */ + DRW_PASS_CREATE(psl->ssgi_filter, DRW_STATE_WRITE_COLOR); + grp_ssgi = DRW_shgroup_create(ssgi_filter_shader, psl->ssgi_filter); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "specroughBuffer", &effects->ssr_specrough_input); + DRW_shgroup_uniform_texture_ref_ex(grp_ssgi, "ssgiFilterInput", &effects->ssgi_filter_input, filter); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_block(grp_ssgi, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_texture(grp_ssgi, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp_ssgi, "renderpass_block", sldata->renderpass_ubo.combined); + DRW_shgroup_uniform_int(grp_ssgi, "samplePoolOffset", &effects->taa_current_sample, 1); + DRW_shgroup_uniform_vec2_copy(grp_ssgi, "resolveSize", (float[2]){gi_resolve_res[0], gi_resolve_res[1]}); + DRW_shgroup_call_procedural_triangles(grp_ssgi, NULL, 1); + + DRW_PASS_CREATE(psl->ssgi_filter_sec, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD); + grp_ssgi = DRW_shgroup_create(ssgi_filter_sec_shader, psl->ssgi_filter_sec); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "specroughBuffer", &effects->ssr_specrough_input); + DRW_shgroup_uniform_texture_ref_ex(grp_ssgi, "ssgiFilterInput", &effects->ssgi_filter_input, filter); + DRW_shgroup_uniform_texture_ref_ex(grp_ssgi, "ssgiFilterSecInput", &effects->ssgi_filter_sec_input, filter); + DRW_shgroup_uniform_texture_ref(grp_ssgi, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_block(grp_ssgi, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_texture(grp_ssgi, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp_ssgi, "renderpass_block", sldata->renderpass_ubo.combined); + DRW_shgroup_uniform_int(grp_ssgi, "samplePoolOffset", &effects->taa_current_sample, 1); + DRW_shgroup_uniform_vec2_copy(grp_ssgi, "resolveSize", (float[2]){gi_resolve_res[0], gi_resolve_res[1]}); + DRW_shgroup_call_procedural_triangles(grp_ssgi, NULL, 1); } } @@ -216,10 +334,15 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v /* Raytrace. */ GPU_framebuffer_bind(fbl->screen_tracing_fb); DRW_draw_pass(psl->ssr_raytrace); + DRW_draw_pass(psl->ssgi_raytrace); + /* TODO Fix */ + DRW_draw_pass(psl->ssgi_resolve); + DRW_draw_pass(psl->ssgi_filter); EEVEE_effects_downsample_radiance_buffer(vedata, txl->color_double_buffer); GPU_framebuffer_bind(fbl->main_color_fb); + DRW_draw_pass(psl->ssgi_filter_sec); DRW_draw_pass(psl->ssr_resolve); /* Restore */ @@ -259,6 +382,7 @@ void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEV GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear); } + DRW_draw_pass(psl->ssgi_filter_sec); DRW_draw_pass(psl->ssr_resolve); } } diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index 41a92d7a5d8b..f8700fab2d81 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -134,6 +134,10 @@ static struct { /* Screen Space Reflection */ struct GPUShader *reflection_trace; struct GPUShader *reflection_resolve; + struct GPUShader *ssgi_trace; + struct GPUShader *ssgi_resolve; + struct GPUShader *ssgi_filter; + struct GPUShader *ssgi_filter_sec; /* Shadows */ struct GPUShader *shadow_sh; @@ -189,6 +193,7 @@ extern char datatoc_common_math_lib_glsl[]; extern char datatoc_common_math_geom_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; extern char datatoc_gpu_shader_common_obinfos_lib_glsl[]; +extern char datatoc_common_colorpacking_lib_glsl[]; extern char datatoc_ambient_occlusion_lib_glsl[]; extern char datatoc_background_vert_glsl[]; @@ -225,6 +230,10 @@ extern char datatoc_effect_motion_blur_frag_glsl[]; extern char datatoc_effect_reflection_lib_glsl[]; extern char datatoc_effect_reflection_resolve_frag_glsl[]; extern char datatoc_effect_reflection_trace_frag_glsl[]; +extern char datatoc_effect_ssgi_filter_sec_frag_glsl[]; +extern char datatoc_effect_ssgi_filter_frag_glsl[]; +extern char datatoc_effect_ssgi_resolve_frag_glsl[]; +extern char datatoc_effect_ssgi_trace_frag_glsl[]; extern char datatoc_effect_subsurface_frag_glsl[]; extern char datatoc_effect_temporal_aa_glsl[]; extern char datatoc_effect_translucency_frag_glsl[]; @@ -386,6 +395,7 @@ static void eevee_shader_library_ensure(void) /* NOTE: These need to be ordered by dependencies. */ DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib); + DRW_SHADER_LIB_ADD(e_data.lib, common_colorpacking_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib); DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib); @@ -859,6 +869,17 @@ struct GPUShader *EEVEE_shaders_effect_reflection_trace_sh_get(void) return e_data.reflection_trace; } +struct GPUShader *EEVEE_shaders_effect_ssgi_trace_sh_get(void) +{ + if (e_data.ssgi_trace == NULL) { + e_data.ssgi_trace = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_ssgi_trace_frag_glsl, + e_data.lib, + SHADER_DEFINES "#define STEP_RAYTRACE\n"); + } + return e_data.ssgi_trace; +} + struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void) { if (e_data.reflection_resolve == NULL) { @@ -870,6 +891,39 @@ struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void) return e_data.reflection_resolve; } +struct GPUShader *EEVEE_shaders_effect_ssgi_resolve_sh_get(void) +{ + if (e_data.ssgi_resolve == NULL) { + e_data.ssgi_resolve = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_ssgi_resolve_frag_glsl, + e_data.lib, + SHADER_DEFINES "#define STEP_RESOLVE_GI\n"); + } + return e_data.ssgi_resolve; +} + +struct GPUShader *EEVEE_shaders_effect_ssgi_filter_sh_get(void) +{ + if (e_data.ssgi_filter == NULL) { + e_data.ssgi_filter = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_ssgi_filter_frag_glsl, + e_data.lib, + SHADER_DEFINES "#define STEP_FILTER_GI\n"); + } + return e_data.ssgi_filter; +} + +struct GPUShader *EEVEE_shaders_effect_ssgi_filter_sec_sh_get(void) +{ + if (e_data.ssgi_filter_sec == NULL) { + e_data.ssgi_filter_sec = DRW_shader_create_fullscreen_with_shaderlib( + datatoc_effect_ssgi_filter_sec_frag_glsl, + e_data.lib, + SHADER_DEFINES "#define STEP_FILTER_SEC_GI\n"); + } + return e_data.ssgi_filter_sec; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1722,7 +1776,11 @@ void EEVEE_shaders_free(void) DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[i]); } DRW_SHADER_FREE_SAFE(e_data.reflection_trace); + DRW_SHADER_FREE_SAFE(e_data.ssgi_trace); DRW_SHADER_FREE_SAFE(e_data.reflection_resolve); + DRW_SHADER_FREE_SAFE(e_data.ssgi_resolve); + DRW_SHADER_FREE_SAFE(e_data.ssgi_filter); + DRW_SHADER_FREE_SAFE(e_data.ssgi_filter_sec); DRW_SHADER_LIB_FREE_SAFE(e_data.lib); if (e_data.default_world) { diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl index e5cbc487e930..d9b4686d0231 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_lib.glsl @@ -157,7 +157,7 @@ #define ClosureInputDummy ClosureOutput #define ClosureOutputDummy ClosureOutput #define ClosureEvalDummy ClosureOutput -#define CLOSURE_EVAL_DUMMY ClosureOutput(vec3(0)) +#define CLOSURE_EVAL_DUMMY ClosureOutput(vec3(0), float(0.0)) #define CLOSURE_INPUT_Dummy_DEFAULT CLOSURE_EVAL_DUMMY #define closure_Dummy_eval_init(cl_in, cl_common, cl_out) CLOSURE_EVAL_DUMMY #define closure_Dummy_planar_eval(cl_in, cl_eval, cl_common, data, cl_out) @@ -211,6 +211,7 @@ struct ClosureEvalCommon { /* Common cl_out struct used by most closures. */ struct ClosureOutput { vec3 radiance; + float AO; }; /* Workaround for screenspace shadows in SSR pass. */ diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl index 183219c90889..cbed00f83975 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_translucent_lib.glsl @@ -69,3 +69,5 @@ void closure_Translucent_eval_end(ClosureInputTranslucent cl_in, return; #endif } + +/* TODO ssr data out */ diff --git a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl index f66f45635f47..707baacf7422 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl @@ -1,6 +1,7 @@ #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(renderpass_lib.glsl) +#pragma BLENDER_REQUIRE(common_colorpacking_lib.glsl) #ifndef VOLUMETRICS @@ -97,10 +98,18 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac) cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac); cl.radiance = mix(cl1.radiance, cl2.radiance, fac); cl.flag = cl1.flag | cl2.flag; - cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac); + /* unpack TODO - clean up */ + vec4 spec_cl1 = vec4(0.0,0.0,0.0,1.0); + vec4 spec_cl2 = vec4(0.0,0.0,0.0,1.0); + vec4 diffuse_cl1 = vec4(0.0,0.0,0.0,1.0); + vec4 diffuse_cl2 = vec4(0.0,0.0,0.0,1.0); + unpackVec4(cl1.ssr_data, spec_cl1, diffuse_cl1); + unpackVec4(cl2.ssr_data, spec_cl2, diffuse_cl2); + + cl.ssr_data.rgb = packVec3(mix(spec_cl1.rgb, spec_cl2.rgb, fac), mix(diffuse_cl1.rgb, diffuse_cl2.rgb, fac)); bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG); - /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz). */ - cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w; + /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/ + cl.ssr_data.w = (use_cl1_ssr) ? packFloat(spec_cl1.a, mix(diffuse_cl1.a, diffuse_cl2.a, fac)) : packFloat(spec_cl2.a, mix(diffuse_cl1.a, diffuse_cl2.a, fac)); cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal; # ifdef USE_SSS @@ -120,10 +129,18 @@ Closure closure_add(Closure cl1, Closure cl2) cl.radiance = cl1.radiance + cl2.radiance; cl.holdout = cl1.holdout + cl2.holdout; cl.flag = cl1.flag | cl2.flag; - cl.ssr_data = cl1.ssr_data + cl2.ssr_data; + /* unpack TODO - clean up */ + vec4 spec_cl1 = vec4(0.0,0.0,0.0,1.0); + vec4 spec_cl2 = vec4(0.0,0.0,0.0,1.0); + vec4 diffuse_cl1 = vec4(0.0,0.0,0.0,1.0); + vec4 diffuse_cl2 = vec4(0.0,0.0,0.0,1.0); + unpackVec4(cl1.ssr_data, spec_cl1, diffuse_cl1); + unpackVec4(cl2.ssr_data, spec_cl2, diffuse_cl2); + + cl.ssr_data.rgb = packVec3((spec_cl1.rgb + spec_cl2.rgb), (diffuse_cl1.rgb + diffuse_cl2.rgb)); bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG); - /* When mixing SSR don't blend roughness and normals. */ - cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w; + /* When mixing SSR don't blend roughness and normals.*/ + cl.ssr_data.w = (use_cl1_ssr) ? packFloat(spec_cl1.a, diffuse_cl1.a + diffuse_cl2.a): packFloat(spec_cl2.a, diffuse_cl1.a + diffuse_cl2.a); cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal; # ifdef USE_SSS @@ -155,17 +172,23 @@ vec3 closure_mask_ssr_radiance(vec3 radiance, float ssr_id) } void closure_load_ssr_data( - vec3 ssr_radiance, float roughness, vec3 N, float ssr_id, inout Closure cl) + vec3 ssr_radiance, float roughness, vec3 N, float ssr_id, inout Closure cl, vec3 rgb_diffuse, float ao) { - /* Still encode to avoid artifacts in the SSR pass. */ + /* Packed colors to a 32bit texture - avoids few fetches, but would make more sense to use separate 16 bit buffers or at least pack before writing to buffer */ + /* A for Spec, B for Diffuse */ + /* color inputs over 1.0 are valid and should be allowed - so using clamped range of 0.0 - 10.0 */ + + /* Still encode normals to avoid artifacts in the SSR pass. */ vec3 vN = normalize(mat3(ViewMatrix) * N); cl.ssr_normal = normal_encode(vN, viewCameraVec(viewPosition)); + cl.ssr_data = packVec4(vec4(ssr_radiance, roughness), vec4(rgb_diffuse, ao)); if (ssrToggle && int(ssr_id) == outputSsrId) { - cl.ssr_data = vec4(ssr_radiance, roughness); + cl.ssr_data = packVec4(vec4(ssr_radiance, roughness), vec4(rgb_diffuse, ao)); cl.flag |= CLOSURE_SSR_FLAG; } else { + cl.ssr_data = packVec4(vec4(0.0,0.0,0.0, 0.0), vec4(rgb_diffuse, ao)); cl.radiance += ssr_radiance; } } 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 c935eca6a391..e4897be08c48 100644 --- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl @@ -46,6 +46,28 @@ layout(std140) uniform common_block float pad7; float pad8; float pad9; + /* SSGI */ + float ssrDiffuseVersioning; + float ssrDiffuseIntensity; /*trace*/ + float ssrDiffuseThickness; + float ssrDiffuseResolveBias; + float ssrDiffuseQuality; + float ssrDiffuseClamp; + float ssrDiffuseAo; + float ssrDiffuseAoLimit; + int ssrDiffuseProbeTrace; /*probe*/ + float ssrDiffuseProbeIntensity; + float ssrDiffuseProbeClamp; + float ssrDiffuseFilter; /*filter*/ + float ssrDiffuseFsize; + int ssrDiffuseFsamples; + float ssrDiffuseFnweight; + float ssrDiffuseFdweight; + float ssrDiffuseFaoweight; + float ssrDiffuseDebugA; /*debug*/ + float ssrDiffuseDebugB; + float ssrDiffuseDebugC; + float ssrDiffuseDebugD; /*float pad11;*/ }; /* rayType (keep in sync with ray_type) */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl index ed600a3be86b..cef855cbc242 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl @@ -26,6 +26,17 @@ struct HitData { bool is_planar; }; +struct SsgiHitData { + /** Hit direction scaled by intersection time. */ + vec3 hit_dir; + /** Screen space [0..1] depth of the reflection hit position, or -1.0 for planar reflections (unused). */ + float hit_depth; + /** Inverse probability of ray spawning in this direction. */ + float ray_pdf_inv; + /** True if ray has hit valid geometry. */ + bool is_hit; +}; + void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth) { vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z); @@ -36,6 +47,15 @@ void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0); } +void ssgi_encode_hit_data(SsgiHitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth) +{ + vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z); + hit_data.xyz = hit_vP - vP; + hit_depth = hit_sP.z; + /* Record 1.0 / pdf to reduce the computation in the resolve phase. */ + /* Encode hit validity in sign. */ + hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0); +} HitData decode_hit_data(vec4 hit_data, float hit_depth) { HitData data; @@ -47,6 +67,15 @@ HitData decode_hit_data(vec4 hit_data, float hit_depth) return data; } +SsgiHitData ssgi_decode_hit_data(vec4 hit_data, float hit_depth) +{ + SsgiHitData data; + data.hit_dir.xyz = hit_data.xyz; + data.hit_depth = hit_depth; + data.ray_pdf_inv = abs(hit_data.w); + data.is_hit = (hit_data.w > 0.0); + return data; +} /* Blue noise categorised into 4 sets of samples. * See "Stochastic all the things" presentation slide 32-37. */ const int resolve_samples_count = 9; diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl index 7689e730bf38..580e8c412692 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl @@ -7,6 +7,7 @@ #pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) #pragma BLENDER_REQUIRE(surface_lib.glsl) #pragma BLENDER_REQUIRE(effect_reflection_lib.glsl) +#pragma BLENDER_REQUIRE(common_colorpacking_lib.glsl) /* Based on: * "Stochastic Screen Space Reflections" @@ -190,6 +191,10 @@ void main() ivec2 texel = ivec2(gl_FragCoord.xy); vec4 speccol_roughness = texelFetch(specroughBuffer, texel, 0).rgba; + /* unpack A for Spec, B for Diffuse */ // TODO Separate input buffers + vec4 difcol_roughness = vec4(0.0); + unpackVec4(speccol_roughness, speccol_roughness, difcol_roughness); + vec3 brdf = speccol_roughness.rgb; float roughness = speccol_roughness.a; diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl index 2f1efd588f7b..4be2de5fcd23 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl @@ -6,6 +6,7 @@ #pragma BLENDER_REQUIRE(lightprobe_lib.glsl) #pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl) #pragma BLENDER_REQUIRE(effect_reflection_lib.glsl) +#pragma BLENDER_REQUIRE(common_colorpacking_lib.glsl) /* Based on: * "Stochastic Screen Space Reflections" @@ -65,6 +66,9 @@ void main() /* Retrieve pixel data */ vec4 speccol_roughness = texture(specroughBuffer, uvs, 0).rgba; + /* unpack - 1 for Spec, 2 for Diffuse */ // TODO separate input buffers + vec4 difcol_roughness = vec4(0.0); + unpackVec4(speccol_roughness, speccol_roughness, difcol_roughness); /* Early out */ if (dot(speccol_roughness.rgb, vec3(1.0)) == 0.0) { diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 84626eac4cf9..29118237b24e 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -186,6 +186,29 @@ vec3 probe_evaluate_world_spec(vec3 R, float roughness) return textureLod_cubemapArray(probeCubes, vec4(R, 0.0), lod).rgb; } +vec3 probe_evaluate_cube_diffuse_trace(int pd_id, vec3 P, vec3 R) +{ + /* Correct reflection ray using parallax volume intersection. */ + vec3 localpos = transform_point(probes_data[pd_id].parallaxmat, P); + vec3 localray = transform_direction(probes_data[pd_id].parallaxmat, R); + + // float dist; + // if (probes_data[pd_id].p_parallax_type == PROBE_PARALLAX_BOX) { + // dist = line_unit_box_intersect_dist(localpos, localray); + // } + // else { + // dist = line_unit_sphere_intersect_dist(localpos, localray); + // } + + float lod = prbLodCubeMax; + return textureLod_cubemapArray(probeCubes, vec4(R, float(pd_id)), prbLodCubeMax).rgb; +} + +vec3 probe_evaluate_world_cubemap_ssgi(vec3 R) +{ + return textureLod_cubemapArray(probeCubes, vec4(R, 0.0), prbLodCubeMax).rgb; +} + vec3 probe_evaluate_planar(int id, PlanarData pd, vec3 P, vec3 N, vec3 V, float roughness) { /* Find view vector / reflection plane intersection. */ @@ -245,6 +268,31 @@ void fallback_cubemap(vec3 N, } } +void fallback_cubemap_ssgi(vec3 N, + vec3 P, + inout vec4 spec_accum) +{ + /* Specular probes */ + + /* Starts at 1 because 0 is world probe */ +/* for (int i = 1; i < MAX_PROBE && i < prbNumRenderCube && spec_accum.a < 0.999; i++) { + float fade = 1.0; + //fade = probe_attenuation_cube(i, P); + + if (fade > 0.0) { + //vec3 spec = probe_evaluate_cube_diffuse_trace(i, P, N); + vec3 spec = textureLod_cubemapArray(probeCubes, vec4(N, float(i)), prbLodCubeMax).rgb; + accumulate_light(spec, fade, spec_accum); + } + } */ + + /* World Specular */ + if (spec_accum.a < 0.999) { + vec3 spec = textureLod_cubemapArray(probeCubes, vec4(N, 1.0), prbLodCubeMax).rgb; + accumulate_light(spec, 1.0, spec_accum); + } +} + vec3 probe_evaluate_grid(GridData gd, vec3 P, vec3 N, vec3 localpos) { localpos = localpos * 0.5 + 0.5; @@ -309,3 +357,11 @@ vec3 probe_evaluate_world_diff(vec3 N) } return irradiance_from_cell_get(0, N); } + +vec3 evaluate_diffuse_probe_ssgi(vec3 N) //TODO: routine for probe selection +{ + if (prbNumRenderGrid == 0) { + return vec3(0); + } + return irradiance_from_cell_get(0, N); +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl index 889bf439d5f9..72f193ca9575 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl @@ -13,6 +13,8 @@ #pragma BLENDER_REQUIRE(surface_lib.glsl) #pragma BLENDER_REQUIRE(volumetric_lib.glsl) +#pragma BLENDER_REQUIRE(common_colorpacking_lib.glsl) + #ifdef USE_ALPHA_BLEND /* Use dual source blending to be able to make a whole range of effects. */ layout(location = 0, index = 0) out vec4 outRadiance; @@ -81,7 +83,12 @@ void main() #ifndef USE_ALPHA_BLEND float alpha_div = safe_rcp(alpha); outRadiance.rgb *= alpha_div; - ssrData.rgb *= alpha_div; + /* unpack TODO - clean up - Needs Vec3 only*/ + vec4 spec = vec4(0.0); + vec4 diffuse = vec4(0.0); + unpackVec4(ssrData.rgba, spec, diffuse); + + ssrData.rgb = packVec3(spec.rgb * alpha_div, diffuse.rgb * alpha_div); # ifdef USE_SSS sssAlbedo.rgb *= alpha_div; # endif diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl index 0efa7b80b0b6..ac72ef2a8620 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl @@ -6,7 +6,7 @@ vec3 worldNormal; \ vec3 viewNormal; -#if defined(STEP_RESOLVE) || defined(STEP_RAYTRACE) +#if defined(STEP_RESOLVE) || defined(STEP_RAYTRACE) || defined(STEP_RESOLVE_GI) || defined(STEP_FILTER_GI) || defined(STEP_FILTER_SEC_GI) /* SSR will set these global variables itself. * Also make false positive compiler warnings disapear by setting values. */ vec3 worldPosition = vec3(0); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl index 01a16e194caa..f7b242771f5a 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl @@ -5,21 +5,19 @@ CLOSURE_EVAL_FUNCTION_DECLARE_1(node_bsdf_diffuse, Diffuse) void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) { CLOSURE_VARS_DECLARE_1(Diffuse); - in_Diffuse_0.N = N; /* Normalized during eval. */ in_Diffuse_0.albedo = color.rgb; CLOSURE_EVAL_FUNCTION_1(node_bsdf_diffuse, Diffuse); result = CLOSURE_DEFAULT; - out_Diffuse_0.radiance = render_pass_diffuse_mask(vec3(1.0), out_Diffuse_0.radiance); out_Diffuse_0.radiance *= color.rgb; result.radiance = out_Diffuse_0.radiance; /* TODO(fclem) Try to not use this. */ - closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result); + closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result, color.rgb, out_Diffuse_0.AO); } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl index 0941482df458..2ae3332111e9 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl @@ -50,7 +50,7 @@ void node_eevee_specular(vec4 diffuse, out_Glossy_1.radiance *= brdf; out_Glossy_1.radiance = render_pass_glossy_mask(specular.rgb, out_Glossy_1.radiance); closure_load_ssr_data( - out_Glossy_1.radiance, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result); + out_Glossy_1.radiance, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result, diffuse.rgb, out_Diffuse_0.AO); } { /* Clearcoat. */ diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl index aa0a8873596d..e9c997e84ed9 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl @@ -38,7 +38,7 @@ void node_bsdf_glass(vec4 color, out_Glossy_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Glossy_0.radiance); out_Glossy_0.radiance *= color.rgb * fresnel; closure_load_ssr_data( - out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result); + out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result, vec3(0.0), 1.0); float btdf = (do_multiscatter != 0.0) ? 1.0 : diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl index fa83bfb6c7a2..b4bf3dbead09 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl @@ -24,7 +24,7 @@ void node_bsdf_glossy( out_Glossy_0.radiance = render_pass_glossy_mask(vec3(1.0), out_Glossy_0.radiance); out_Glossy_0.radiance *= color.rgb; closure_load_ssr_data( - out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result); + out_Glossy_0.radiance, in_Glossy_0.roughness, in_Glossy_0.N, ssr_id, result, vec3(0.0), 1.0); } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index bba84c2be52c..3482550b6e41 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -62,7 +62,7 @@ void node_bsdf_principled(vec4 base_color, CLOSURE_VARS_DECLARE_4(Diffuse, Glossy, Glossy, Refraction); in_Diffuse_0.N = N; /* Normalized during eval. */ - in_Diffuse_0.albedo = mix(base_color.rgb, subsurface_color.rgb, subsurface); + in_Diffuse_0.albedo = mix(base_color.rgb + (emission.rgb * emission_strength), subsurface_color.rgb, subsurface); //Note - adding emissive to albedo to influence GTAO multibounce (non colored). //TODO - how to handle emissive only node in_Glossy_1.N = N; /* Normalized during eval. */ in_Glossy_1.roughness = roughness; @@ -143,7 +143,7 @@ void node_bsdf_principled(vec4 base_color, } closure_load_ssr_data( - glossy_radiance_final, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result); + glossy_radiance_final * alpha, in_Glossy_1.roughness, in_Glossy_1.N, ssr_id, result, (mix(base_color.rgb, subsurface_color.rgb, subsurface) * alpha) * (1 - metallic), out_Diffuse_0.AO); } if (diffuse_weight > 1e-5) { @@ -194,7 +194,6 @@ void node_bsdf_principled(vec4 base_color, result.transmittance = vec3(1.0 - alpha); result.radiance *= alpha; - result.ssr_data.rgb *= alpha; # ifdef USE_SSS result.sss_albedo *= alpha; # endif diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl index d0c159cdf37a..e6ca82032f6d 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl @@ -23,7 +23,7 @@ void node_subsurface_scattering(vec4 color, closure_load_sss_data(scale, out_Diffuse_0.radiance, color.rgb, int(sss_id), result); /* TODO(fclem) Try to not use this. */ - closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result); + closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result, color.rgb, out_Diffuse_0.AO); } #else diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl index 80bd3941b22a..c2dc6f3dcb6b 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl @@ -11,7 +11,7 @@ void node_bsdf_translucent(vec4 color, vec3 N, out Closure result) CLOSURE_EVAL_FUNCTION_1(node_bsdf_translucent, Translucent); result = CLOSURE_DEFAULT; - closure_load_ssr_data(vec3(0.0), 0.0, -in_Translucent_0.N, -1.0, result); + closure_load_ssr_data(vec3(0.0), 0.0, -in_Translucent_0.N, -1.0, result, color.rgb , 1.0); result.radiance = render_pass_diffuse_mask(color.rgb, out_Translucent_0.radiance * color.rgb); } diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h index a3a914a9b69b..fd5f58e26e35 100644 --- a/source/blender/makesdna/DNA_scene_defaults.h +++ b/source/blender/makesdna/DNA_scene_defaults.h @@ -246,6 +246,27 @@ .ssr_thickness = 0.2f, \ .ssr_border_fade = 0.075f, \ .ssr_firefly_fac = 10.0f, \ + .ssr_diffuse_versioning = 1.14f, \ + .ssr_diffuse_intensity = 1.0f, \ + .ssr_diffuse_thickness = 1.0f, \ + .ssr_diffuse_resolve_bias = 0.1f, \ + .ssr_diffuse_quality = 0.25f, \ + .ssr_diffuse_clamp = 1.0f, \ + .ssr_diffuse_ao = 1.0f, \ + .ssr_diffuse_ao_limit = 0.5f, \ + .ssr_diffuse_probe_trace = 0, \ + .ssr_diffuse_probe_intensity = 1.0, \ + .ssr_diffuse_probe_clamp = 1.0, \ + .ssr_diffuse_filter = 1.0f, \ + .ssr_diffuse_fsize = 32.0f, \ + .ssr_diffuse_fsamples = 1, \ + .ssr_diffuse_fnweight = 1.0f, \ + .ssr_diffuse_fdweight = 1.0f, \ + .ssr_diffuse_faoweight = 0.75f, \ + .ssr_diffuse_debug_a = 1.0f, \ + .ssr_diffuse_debug_b = 1.0f, \ + .ssr_diffuse_debug_c = 1.0f, \ + .ssr_diffuse_debug_d = 1.0f, \ \ .volumetric_start = 0.1f, \ .volumetric_end = 100.0f, \ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5200532e72fe..d8ebdb81d3fd 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1791,6 +1791,28 @@ typedef struct SceneEEVEE { float ssr_thickness; float ssr_border_fade; float ssr_firefly_fac; + float ssr_diffuse_versioning; + float ssr_diffuse_intensity; + float ssr_diffuse_thickness; + float ssr_diffuse_resolve_bias; + float ssr_diffuse_quality; + float ssr_diffuse_clamp; + float ssr_diffuse_ao; + float ssr_diffuse_ao_limit; + int ssr_diffuse_probe_trace; + float ssr_diffuse_probe_intensity; + float ssr_diffuse_probe_clamp; + float ssr_diffuse_filter; + float ssr_diffuse_fsize; + int ssr_diffuse_fsamples; + float ssr_diffuse_fnweight; + float ssr_diffuse_fdweight; + float ssr_diffuse_faoweight; + float ssr_diffuse_debug_a; + float ssr_diffuse_debug_b; + float ssr_diffuse_debug_c; + float ssr_diffuse_debug_d; + char _pad[4]; float volumetric_start; float volumetric_end; @@ -1836,7 +1858,7 @@ typedef struct SceneEEVEE { float light_threshold; int gameflag, smaa_quality; // UPBGE - float smaa_predication_scale, _pad; // UPBGE + float smaa_predication_scale, _pad0; // UPBGE } SceneEEVEE; diff --git a/source/tools b/source/tools index b22d19e47f4d..9f82f09bd322 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit b22d19e47f4d0353082f3d9f30ee8d244c5266d5 +Subproject commit 9f82f09bd322247496471e1c31ee92dc5c52ac8d From b1a59cbd8ed0c3a38c7a181b4c15fa06282016d0 Mon Sep 17 00:00:00 2001 From: e2002e Date: Wed, 14 Sep 2022 22:36:57 +0200 Subject: [PATCH 2/2] reapplied patch to get all options from the ssgi module --- .../eevee/shaders/bsdf_common_lib.glsl | 52 +++++++ .../eevee/shaders/bsdf_sampling_lib.glsl | 28 ++++ .../shaders/closure_eval_diffuse_lib.glsl | 14 +- .../engines/eevee/shaders/lightprobe_lib.glsl | 2 +- source/blender/makesrna/intern/rna_scene.c | 140 ++++++++++++++++++ 5 files changed, 232 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 4ee21cf8c2e7..e3c684877bb0 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -130,6 +130,58 @@ float bsdf_ggx(vec3 N, vec3 L, vec3 V, float roughness) return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ } +/* SSGI placeholder testing BSDF !TODO lambertian! */ + +float G1_Smith_GGX_GI(float NX, float a2) //Temp TODO +{ + /* Using Brian Karis approach and refactoring by NX/NX + * this way the (2*NL)*(2*NV) in G = G1(V) * G1(L) gets canceled by the brdf denominator 4*NL*NV + * Rcp is done on the whole G later + * Note that this is not convenient for the transmission formula */ + return NX + sqrt(NX * (NX - NX * a2) + a2); + /* return 2 / (1 + sqrt(1 + a2 * (1 - NX*NX) / (NX*NX) ) ); /* Reference function */ +} + +float bsdf_ggx_gi(vec3 N, vec3 L, vec3 V, float roughness) //Temp TODO +{ + //float a = roughness; + //float a2 = a * a; + float a = 1.0; + float a2 = 1.0; + + vec3 H = normalize(L + V); + float NH = max(dot(N, H), 1e-8); + float NL = max(dot(N, L), 1e-8); + float NV = max(dot(N, V), 1e-8); + + float G = G1_Smith_GGX_GI(NV, a2) * G1_Smith_GGX_GI(NL, a2); /* Doing RCP at the end */ + float D = D_ggx_opti(NH, a2); + + /* Denominator is canceled by G1_Smith */ + /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ + return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ +} + +float bsdf_gi(vec3 N, vec3 L, vec3 V) //Temp TODO //(vN, data.hit_dir / hit_dist, vV) +{ + // float a = 1.0; + // float a2 = 1.0; + + // vec3 H = normalize(L + V); + // float NH = max(dot(N, H), 1e-8); + // float NL = max(dot(N, L), 1e-8); + // float NV = max(dot(N, V), 1e-8); + + // float G = G1_Smith_GGX_GI(NV, a2) * G1_Smith_GGX_GI(NL, a2); /* Doing RCP at the end */ + // float D = D_ggx_opti(NH, a2); + + // /* Denominator is canceled by G1_Smith */ + // /* bsdf = D * G / (4.0 * NL * NV); /* Reference function */ + // return NL * a2 / (D * G); /* NL to Fit cycles Equation : line. 345 in bsdf_microfacet.h */ + + return 1.0 / 3.1415926538; +} + void accumulate_light(vec3 light, float fac, inout vec4 accum) { accum += vec4(light, 1.0) * min(fac, (1.0 - accum.a)); diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl index e0f52338914d..408a69504ae3 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl @@ -10,6 +10,8 @@ /** \name Microfacet GGX distribution * \{ */ +/* SSGI - TODO Lambert, cosine */ + #define USE_VISIBLE_NORMAL 1 float pdf_ggx_reflect(float NH, float NV, float VH, float alpha) @@ -71,6 +73,32 @@ vec3 sample_ggx(vec3 rand, float alpha, vec3 V, vec3 N, vec3 T, vec3 B, out floa return tangent_to_world(Ht, N, T, B); } +/* SSGI Temp TODO */ +/* + hammersley already available? */ +float pdf_ggx_reflect_gi(float NH, float a2) //Temp TODO +{ + return NH * a2 / D_ggx_opti(NH, a2); +} + +vec3 sample_ggx_gi(vec3 rand, float a2) //Temp TODO +{ + /* Theta is the cone angle. */ + float z = sqrt((1.0 - rand.x) / (1.0 + a2 * rand.x - rand.x)); /* cos theta */ + float r = sqrt(max(0.0, 1.0 - z * z)); /* sin theta */ + float x = r * rand.y; + float y = r * rand.z; + + /* Microfacet Normal */ + return vec3(x, y, z); +} + +vec3 sample_ggx_gi(vec3 rand, float a2, vec3 N, vec3 T, vec3 B, out float NH) +{ + vec3 Ht = sample_ggx_gi(rand, a2); + NH = Ht.z; + return tangent_to_world(Ht, N, T, B); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl index 4f9791ac95f5..45f29a3f6b7d 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl @@ -1,6 +1,7 @@ #pragma BLENDER_REQUIRE(lights_lib.glsl) #pragma BLENDER_REQUIRE(lightprobe_lib.glsl) #pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl) +#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl) struct ClosureInputDiffuse { vec3 N; /** Shading normal. */ @@ -23,6 +24,8 @@ ClosureEvalDiffuse closure_Diffuse_eval_init(inout ClosureInputDiffuse cl_in, ClosureEvalCommon cl_common, out ClosureOutputDiffuse cl_out) { + /* TODO SSGI - don't call ensure_valid_reflection when not needed, fix edge cases (do in ssr_data? or add extra out for SSR normal)*/ + cl_in.N = ensure_valid_reflection(cl_common.Ng, cl_common.V, cl_in.N); cl_in.N = safe_normalize(cl_in.N); cl_out.radiance = vec3(0.0); @@ -67,14 +70,19 @@ void closure_Diffuse_indirect_end(ClosureInputDiffuse cl_in, { /* If not enough light has been accumulated from probes, use the world specular cubemap * to fill the remaining energy needed. */ - if (cl_common.diffuse_accum > 0.0) { + /* Extra toggle added for skipping diffuse probe contribution when it's done in SSGI*/ + if (cl_common.diffuse_accum > 0.0 && ssrDiffuseProbeTrace < 1) { vec3 probe_radiance = probe_evaluate_world_diff(cl_eval.probe_sampling_dir); cl_out.radiance += cl_common.diffuse_accum * probe_radiance; } /* Apply occlusion on radiance before the light loop. */ - cl_out.radiance *= cl_eval.ambient_occlusion; + float ao_transfer = 1.0 * cl_eval.ambient_occlusion; + + cl_out.radiance *= ao_transfer; + cl_out.AO = ao_transfer; //AO out for SSGI } + void closure_Diffuse_eval_end(ClosureInputDiffuse cl_in, ClosureEvalDiffuse cl_eval, ClosureEvalCommon cl_common, @@ -85,4 +93,4 @@ void closure_Diffuse_eval_end(ClosureInputDiffuse cl_in, cl_out.radiance = vec3(0.0); return; #endif -} +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index 29118237b24e..3f19074fff46 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -364,4 +364,4 @@ vec3 evaluate_diffuse_probe_ssgi(vec3 N) //TODO: routine for probe selection return vec3(0); } return irradiance_from_cell_get(0, N); -} \ No newline at end of file +} diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 68227abc938e..db9bf0d193af 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -7817,6 +7817,146 @@ static void rna_def_scene_eevee(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "ssr_diffuse_versioning", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Versioning", "Set settings to defaults if version number is lower than defined"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_intensity", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Intensity", "Diffuse bounce light intensity - 0.0 disables all tracing and resolve in shader"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 2); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_thickness", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_ui_text(prop, "Thickness", "Pixel thickness used to detect intersection for diffuse bounce"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 3.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_resolve_bias", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Resolve Bias", "Diffuse resolve bias - Higher values blur ray hit color sample, potentially reducing noise at the cost of accuracy. Can introduce noticable light bleeding."); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_quality", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Ray Length", "Diffuse trace ray stride length"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_clamp", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Clamp", "Firefly filter for diffuse resolve"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_ao", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Occlusion", "Multiply SSGI output with AO"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_ao_limit", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Occlusion Limit", "Clamps multiplied AO lower values to avoid pitch black areas"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_filter", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Denoise Mix", "Mixes raw SSGI output with denoised output"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_fsize", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Filter Size", "Denoise filter kernel size"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 32.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_fsamples", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Skip Denoising on first sample", "Starts denosing at specified render sample"); + //RNA_def_property_range(prop, 1, 2); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_fnweight", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Filter Normal Weight", "Filter normal weight"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0, 1.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_fdweight", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Filter Depth Weight", "Filter depth weight"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_faoweight", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Filter AO Weight", "Filter AO weight"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_probe_trace", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Enable Probe tracing (Experimental)", "Replaces probe lighting contribution with SSGI traced probes"); + //RNA_def_property_range(prop, 0, 1); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + + prop = RNA_def_property(srna, "ssr_diffuse_probe_intensity", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Injected Probe GI intensity", "GI intensity from injected probes"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_probe_clamp", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Injected Probe Clamp", "Clamps injected probes to remove noise at the cost of contrast"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 5.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_debug_a", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Debug A", ""); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 5.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_debug_b", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Debug B", ""); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 5.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_debug_c", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Debug C", ""); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 5.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + prop = RNA_def_property(srna, "ssr_diffuse_debug_d", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_ui_text(prop, "Debug D", ""); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 5.0f, 5, 3); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + + /* Volumetrics */ prop = RNA_def_property(srna, "volumetric_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_ui_text(prop, "Start", "Start distance of the volumetric effect");