[Bf-blender-cvs] [7f3ea60aa73] temp-eeveelightcache: Eevee: Add back planar reflection.

Clément Foucault noreply at git.blender.org
Thu Jun 28 15:55:01 CEST 2018


Commit: 7f3ea60aa73420765b589ced96d75e2678538f86
Author: Clément Foucault
Date:   Mon Jun 25 17:41:47 2018 +0200
Branches: temp-eeveelightcache
https://developer.blender.org/rB7f3ea60aa73420765b589ced96d75e2678538f86

Eevee: Add back planar reflection.

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

M	source/blender/draw/engines/eevee/eevee_engine.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_render.c
M	source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 215bd183f7e..7e66752368b 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -146,7 +146,7 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
 				/* TODO: Special case for dupli objects because we cannot save the object pointer. */
 			}
 			else {
-				EEVEE_lightprobes_cache_add(sldata, ob);
+				EEVEE_lightprobes_cache_add(sldata, vedata, ob);
 			}
 		}
 		else if (ob->type == OB_LAMP) {
@@ -282,7 +282,9 @@ static void eevee_draw_background(void *vedata)
 		EEVEE_subsurface_compute(sldata, vedata);
 		EEVEE_reflection_compute(sldata, vedata);
 		EEVEE_occlusion_draw_debug(sldata, vedata);
-		DRW_draw_pass(psl->probe_display);
+		if (psl->probe_display) {
+			DRW_draw_pass(psl->probe_display);
+		}
 		EEVEE_refraction_compute(sldata, vedata);
 
 		/* Opaque refraction */
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index e10bdfb26b8..a8ad25bc7c6 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -103,6 +103,33 @@ extern char datatoc_bsdf_sampling_lib_glsl[];
 extern GlobalsUboStorage ts;
 
 /* *********** FUNCTIONS *********** */
+
+/* TODO find a better way than this. This does not support dupli objects if
+ * the original object is hidden. */
+bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data)
+{
+	EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data;
+
+	/* test disabled if group is NULL */
+	if (oed->test_data->collection == NULL)
+		return vis_in;
+
+	if (oed->test_data->cached == false)
+		oed->ob_vis_dirty = true;
+
+	/* early out, don't need to compute ob_vis yet. */
+	if (vis_in == false)
+		return vis_in;
+
+	if (oed->ob_vis_dirty) {
+		oed->ob_vis_dirty = false;
+		oed->ob_vis = BKE_collection_has_object_recursive(oed->test_data->collection, oed->ob);
+		oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis;
+	}
+
+	return vis_in && oed->ob_vis;
+}
+
 static struct GPUTexture *create_hammersley_sample_texture(int samples)
 {
 	struct GPUTexture *tex;
@@ -122,6 +149,39 @@ static struct GPUTexture *create_hammersley_sample_texture(int samples)
 	return tex;
 }
 
