Eevee: Make Planar reflections work with the new DRWView system
authorClément Foucault <foucault.clem@gmail.com>
Tue, 21 May 2019 15:53:49 +0000 (17:53 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Wed, 22 May 2019 11:29:05 +0000 (13:29 +0200)
Also get rid of clip_block which did the same as clipplanes inside
common_view_lib.glsl.

source/blender/draw/engines/eevee/eevee_data.c
source/blender/draw/engines/eevee/eevee_engine.c
source/blender/draw/engines/eevee/eevee_lightcache.c
source/blender/draw/engines/eevee/eevee_lightprobes.c
source/blender/draw/engines/eevee/eevee_materials.c
source/blender/draw/engines/eevee/eevee_private.h
source/blender/draw/engines/eevee/eevee_render.c
source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
source/blender/draw/intern/draw_manager_data.c

index b7b8702..0ce2712 100644 (file)
@@ -62,7 +62,6 @@ void EEVEE_view_layer_data_free(void *storage)
   DRW_UBO_FREE_SAFE(sldata->grid_ubo);
   DRW_UBO_FREE_SAFE(sldata->planar_ubo);
   DRW_UBO_FREE_SAFE(sldata->common_ubo);
-  DRW_UBO_FREE_SAFE(sldata->clip_ubo);
 }
 
 EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
index 35614ac..bb37f36 100644 (file)
@@ -79,9 +79,6 @@ static void eevee_engine_init(void *ved)
     sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
                                                   &sldata->common_data);
   }
-  if (sldata->clip_ubo == NULL) {
-    sldata->clip_ubo = DRW_uniformbuffer_create(sizeof(sldata->clip_data), &sldata->clip_data);
-  }
 
   /* EEVEE_effects_init needs to go first for TAA */
   EEVEE_effects_init(sldata, vedata, camera, false);
@@ -209,12 +206,22 @@ static void eevee_draw_background(void *vedata)
     /* Copy previous persmat to UBO data */
     copy_m4_m4(sldata->common_data.prev_persmat, stl->effects->prev_persmat);
 
+    /* Refresh Probes */
+    DRW_stats_group_start("Probes Refresh");
+    EEVEE_lightprobes_refresh(sldata, vedata);
+    EEVEE_lightprobes_refresh_planar(sldata, vedata);
+    DRW_stats_group_end();
+
+    /* Refresh shadows */
+    DRW_stats_group_start("Shadows");
+    EEVEE_draw_shadows(sldata, vedata, stl->effects->taa_view);
+    DRW_stats_group_end();
+
     if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) &&
         (stl->effects->taa_current_sample > 1) && !DRW_state_is_image_render() &&
         !taa_use_reprojection) {
       DRW_view_set_active(stl->effects->taa_view);
     }
-
     /* when doing viewport rendering the overrides needs to be recalculated for
      * every loop as this normally happens once inside
      * `EEVEE_temporal_sampling_init` */
@@ -223,21 +230,6 @@ static void eevee_draw_background(void *vedata)
       EEVEE_temporal_sampling_update_matrices(vedata);
     }
 
-    /* Refresh Probes */
-    DRW_stats_group_start("Probes Refresh");
-    EEVEE_lightprobes_refresh(sldata, vedata);
-    /* Probes refresh can have reset the current sample. */
-    if (stl->effects->taa_current_sample == 1) {
-      DRW_viewport_matrix_override_unset_all();
-    }
-    EEVEE_lightprobes_refresh_planar(sldata, vedata);
-    DRW_stats_group_end();
-
-    /* Refresh shadows */
-    DRW_stats_group_start("Shadows");
-    EEVEE_draw_shadows(sldata, vedata, stl->effects->taa_view);
-    DRW_stats_group_end();
-
     /* Set ray type. */
     sldata->common_data.ray_type = EEVEE_RAY_CAMERA;
     sldata->common_data.ray_depth = 0.0f;
@@ -301,9 +293,7 @@ static void eevee_draw_background(void *vedata)
     EEVEE_draw_effects(sldata, vedata);
     DRW_stats_group_end();
 
-    if ((stl->effects->taa_current_sample > 1)) {
-      DRW_view_set_active(NULL);
-    }
+    DRW_view_set_active(NULL);
   }
 
   /* Tonemapping and transfer result to default framebuffer. */
index 3e0e5f6..a3cab92 100644 (file)
@@ -724,9 +724,6 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
     sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
                                                   &sldata->common_data);
   }
