[Bf-blender-cvs] [0bdf4e2f2d1] master: Show Background Image Beneath Transparent Objects (Cycles only)

Jeroen Bakker noreply at git.blender.org
Sat Oct 5 17:20:33 CEST 2019


Commit: 0bdf4e2f2d1cd9538ac0196db8c302c21d49c860
Author: Jeroen Bakker
Date:   Sat Oct 5 17:18:41 2019 +0200
Branches: master
https://developer.blender.org/rB0bdf4e2f2d1cd9538ac0196db8c302c21d49c860

Show Background Image Beneath Transparent Objects (Cycles only)

Camera background images were not shown under transparent objects.
This patch performs an alpha under for background images for cycles.

In order to see the difference the Film transparency needs to be turned on.

Note that workbench and EEVEE still needs to be adapted as they don't
write store alpha value in the viewport.

Side note. This implementation is already an improvement of the current behavior, what users are requesting. (Show background images underneath cycles viewport rendering.) It is clear that this patch still needs to be extended to workbench and eevee. For now that should be marked as a known limitation.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D5437

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

M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_view.c
M	source/blender/draw/intern/draw_view.h
M	source/blender/draw/modes/object_mode.c
M	source/blender/draw/modes/shaders/object_camera_image_frag.glsl

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

diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 6387cecc01f..66cf921d47d 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1171,7 +1171,7 @@ static void drw_engines_cache_finish(void)
   MEM_freeN(DST.vedata_array);
 }
 
-static void drw_engines_draw_background(void)
+static bool drw_engines_draw_background(void)
 {
   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
     DrawEngineType *engine = link->data;
@@ -1185,10 +1185,20 @@ static void drw_engines_draw_background(void)
       DRW_stats_group_end();
 
       PROFILE_END_UPDATE(data->background_time, stime);
-      return;
+      return true;
     }
   }
 
+  /* No draw engines draw the background. We clear the background.
+   * We draw the background after drawing of the scene so the camera background
+   * images can be drawn using ALPHA Under. Otherwise the background always
+   * interferred with the alpha blending */
+  DRW_clear_background();
+  return false;
+}
+
+static void drw_draw_background_alpha_under(void)
+{
   /* No draw_background found, doing default background */
   const bool do_alpha_checker = !DRW_state_draw_background();
   DRW_draw_background(do_alpha_checker);
@@ -1685,7 +1695,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
 
   DRW_hair_update();
 
-  drw_engines_draw_background();
+  const bool background_drawn = drw_engines_draw_background();
 
   GPU_framebuffer_bind(DST.default_framebuffer);
 
@@ -1696,6 +1706,10 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
 
   drw_engines_draw_scene();
 
+  if (!background_drawn) {
+    drw_draw_background_alpha_under();
+  }
+
   /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
   GPU_flush();
 
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 7aa2e007f79..58643eb12a8 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -41,11 +41,9 @@
 #include "BKE_object.h"
 #include "BKE_paint.h"
 
-#include "DRW_render.h"
-
 #include "view3d_intern.h"
 
-#include "draw_view.h"
+#include "draw_manager.h"
 
 /* ******************** region info ***************** */
 
@@ -60,18 +58,17 @@ void DRW_draw_region_info(void)
 }
 
 /* ************************* Background ************************** */
+void DRW_clear_background()
+{
+  GPU_clear_color(0.0, 0.0, 0.0, 0.0);
+  GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT);
+}
 
 void DRW_draw_background(bool do_alpha_checker)
 {
-  /* Just to make sure */
-  glDepthMask(GL_TRUE);
-  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-  glStencilMask(0xFF);
-
+  drw_state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_UNDER_PREMUL);
   if (do_alpha_checker) {
     /* Transparent render, do alpha checker. */
-    GPU_depth_test(false);
-
     GPU_matrix_push();
     GPU_matrix_identity_set();
     GPU_matrix_identity_projection_set();
@@ -79,18 +76,11 @@ void DRW_draw_background(bool do_alpha_checker)
     imm_draw_box_checker_2d(-1.0f, -1.0f, 1.0f, 1.0f);
 
     GPU_matrix_pop();
-
-    GPU_clear(GPU_DEPTH_BIT | GPU_STENCIL_BIT);
-
-    GPU_depth_test(true);
   }
-  else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+  else {
     float m[4][4];
     unit_m4(m);
 
-    /* Gradient background Color */
-    GPU_depth_test(false);
-
     GPUVertFormat *format = immVertexFormat();
     uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
     uint color = GPU_vertformat_attr_add(
@@ -103,8 +93,8 @@ void DRW_draw_background(bool do_alpha_checker)
 
     immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR_DITHER);
 
-    UI_GetThemeColor3ubv(TH_BACK_GRAD, col_lo);
     UI_GetThemeColor3ubv(TH_BACK, col_hi);
+    UI_GetThemeColor3ubv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_BACK_GRAD : TH_BACK, col_lo);
 
     immBegin(GPU_PRIM_TRI_FAN, 4);
     immAttr3ubv(color, col_lo);
@@ -119,16 +109,6 @@ void DRW_draw_background(bool do_alpha_checker)
     immUnbindProgram();
 
     GPU_matrix_pop();
-
-    GPU_clear(GPU_DEPTH_BIT | GPU_STENCIL_BIT);
-
-    GPU_depth_test(true);
-  }
-  else {
-    /* Solid background Color */
-    UI_ThemeClearColorAlpha(TH_BACK, 1.0f);
-
-    GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT | GPU_STENCIL_BIT);
   }
 }
 
diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h
index 715c3c0d40c..7be186f1c72 100644
--- a/source/blender/draw/intern/draw_view.h
+++ b/source/blender/draw/intern/draw_view.h
@@ -24,6 +24,7 @@
 #define __DRAW_VIEW_H__
 
 void DRW_draw_region_info(void);
