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. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to