-  if (sldata->clip_ubo == NULL) {
-    sldata->clip_ubo = DRW_uniformbuffer_create(sizeof(sldata->clip_data), &sldata->clip_data);
-  }
 
   /* HACK: set txl->color but unset it before Draw Manager frees it. */
   txl->color = lbake->rt_color;
index 9b193c3..90802a8 100644 (file)
@@ -679,22 +679,35 @@ void EEVEE_lightprobes_planar_data_from_object(Object *ob,
   eplanar->attenuation_bias = max_dist * -eplanar->attenuation_scale;
 }
 
-static void lightbake_planar_compute_render_matrices(EEVEE_PlanarReflection *eplanar,
-                                                     DRWMatrixState *r_matstate,
-                                                     const float viewmat[4][4],
-                                                     const float winmat[4][4])
+static void lightbake_planar_ensure_view(EEVEE_PlanarReflection *eplanar,
+                                         const DRWView *main_view,
+                                         DRWView **r_planar_view)
 {
+  float winmat[4][4], viewmat[4][4];
+  DRW_view_viewmat_get(main_view, viewmat, false);
   /* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */
-  copy_m4_m4(r_matstate->winmat, winmat);
+  DRW_view_winmat_get(main_view, winmat, false);
   /* Invert X to avoid flipping the triangle facing direction. */
-  r_matstate->winmat[0][0] = -r_matstate->winmat[0][0];
-  r_matstate->winmat[1][0] = -r_matstate->winmat[1][0];
-  r_matstate->winmat[2][0] = -r_matstate->winmat[2][0];
-  r_matstate->winmat[3][0] = -r_matstate->winmat[3][0];
+  winmat[0][0] = -winmat[0][0];
+  winmat[1][0] = -winmat[1][0];
+  winmat[2][0] = -winmat[2][0];
+  winmat[3][0] = -winmat[3][0];
   /* Reflect Camera Matrix. */
-  mul_m4_m4m4(r_matstate->viewmat, viewmat, eplanar->mtx);
-  /* Apply Projection Matrix. */
-  mul_m4_m4m4(r_matstate->persmat, r_matstate->winmat, r_matstate->viewmat);
+  mul_m4_m4m4(viewmat, viewmat, eplanar->mtx);
+
+  if (*r_planar_view == NULL) {
+    *r_planar_view = DRW_view_create(
+        viewmat, winmat, NULL, NULL, EEVEE_lightprobes_obj_visibility_cb);
+    /* Compute offset plane equation (fix missing texels near reflection plane). */
+    float clip_plane[4];
+    copy_v4_v4(clip_plane, eplanar->plane_equation);
+    clip_plane[3] += eplanar->clipsta;
+    /* Set clipping plane */
+    DRW_view_clip_planes_set(*r_planar_view, &clip_plane, 1);
+  }
+  else {
+    DRW_view_update(*r_planar_view, viewmat, winmat, NULL, NULL);
+  }
 }
 
 static void eevee_lightprobes_extract_from_cache(EEVEE_LightProbesInfo *pinfo, LightCache *lcache)
@@ -762,7 +775,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
     }
   }
 
