[Bf-blender-cvs] [d2a1d222c08] tmp-overlay-engine: Overlay Engine: Add Camera & Stereo Camera

Clément Foucault noreply at git.blender.org
Fri Nov 15 01:35:02 CET 2019


Commit: d2a1d222c08766758cd282f71d244dd186659ddc
Author: Clément Foucault
Date:   Thu Nov 7 03:04:54 2019 +0100
Branches: tmp-overlay-engine
https://developer.blender.org/rBd2a1d222c08766758cd282f71d244dd186659ddc

Overlay Engine: Add Camera & Stereo Camera

This change a few thing:
- This fixes the toe-in convergence plane drawing issue.
- The volume wires are drawn without depth write to avoid Z-fighting.

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

M	source/blender/draw/engines/overlay/overlay_extra.c
M	source/blender/draw/engines/overlay/overlay_private.h
M	source/blender/draw/engines/overlay/shaders/extra_vert.glsl
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/modes/object_mode.c

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

diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index 9d4f4d513fd..908d9870f91 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -24,6 +24,12 @@
 
 #include "UI_resources.h"
 
+#include "BKE_camera.h"
+
+#include "DNA_camera_types.h"
+
+#include "DEG_depsgraph_query.h"
+
 #include "overlay_private.h"
 
 #include "draw_common.h"
@@ -176,12 +182,19 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
       DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
       DRW_shgroup_uniform_block_persistent(grp, "globalsBlock", G_draw.block_ubo);
 
-      cb->light_point = BUF_INSTANCE(grp, format, DRW_cache_light_point_lines_get());
-      cb->light_sun = BUF_INSTANCE(grp, format, DRW_cache_light_sun_lines_get());
-      cb->light_area[0] = BUF_INSTANCE(grp, format, DRW_cache_light_area_disk_lines_get());
-      cb->light_area[1] = BUF_INSTANCE(grp, format, DRW_cache_light_area_square_lines_get());
-      cb->light_spot = BUF_INSTANCE(grp, format, DRW_cache_light_spot_lines_get());
-
+      grp_sub = DRW_shgroup_create_sub(grp);
+      cb->light_point = BUF_INSTANCE(grp_sub, format, DRW_cache_light_point_lines_get());
+      cb->light_sun = BUF_INSTANCE(grp_sub, format, DRW_cache_light_sun_lines_get());
+      cb->light_area[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_disk_lines_get());
+      cb->light_area[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_square_lines_get());
+      cb->light_spot = BUF_INSTANCE(grp_sub, format, DRW_cache_light_spot_lines_get());
+
+      cb->camera_frame = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_frame_get());
+      cb->camera_tria[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_tria_wire_get());
+      cb->camera_tria[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_tria_get());
+      cb->camera_distances = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_distances_get());
+
+      /* TODO Own move to transparent pass. */
       grp_sub = DRW_shgroup_create_sub(grp);
       DRW_shgroup_state_enable(grp_sub, DRW_STATE_CULL_BACK | DRW_STATE_BLEND_ALPHA);
       DRW_shgroup_state_disable(grp_sub, DRW_STATE_WRITE_DEPTH);
@@ -193,6 +206,12 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
       DRW_shgroup_state_disable(grp_sub, DRW_STATE_WRITE_DEPTH);
       cb->light_spot_volume_inside = BUF_INSTANCE(
           grp_sub, format, DRW_cache_light_spot_volume_get());
+
+      grp_sub = DRW_shgroup_create_sub(grp);
+      DRW_shgroup_state_enable(grp_sub, DRW_STATE_CULL_BACK | DRW_STATE_BLEND_ALPHA);
+      DRW_shgroup_state_disable(grp_sub, DRW_STATE_WRITE_DEPTH);
+      cb->camera_volume = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_volume_get());
+      cb->camera_volume_frame = BUF_INSTANCE(grp_sub, format, DRW_cache_camera_volume_wire_get());
     }
     {
       format = formats->instance_pos;
@@ -282,6 +301,10 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
   }
 }
 
