[Bf-blender-cvs] [5b6cfa705cb] blender2.8: Eevee: Irradiance Visibility: Initial Implementation

Clément Foucault noreply at git.blender.org
Mon Dec 4 10:19:38 CET 2017


Commit: 5b6cfa705cb180d042f6f27e45331c12972be7ae
Author: Clément Foucault
Date:   Sat Dec 2 14:28:29 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB5b6cfa705cb180d042f6f27e45331c12972be7ae

Eevee: Irradiance Visibility: Initial Implementation

This augment the existing irradiance grid with a new visibility precomputation.
We store a small shadowmap for each grid sample so that light does not leak through walls and such.

The visibility parameter are similar to the one used by the Variance Shadow Map for point lights.

Technical details:

We store the visibility in the same texture (array) as the irradiance itself (in order to reduce the number of sampler).
But the irradiance and the visibility are not the same data so we must encode them in order to use the same texture format.
We use RGBA8 normalized texture and encode irradiance as RGBE (shared exponent).
Using RGBE encoding instead of R11_G11_B10 may lead to some lighting changes, but quality seems to be nearly the same in my test cases.
Using full RGBA16/32F maybe a future option but that will require much more memory and reduce the perf significantly.

Visibility moments (VSM) are encoded as 16bits fixed point precision using a special range. This seems to retain enough precision for the needs.
Also interpolation does not seems to be big problem (even though it's incorrect).

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/engines/eevee/eevee_data.c
M	source/blender/draw/engines/eevee/eevee_lightprobes.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_volumes.c
M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
M	source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
A	source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
M	source/blender/draw/engines/eevee/shaders/lightprobe_grid_fill_frag.glsl
M	source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
M	source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 9c806f26fda..8339b6b8720 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -137,6 +137,7 @@ data_to_c_simple(engines/eevee/shaders/lamps_lib.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_geom.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_vert.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/lightprobe_cube_display_frag.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index d1cd1b1440c..d5582a498a4 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -55,6 +55,7 @@ static void eevee_view_layer_data_free(void *storage)
 	DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_fb);
 	DRW_FRAMEBUFFER_FREE_SAFE(sldata->probe_filter_fb);
 	DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
+	DRW_TEXTURE_FREE_SAFE(sldata->probe_depth_rt);
 	DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
 	DRW_TEXTURE_FREE_SAFE(sldata->irradiance_pool);
 	DRW_TEXTURE_FREE_SAFE(sldata->irradiance_rt);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 32b5023c65e..a83562e81ce 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -47,11 +47,13 @@
 #include "ED_screen.h"
 
 #define IRRADIANCE_POOL_SIZE 1024
+#define HAMMERSLEY_SIZE 1024
 
 static struct {
 	struct GPUShader *probe_default_sh;
 	struct GPUShader *probe_filter_glossy_sh;
 	struct GPUShader *probe_filter_diffuse_sh;
+	struct GPUShader *probe_filter_visibility_sh;
 	struct GPUShader *probe_grid_fill_sh;
 	struct GPUShader *probe_grid_display_sh;
 	struct GPUShader *probe_planar_display_sh;
@@ -62,7 +64,6 @@ static struct {
 	struct GPUTexture *planar_pool_placeholder;
 	struct GPUTexture *depth_placeholder;
 	struct GPUTexture *depth_array_placeholder;
-	struct GPUTexture *cube_face_depth;
 	struct GPUTexture *cube_face_minmaxz;
 
 	int update_world;
@@ -73,6 +74,7 @@ extern char datatoc_background_vert_glsl[];
 extern char datatoc_default_world_frag_glsl[];
 extern char datatoc_lightprobe_filter_glossy_frag_glsl[];
 extern char datatoc_lightprobe_filter_diffuse_frag_glsl[];
+extern char datatoc_lightprobe_filter_visibility_frag_glsl[];
 extern char datatoc_lightprobe_geom_glsl[];
 extern char datatoc_lightprobe_vert_glsl[];
 extern char datatoc_lightprobe_planar_display_frag_glsl[];
@@ -159,6 +161,7 @@ static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
 
 void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
 {
+	bool update_all = false;
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 	ViewLayer *view_layer = draw_ctx->view_layer;
 	IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
@@ -176,7 +179,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
 
 		e_data.probe_filter_glossy_sh = DRW_shader_create(
 		        datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str,
-		        "#define HAMMERSLEY_SIZE 1024\n"
+		        "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
 		        "#define NOISE_SIZE 64\n");
 
 		e_data.probe_default_sh = DRW_shader_create(
@@ -200,7 +203,21 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
 #elif defined(IRRADIANCE_HL2)
 		        "#define IRRADIANCE_HL2\n"
 #endif
-		        "#define HAMMERSLEY_SIZE 1024\n"
+		        "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
+		        "#define NOISE_SIZE 64\n");
+
+		MEM_freeN(shader_str);
+
+		ds_frag = BLI_dynstr_new();
+		BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+		BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
+		BLI_dynstr_append(ds_frag, datatoc_lightprobe_filter_visibility_frag_glsl);
+		shader_str = BLI_dynstr_get_cstring(ds_frag);
+		BLI_dynstr_free(ds_frag);
+
+		e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen(
+		        shader_str,
+		        "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
 		        "#define NOISE_SIZE 64\n");
 
 		MEM_freeN(shader_str);
@@ -260,7 +277,7 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
 		        datatoc_lightprobe_planar_downsample_frag_glsl,
 		        NULL);
 
-		e_data.hammersley = create_hammersley_sample_texture(1024);
+		e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE);
 	}
 
 	if (!sldata->probes) {
@@ -275,21 +292,15 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
 	}
 
 	int prop_bounce_num = BKE_collection_engine_property_value_get_int(props, "gi_diffuse_bounces");
-	/* Update all probes if number of bounces mismatch. */
 	if (sldata->probes->num_bounce != prop_bounce_num) {
-		e_data.update_world |= PROBE_UPDATE_ALL;
-		sldata->probes->updated_bounce = 0;
-		sldata->probes->grid_initialized = false;
+		sldata->probes->num_bounce = prop_bounce_num;
+		update_all = true;
 	}
-	sldata->probes->num_bounce = prop_bounce_num;
 
 	int prop_cubemap_res = BKE_collection_engine_property_value_get_int(props, "gi_cubemap_resolution");
 	if (sldata->probes->cubemap_res != prop_cubemap_res) {
 		sldata->probes->cubemap_res = prop_cubemap_res;
-
-		e_data.update_world |= PROBE_UPDATE_ALL;
-		sldata->probes->updated_bounce = 0;
-		sldata->probes->grid_initialized = false;
+		update_all = true;
 
 		sldata->probes->target_size = prop_cubemap_res >> 1;
 
@@ -297,25 +308,27 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(veda
 		DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
 	}
 
-	/* Setup Render Target Cubemap */
-
-	/* We do this detach / attach dance to not generate an invalid framebuffer (mixed cubemap / 2D map) */
-	if (sldata->probe_rt) {
-		/* XXX Silly,TODO Cleanup this mess */
-		DRW_framebuffer_texture_detach(sldata->probe_rt);
+	int visibility_res = BKE_collection_engine_property_value_get_int(props, "gi_visibility_resolution");
+	if (sldata->probes->irradiance_vis_size != visibility_res) {
+		sldata->probes->irradiance_vis_size = visibility_res;
+		update_all = true;
 	}
 
-	DRWFboTexture tex_probe = {&e_data.cube_face_depth, DRW_TEX_DEPTH_24, DRW_TEX_TEMP};
-	DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, sldata->probes->target_size, sldata->probes->target_size, &tex_probe, 1);
+	if (update_all) {
+		e_data.update_world |= PROBE_UPDATE_ALL;
+		sldata->probes->updated_bounce = 0;
+		sldata->probes->grid_initialized = false;
+	}
 
+	/* Setup Render Target Cubemap */
 	if (!sldata->probe_rt) {
+		sldata->probe_depth_rt = DRW_texture_create_cube(sldata->probes->target_size, DRW_TEX_DEPTH_24, 0, NULL);
 		sldata->probe_rt = DRW_texture_create_cube(sldata->probes->target_size, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
 	}
 
-	if (sldata->probe_rt) {
-		/* XXX Silly,TODO Cleanup this mess */
-		DRW_framebuffer_texture_attach(sldata->probe_fb, sldata->probe_rt, 0, 0);
-	}
+	DRWFboTexture tex_probe[2] = {{&sldata->probe_depth_rt, DRW_TEX_DEPTH_24, 0},
+	                              {&sldata->probe_rt, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP}};
+	DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, sldata->probes->target_size, sldata->probes->target_size, tex_probe, 2);
 
 	/* Minmaxz Pyramid */
 	// DRWFboTexture tex_minmaxz = {&e_data.cube_face_minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP};
@@ -434,11 +447,30 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
 		DRW_shgroup_call_add(grp, geom, NULL);
 	}
 
+	{
+		psl->probe_visibility_compute = DRW_pass_create("LightProbe Visibility Compute", DRW_STATE_WRITE_COLOR);
+
+		DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_visibility_sh, psl->probe_visibility_compute);
+		DRW_shgroup_uniform_int(grp, "outputSize", &sldata->probes->shres, 1);
+		DRW_shgroup_uniform_float(grp, "visibilityRange", &sldata->probes->visibility_range, 1);
+		DRW_shgroup_uniform_float(grp, "visibilityBlur", &sldata->probes->visibility_blur, 1);
+		DRW_shgroup_uniform_float(grp, "sampleCount", &sldata->probes->samples_ct, 1);
+		DRW_shgroup_uniform_float(grp, "invSampleCount", &sldata->probes->invsamples_ct, 1);
+		DRW_shgroup_uniform_float(grp, "storedTexelSize", &sldata->probes->texel_size, 1);
+		DRW_shgroup_uniform_float(grp, "nearClip", &sldata->probes->near_clip, 1);
+		DRW_shgroup_uniform_float(grp, "farClip", &sldata->probes->far_clip, 1);
+		DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
+		DRW_shgroup_uniform_texture(grp, "probeDepth", sldata->probe_depth_rt);
+
+		struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
+		DRW_shgroup_call_add(grp, geom, NULL);
+	}
+
 	{
 		psl->probe_grid_fill = DRW_pass_create("LightProbe Grid Floodfill", DRW_STATE_WRITE_COLOR);
 
 		DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_grid_fill_sh, psl->probe_grid_fill);
-		DRW_shgroup_uniform_buffer(grp, "gridTexture", &sldata->irradiance_pool);
+		DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
 
 		struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
 		DRW_shgroup_call_add(grp, geom, NULL);
@@ -751,6 +783,13 @@ static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassLis
 
 		copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x);
 
+		/* Visibility bias */
+		egrid->visibility_bias = 0.05f * probe->vis_bias;
+		egrid->visibility_bleed = probe->vis_bleedbias;
+		egrid->visibility_range = max_ff(max_ff(len_v3(egrid->increment_x),
+		                                        len_v3(egrid->increment_y)),
+		                                       

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list