+void DRW_clear_background(void);
 void DRW_draw_background(bool do_alpha_checker);
 void DRW_draw_cursor(void);
 void DRW_draw_gizmo_3d(void);
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 05a915185df..ec19c731e96 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -122,8 +122,9 @@ typedef struct OBJECT_PassList {
   struct DRWPass *bone_axes[2];
   struct DRWPass *particle;
   struct DRWPass *lightprobes;
-  struct DRWPass *camera_images_back;
-  struct DRWPass *camera_images_front;
+  struct DRWPass *camera_images_back_alpha_under;
+  struct DRWPass *camera_images_back_alpha_over;
+  struct DRWPass *camera_images_front_alpha_over;
 } OBJECT_PassList;
 
 typedef struct OBJECT_FramebufferList {
@@ -991,13 +992,19 @@ static void DRW_shgroup_empty_image(OBJECT_Shaders *sh_data,
   }
 }
 
-/* Draw Camera Background Images */
+/* -------------------------------------------------------------------- */
+/** \name Camera Background Images
+ * \{ */
 typedef struct CameraEngineData {
   DrawData dd;
   ListBase bg_data;
 } CameraEngineData;
+
 typedef struct CameraEngineBGData {
+  CameraBGImage *camera_image;
+  GPUTexture *texture;
   float transform_mat[4][4];
+  bool premultiplied;
 } CameraEngineBGData;
 
 static void camera_engine_data_free(DrawData *dd)
@@ -1032,6 +1039,26 @@ static void camera_background_images_stereo_setup(Scene *scene,
     iuser->flag &= ~IMA_SHOW_STEREO;
   }
 }
+static void camera_background_images_add_shgroup(DRWPass *pass,
+                                                 CameraEngineBGData *bg_data,
+                                                 GPUShader *shader,
+                                                 GPUBatch *batch)
+{
+  CameraBGImage *camera_image = bg_data->camera_image;
+  DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+
+  DRW_shgroup_uniform_float_copy(
+      grp, "depth", camera_image->flag & CAM_BGIMG_FLAG_FOREGROUND ? 0.000001f : 0.999999f);
+  DRW_shgroup_uniform_float_copy(grp, "alpha", camera_image->alpha);
+  DRW_shgroup_uniform_texture(grp, "image", bg_data->texture);
+  DRW_shgroup_uniform_bool_copy(grp, "imagePremultiplied", bg_data->premultiplied);
+  DRW_shgroup_uniform_float_copy(
+      grp, "flipX", (camera_image->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0);
+  DRW_shgroup_uniform_float_copy(
+      grp, "flipY", (camera_image->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0);
+  DRW_shgroup_uniform_mat4(grp, "TransformMat", bg_data->transform_mat);
+  DRW_shgroup_call(grp, batch, NULL);
+}
 
 static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data,
                                                  OBJECT_PassList *psl,
@@ -1255,25 +1282,46 @@ static void DRW_shgroup_camera_background_images(OBJECT_Shaders *sh_data,
                     scale_m4,
                     uv2img_space);
 
-      DRWPass *pass = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? psl->camera_images_front :
-                                                                  psl->camera_images_back;
-      GPUShader *shader = DRW_state_do_color_management() ? sh_data->object_camera_image_cm :
-                                                            sh_data->object_camera_image;
-      DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+      /* Keep the references so we can reverse the loop */
+      bg_data->camera_image = bgpic;
+      bg_data->texture = tex;
+      bg_data->premultiplied = premultiplied;
+    }
 
-      DRW_shgroup_uniform_float_copy(
-          grp, "depth", (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) ? 0.000001 : 0.999999);
-      DRW_shgroup_uniform_float_copy(grp, "alpha", bgpic->alpha);
-      DRW_shgroup_uniform_texture(grp, "image", tex);
-      DRW_shgroup_uniform_bool_copy(grp, "imagePremultiplied", premultiplied);
+    /* Mark the rest bg_data's to be reused in the next drawing call */
+    LinkData *last_node = list_node ? list_node->prev : camera_engine_data->bg_data.last;
+    while (list_node != NULL) {
+      CameraEngineBGData *bg_data = (CameraEngineBGData *)list_node->data;
+      bg_data->texture = NULL;
+      bg_data->camera_image = NULL;
+      list_node = list_node->next;
+    }
 
-      DRW_shgroup_uniform_float_copy(
-          grp, "flipX", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) ? -1.0 : 1.0);
-      DRW_shgroup_uniform_float_copy(
-          grp, "flipY", (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) ? -1.0 : 1.0);
-      DRW_shgroup_uniform_mat4(grp, "TransformMat", bg_data->transform_mat);
+    GPUShader *shader = DRW_state_do_color_management() ? sh_data->object_camera_image_cm :
+                                                          sh_data->object_camera_image;
+    /* loop 1: camera images alpha under */
+    for (list_node = last_node; list_node; list_node = list_node->prev) {
+      CameraEngineBGData *bg_data = (CameraEngineBGData *)list_node->data;
+      CameraBGImage *camera_image = bg_data->camera_image;
+      if ((camera_image->flag & CAM_BGIMG_FLAG_FOREGROUND) == 0) {
+        camera_background_images_add_shgroup(
+            psl->camera_images_back_alpha_under, bg_data, shader, batch);
+      }
+    }
 
-      DRW_shgroup_call(grp, batch, NULL);
+    /* loop 2: camera images alpha over */
+    for (list_node = camera_engine_data->bg_data.first; list_node; list_node = list_node->next) {
+      CameraEngineBGData *bg_data = (CameraEngineBGData *)list_node->data;
+      CameraBGImage *camera_image = bg_data->camera_image;
+      i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list