+static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
+{
+	EEVEE_TextureList *txl = vedata->txl;
+
+	/* XXX TODO OPTIMISATION : 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 width = (int)(viewport_size[0] * screen_percentage);
+	int height = (int)(viewport_size[1] * screen_percentage);
+
+	/* We need an Array texture so allocate it ourself */
+	if (!txl->planar_pool) {
+		if (num_planar_ref > 0) {
+			txl->planar_pool = DRW_texture_create_2D_array(width, height, max_ff(1, 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_ff(1, 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 bound to shader. */
+			txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
+			txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
+		}
+	}
+}
+
 static void lightprobe_shaders_init(void)
 {
 	const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
@@ -240,7 +300,6 @@ static void lightprobe_shaders_init(void)
 void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 {
 	EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
-	EEVEE_TextureList *txl = vedata->txl;
 	EEVEE_StorageList *stl = vedata->stl;
 
 	const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -281,10 +340,9 @@ void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 	common_data->ssr_toggle = true;
 	common_data->sss_toggle = true;
 
-	if (!txl->planar_pool) {
-		/* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */
-		txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
-		txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
+	/* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */
+	if (!e_data.planar_pool_placeholder) {
+		e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL);
 	}
 }
 
@@ -374,6 +432,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
 	const DRWContextState *draw_ctx = DRW_context_state_get();
 	const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
 
+	pinfo->num_planar = 0;
+
 	{
 		psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
 
@@ -419,7 +479,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
 		}
 	}
 
-	{
+	if (DRW_state_draw_support()) {
 		DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
 		psl->probe_display = DRW_pass_create("LightProbe Display", state);
 
@@ -468,6 +528,9 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
 		stl->g_data->planar_display_shgrp = grp;
 		DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
 	}
+	else {
+		stl->g_data->planar_display_shgrp = NULL;
+	}
 
 	{
 		psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR);
@@ -479,8 +542,66 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
 	}
 }
 
-void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
+static bool eevee_lightprobes_culling_test(Object *ob)
 {
+	LightProbe *probe = (LightProbe *)ob->data;
+
+	switch (probe->type) {
+		case LIGHTPROBE_TYPE_PLANAR:
+		{
+			/* See if this planar probe is inside the view frustum. If not, no need to update it. */
+			/* NOTE: this could be bypassed if we want feedback loop mirrors for rendering. */
+			BoundBox bbox; float tmp[4][4];
+			const float min[3] = {-1.0f, -1.0f, -1.0f};
+			const float max[3] = { 1.0f,  1.0f,  1.0f};
+			BKE_boundbox_init_from_minmax(&bbox, min, max);
+
+			copy_m4_m4(tmp, ob->obmat);
+			normalize_v3(tmp[2]);
+			mul_v3_fl(tmp[2], probe->distinf);
+
+			for (int v = 0; v < 8; ++v) {
+				mul_m4_v3(tmp, bbox.vec[v]);
+			}
+			return DRW_culling_box_test(&bbox);
+		}
+		case LIGHTPROBE_TYPE_CUBE:
+			return true; /* TODO */
+		case LIGHTPROBE_TYPE_GRID:
+			return true; /* TODO */
+	}
+	BLI_assert(0);
+	return true;
+}
+
+void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *ob)
+{
+	EEVEE_LightProbesInfo *pinfo = sldata->probes;
+	LightProbe *probe = (LightProbe *)ob->data;
+
+	if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) ||
+	    (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) ||
+	    (probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR))
+	{
+		printf("Too many probes in the view !!!\n");
+		return;
+	}
+
+	if (probe->type == LIGHTPROBE_TYPE_PLANAR) {
+		if (!eevee_lightprobes_culling_test(ob)) {
+			return; /* Culled */
+		}
+		EEVEE_lightprobes_planar_data_from_object(ob,
+		                                          &pinfo->planar_data[pinfo->num_planar],
+		                                          &pinfo->planar_vis_tests[pinfo->num_planar]);
+		/* Debug Display */
+		DRWShadingGroup *grp = vedata->stl->g_data->planar_display_shgrp;
+		if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
+			DRW_shgroup_call_dynamic_add(grp, &pinfo->num_planar, ob->obmat);
+		}
+
+		pinfo->num_planar++;
+	}
 }
 
 void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *egrid, int *offset)
@@ -573,6 +694,85 @@ void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprob
 	invert_m4(eprobe->parallaxmat);
 }
 
+void EEVEE_lightprobes_planar_data_from_object(Object *ob, EEVEE_PlanarReflection *eplanar, EEVEE_LightProbeVisTest *vis_test)
+{
+	LightProbe *probe = (LightProbe *)ob->data;
+	float normat[4][4], imat[4][4];
+
+	vis_test->collection = probe->visibility_grp;
+	vis_test->invert = probe->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
+	vis_test->cached = false;
+
+	/* Computing mtx : matrix that mirror position around object's XY plane. */
+	normalize_m4_m4(normat, ob->obmat);  /* object > world */
+	invert_m4_m4(imat, normat); /* world > object */
+	/* XY reflection plane */
+	imat[0][2] = -imat[0][2];
+	imat[1][2] = -imat[1][2];
+	imat[2][2] = -imat[2][2];
+	imat[3][2] = -imat[3][2]; /* world > object > mirrored obj */
+	mul_m4_m4m4(eplanar->mtx, normat, imat); /* world > object > mirrored obj > world */
+
+	/* Compute clip plane equation / normal. */
+	copy_v3_v3(eplanar->plane_equation, ob->obmat[2]);
+	normalize_v3(eplanar->plane_equation); /* plane normal */
+	eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]);
+	eplanar->clipsta = probe->clipsta;
+
+	/* Compute XY clip planes. */
+	normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]);
+	normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]);
+
+	float vec[3] = {0.0f, 0.0f, 0.0f};
+	vec[0] = 1.0f; vec[1] = 0.0f; vec[2] = 0.0f;
+	mul_m4_v3(ob->obmat, vec); /* Point on the edge */
+	eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list