-  if (pinfo->num_planar) {
+  if (pinfo->num_planar > 0) {
     EEVEE_PassList *psl = vedata->psl;
     EEVEE_TextureList *txl = vedata->txl;
     DRW_PASS_CREATE(psl->probe_planar_downsample_ps, DRW_STATE_WRITE_COLOR);
@@ -824,21 +837,16 @@ static void render_reflections(void (*callback)(int face, EEVEE_BakeRenderData *
                                EEVEE_PlanarReflection *planar_data,
                                int ref_count)
 {
-  DRWMatrixState matstate;
-
-  float original_viewmat[4][4], original_winmat[4][4];
-  DRW_viewport_matrix_get(original_viewmat, DRW_MAT_VIEW);
-  DRW_viewport_matrix_get(original_winmat, DRW_MAT_WIN);
-
+  EEVEE_StorageList *stl = user_data->vedata->stl;
+  DRWView *main_view = stl->effects->taa_view;
+  DRWView **views = stl->g_data->planar_views;
+  /* Prepare views at the same time for faster culling. */
   for (int i = 0; i < ref_count; ++i) {
-    /* Setup custom matrices */
-    lightbake_planar_compute_render_matrices(
-        planar_data + i, &matstate, original_viewmat, original_winmat);
-    invert_m4_m4(matstate.persinv, matstate.persmat);
-    invert_m4_m4(matstate.viewinv, matstate.viewmat);
-    invert_m4_m4(matstate.wininv, matstate.winmat);
-    DRW_viewport_matrix_override_set_all(&matstate);
+    lightbake_planar_ensure_view(&planar_data[i], main_view, &views[i]);
+  }
 
+  for (int i = 0; i < ref_count; ++i) {
+    DRW_view_set_active(views[i]);
     callback(i, user_data);
   }
 }
@@ -912,9 +920,9 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
   EEVEE_ViewLayerData *sldata = user_data->sldata;
   EEVEE_PassList *psl = vedata->psl;
   EEVEE_TextureList *txl = vedata->txl;
+  EEVEE_StorageList *stl = vedata->stl;
   EEVEE_FramebufferList *fbl = vedata->fbl;
   EEVEE_LightProbesInfo *pinfo = sldata->probes;
-  EEVEE_PlanarReflection *eplanar = pinfo->planar_data + layer;
 
   GPU_framebuffer_ensure_config(&fbl->planarref_fb,
                                 {GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_depth, layer),
@@ -930,18 +938,10 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
   txl->planar_pool = e_data.planar_pool_placeholder;
   txl->planar_depth = e_data.depth_array_placeholder;
 
-  /* Be sure that cascaded shadow maps are updated. */
   DRW_stats_group_start("Planar Reflection");
 
   /* Be sure that cascaded shadow maps are updated. */
-  EEVEE_draw_shadows(sldata, vedata, NULL /* TODO */);
-
-  /* Compute offset plane equation (fix missing texels near reflection plane). */
-  copy_v4_v4(sldata->clip_data.clip_planes[0], eplanar->plane_equation);
-  sldata->clip_data.clip_planes[0][3] += eplanar->clipsta;
-  /* Set clipping plane */
-  DRW_uniformbuffer_update(sldata->clip_ubo, &sldata->clip_data);
-  DRW_state_clip_planes_len_set(1);
+  EEVEE_draw_shadows(sldata, vedata, stl->g_data->planar_views[layer]);
 
   GPU_framebuffer_bind(fbl->planarref_fb);
   GPU_framebuffer_clear_depth(fbl->planarref_fb, 1.0);
index 45b0077..6757c8e 100644 (file)
@@ -386,7 +386,6 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
   DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
   DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
   DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
-  DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo);
 
   if (use_diffuse || use_glossy || use_refract) {
     DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
@@ -1024,14 +1023,12 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
     DRW_PASS_CREATE(psl->depth_pass_clip, state);
     stl->g_data->depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh,
                                                        psl->depth_pass_clip);
-    DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_clip, "clip_block", sldata->clip_ubo);
 
     state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES |
             DRW_STATE_CULL_BACK;
     DRW_PASS_CREATE(psl->depth_pass_clip_cull, state);
     stl->g_data->depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh,
                                                             psl->depth_pass_clip_cull);
-    DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_clip_cull, "clip_block", sldata->clip_ubo);
   }
 
   {
@@ -1055,16 +1052,12 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
     DRW_PASS_CREATE(psl->refract_depth_pass_clip, state);
     stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh,
                                                                psl->refract_depth_pass_clip);
-    DRW_shgroup_uniform_block(
-        stl->g_data->refract_depth_shgrp_clip, "clip_block", sldata->clip_ubo);
 
     state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES |
             DRW_STATE_CULL_BACK;
     DRW_PASS_CREATE(psl->refract_depth_pass_clip_cull, state);
     stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(
         e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull);