+/* -------------------------------------------------------------------- */
+/** \name Lights
+ * \{ */
+
 static void DRW_shgroup_light(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLayer *view_layer)
 {
   Light *la = ob->data;
@@ -357,6 +380,293 @@ static void DRW_shgroup_light(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLaye
   }
 }
 
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Camera
+ * \{ */
+
+typedef union OVERLAY_CameraInstanceData {
+  /* Pack render data into object matrix and object color. */
+  struct {
+    float color[4];
+    float mat[4][4];
+  };
+  struct {
+    float _pad0[2];
+    float volume_sta;
+    union {
+      float depth;
+      float focus;
+      float volume_end;
+    };
+    float _pad00[3];
+    union {
+      float corner_x;
+      float dist_color_id;
+    };
+    float _pad01[3];
+    union {
+      float corner_y;
+    };
+    float _pad02[3];
+    union {
+      float center_x;
+      float clip_sta;
+      float mist_sta;
+    };
+    float pos[3];
+    union {
+      float center_y;
+      float clip_end;
+      float mist_end;
+    };
+  };
+} OVERLAY_CameraInstanceData;
+
+static float camera_offaxis_shiftx_get(Scene *scene,
+                                       Object *ob,
+                                       const OVERLAY_CameraInstanceData *instdata,
+                                       bool right_eye)
+{
+  Camera *cam = ob->data;
+  if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
+    const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
+    const float shiftx = BKE_camera_multiview_shift_x(&scene->r, ob, viewnames[right_eye]);
+    const float delta_shiftx = shiftx - cam->shiftx;
+    const float width = instdata->corner_x * 2.0f;
+    return delta_shiftx * width;
+  }
+  else {
+    return 0.0;
+  }
+}
+/**
+ * Draw the stereo 3d support elements (cameras, plane, volume).
+ * They are only visible when not looking through the camera:
+ */
+static void camera_stereoscopy_extra(OVERLAY_ExtraCallBuffers *cb,
+                                     Scene *scene,
+                                     View3D *v3d,
+                                     Object *ob,
+                                     const OVERLAY_CameraInstanceData *instdata)
+{
+  OVERLAY_CameraInstanceData stereodata = *instdata;
+  Camera *cam = ob->data;
+  const bool is_select = DRW_state_is_select();
+  const char *viewnames[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
+
+  const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) != 0;
+  const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) != 0;
+  const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME) != 0;
+
+  for (int eye = 0; eye < 2; eye++) {
+    ob = BKE_camera_multiview_render(scene, ob, viewnames[eye]);
+    BKE_camera_multiview_model_matrix(&scene->r, ob, viewnames[eye], stereodata.mat);
+
+    stereodata.corner_x = instdata->corner_x;
+    stereodata.corner_y = instdata->corner_y;
+    stereodata.center_x = instdata->center_x + camera_offaxis_shiftx_get(scene, ob, instdata, eye);
+    stereodata.center_y = instdata->center_y;
+    stereodata.depth = instdata->depth;
+
+    if (is_stereo3d_cameras) {
+      DRW_buffer_add_entry_struct(cb->camera_frame, &stereodata);
+
+      /* Connecting line between cameras. */
+      /* TODO */
+      // DRW_buffer_add_entry(cb->relationship_lines, obmat[3]);
+    }
+
+    if (is_stereo3d_volume && !is_select) {
+      float r = (eye == 1) ? 2.0f : 1.0f;
+
+      stereodata.volume_sta = -cam->clip_start;
+      stereodata.volume_end = -cam->clip_end;
+      /* Encode eye + intensity and alpha (see shader) */
+      copy_v2_fl2(stereodata.color, r + 0.15f, 1.0f);
+      DRW_buffer_add_entry_struct(cb->camera_volume_frame, &stereodata);
+
+      if (v3d->stereo3d_volume_alpha > 0.0f) {
+        /* Encode eye + intensity and alpha (see shader) */
+        copy_v2_fl2(stereodata.color, r + 0.999f, v3d->stereo3d_volume_alpha);
+        DRW_buffer_add_entry_struct(cb->camera_volume, &stereodata);
+      }
+      /* restore */
+      copy_v3_v3(stereodata.color, instdata->color);
+    }
+  }
+
+  if (is_stereo3d_plane && !is_select) {
+    if (cam->stereo.convergence_mode == CAM_S3D_TOE) {
+      /* There is no real convergence plane but we highlight the center
+       * point where the views are pointing at. */
+      // zero_v3(stereodata.mat[0]); /* We reconstruct from Z and Y */
+      // zero_v3(stereodata.mat[1]); /* Y doesn't change */
+      zero_v3(stereodata.mat[2]);
+      zero_v3(stereodata.mat[3]);
+      for (int i = 0; i < 2; i++) {
+        float mat[4][4];
+        /* Need normalized version here. */
+        BKE_camera_multiview_model_matrix(&scene->r, ob, viewnames[i], mat);
+        add_v3_v3(stereodata.mat[2], mat[2]);
+        madd_v3_v3fl(stereodata.mat[3], mat[3], 0.5f);
+      }
+      normalize_v3(stereodata.mat[2]);
+      cross_v3_v3v3(stereodata.mat[0], stereodata.mat[1], stereodata.mat[2]);
+    }
+    else if (cam->stereo.convergence_mode == CAM_S3D_PARALLEL) {
+      /* Show plane at the given distance between the views even if it makes no sense. */
+      zero_v3(stereodata.pos);
+      for (int i = 0; i < 2; i++) {
+        float mat[4][4];
+        BKE_camera_multiview_model_matrix_scaled(&scene->r, ob, viewnames[i], mat);
+        madd_v3_v3fl(stereodata.pos, mat[3], 0.5f);
+      }
+    }
+    else if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) {
+      /* Nothing to do. Everything is already setup. */
+    }
+    stereodata.volume_sta = -cam->stereo.convergence_distance;
+    stereodata.volume_end = -cam->stereo.convergence_distance;
+    /* Encode eye + intensity and alpha (see shader) */
+    copy_v2_fl2(stereodata.color, 0.1f, 1.0f);
+    DRW_buffer_add_entry_struct(cb->camera_volume_frame, &stereodata);
+
+    if (v3d->stereo3d_convergence_alpha > 0.0f) {
+      /* Encode eye + intensity and alpha (see shader) */
+      copy_v2_fl2(stereodata.color, 0.0f, v3d->stereo3d_convergence_alpha);
+      DRW_buffer_add_entry_struct(cb->camera_volume, &stereodata);
+    }
+  }
+}
+
+static void DRW_shgroup_camera(OVERLAY_ExtraCallBuffers *cb, Object *ob, ViewLayer *view_layer)
+{
+  OVERLAY_CameraInstanceData instdata;
+
+  const DRWContextState *draw_ctx = DRW_context_state_get();
+  View3D *v3d = draw_ctx->v3d;
+  Scene *scene = draw_ctx->scene;
+  RegionView3D *rv3d = draw_ctx->rv3d;
+
+  Camera *cam = ob->data;
+  Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
+  const bool is_select = DRW_state_is_select();
+  const bool is_active = (ob == camera_object);
+  const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB));
+
+  const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
+  const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D);
+  const bool is_stereo3d_display_extra = is_active && is_multiview && (!look_through) &&
+                                         ((v3d->stereo3d_flag) != 0);
+  const bool is_selection_camera_stereo = is_select && look_thr

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list