-    DRW_shgroup_uniform_block(
-        stl->g_data->refract_depth_shgrp_clip_cull, "clip_block", sldata->clip_ubo);
   }
 
   {
@@ -1509,7 +1502,6 @@ static void material_transparent(Material *ma,
   /* Depth prepass */
   if (use_prepass) {
     *shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
-    DRW_shgroup_uniform_block(*shgrp_depth, "clip_block", sldata->clip_ubo);
 
     cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
     cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
@@ -1747,7 +1739,6 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
 
         shgrp = DRW_shgroup_hair_create(
             ob, psys, md, psl->depth_pass_clip, e_data.default_hair_prepass_clip_sh);
-        DRW_shgroup_uniform_block(shgrp, "clip_block", sldata->clip_ubo);
 
         shgrp = NULL;
         if (ma->use_nodes && ma->nodetree) {
index c64f489..a44d138 100644 (file)
@@ -693,12 +693,6 @@ typedef struct EEVEE_CommonUniformBuffer {
 #define EEVEE_RAY_DIFFUSE 2
 #define EEVEE_RAY_GLOSSY 3
 
-/* ***************** CLIP PLANES DATA **************** */
-
-typedef struct EEVEE_ClipPlanesUniformBuffer {
-  float clip_planes[1][4]; /* must be less than MAX_CLIP_PLANES */
-} EEVEE_ClipPlanesUniformBuffer;
-
 /* ************** SCENE LAYER DATA ************** */
 typedef struct EEVEE_ViewLayerData {
   /* Lights */
@@ -734,9 +728,6 @@ typedef struct EEVEE_ViewLayerData {
   struct EEVEE_CommonUniformBuffer common_data;
   struct GPUUniformBuffer *common_ubo;
 
-  struct EEVEE_ClipPlanesUniformBuffer clip_data;
-  struct GPUUniformBuffer *clip_ubo;
-
   struct LightCache *fallback_lightcache;
 } EEVEE_ViewLayerData;
 
index e083d16..5141b37 100644 (file)
@@ -100,9 +100,6 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
     sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data),
                                                   &sldata->common_data);
   }
-  if (sldata->clip_ubo == NULL) {
-    sldata->clip_ubo = DRW_uniformbuffer_create(sizeof(sldata->clip_data), &sldata->clip_data);
-  }
 
   /* Set the pers & view matrix. */
   float winmat[4][4], viewmat[4][4], viewinv[4][4];
@@ -543,9 +540,6 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
     EEVEE_volumes_set_jitter(sldata, stl->effects->taa_current_sample - 1);
     EEVEE_materials_init(sldata, stl, fbl);
 
-    /* Set matrices. */
-    DRW_view_set_active(stl->effects->taa_view);
-
     /* Refresh Probes */
     EEVEE_lightprobes_refresh(sldata, vedata);
     EEVEE_lightprobes_refresh_planar(sldata, vedata);
@@ -562,6 +556,9 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
     EEVEE_lights_update(sldata, vedata);
     EEVEE_draw_shadows(sldata, vedata, stl->effects->taa_view);
 
+    /* Set matrices. */
+    DRW_view_set_active(stl->effects->taa_view);
+
     /* Set ray type. */
     sldata->common_data.ray_type = EEVEE_RAY_CAMERA;
     sldata->common_data.ray_depth = 0.0f;
index 2b9a325..cf20b3f 100644 (file)
@@ -7,13 +7,6 @@ in vec3 nor;
 out vec3 worldPosition;
 out vec3 viewPosition;
 
-/* Used for planar reflections */
-/* keep in sync with EEVEE_ClipPlanesUniformBuffer */
-layout(std140) uniform clip_block
-{
-  vec4 ClipPlanes[1];
-};
-
 out vec3 worldNormal;
 out vec3 viewNormal;
 
@@ -61,7 +54,7 @@ void main()
   gl_Position = point_world_to_ndc(worldPosition);
 
   /* Used for planar reflections */
-  gl_ClipDistance[0] = dot(vec4(worldPosition, 1.0), ClipPlanes[0]);
+  gl_ClipDistance[0] = dot(vec4(worldPosition, 1.0), clipPlanes[0]);
 
 #ifdef USE_ATTR
   pass_attr(pos);
index d133889..2c7e0ac 100644 (file)
@@ -1,12 +1,4 @@
 
-#ifdef CLIP_PLANES
-/* keep in sync with DRWManager.view_data */
-layout(std140) uniform clip_block
-{
-  vec4 ClipPlanes[1];
-};
-#endif
-
 #ifndef HAIR_SHADER
 in vec3 pos;
 #endif
@@ -40,7 +32,7 @@ void main()
   gl_Position = point_world_to_ndc(worldPosition);
 
 #ifdef CLIP_PLANES
-  gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), ClipPlanes[0]);
+  gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]);
 #endif
   /* TODO motion vectors */
 }
index 12f60b5..4e8544f 100644 (file)
@@ -1320,6 +1320,7 @@ DRWView *DRW_view_create(const float viewmat[4][4],
     view->culling_mask = 1u << DST.primary_view_ct++;
   }
   else {
+    BLI_assert(0);
     view->culling_mask = 0u;
   }
   view->clip_planes_len = 0;
@@ -1461,6 +1462,7 @@ void DRW_view_default_set(DRWView *view)
 /**
  * This only works if DRWPasses have been tagged with DRW_STATE_CLIP_PLANES,
  * and if the shaders have support for it (see usage of gl_ClipDistance).
+ * NOTE: planes must be in world space.
  */
 void DRW_view_clip_planes_set(DRWView *view, float (*planes)[4], int plane_len)
 {