[Bf-blender-cvs] [935cabdb6af] temp-xr-virtual-camera-experiment: Initial implementation of 2 stage drawing.

Jeroen Bakker noreply at git.blender.org
Wed Nov 2 16:06:05 CET 2022


Commit: 935cabdb6af74a0d31799d4b1f8111a17bcc2772
Author: Jeroen Bakker
Date:   Wed Nov 2 15:47:53 2022 +0100
Branches: temp-xr-virtual-camera-experiment
https://developer.blender.org/rB935cabdb6af74a0d31799d4b1f8111a17bcc2772

Initial implementation of 2 stage drawing.

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

M	source/blender/editors/space_view3d/view3d_draw.cc
M	source/blender/gpu/intern/gpu_node_graph.c
M	source/blender/gpu/intern/gpu_node_graph.h
M	source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl
M	source/blender/makesdna/DNA_camera_types.h
M	source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc

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

diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc
index 31b26ba4cda..15356adab58 100644
--- a/source/blender/editors/space_view3d/view3d_draw.cc
+++ b/source/blender/editors/space_view3d/view3d_draw.cc
@@ -7,6 +7,7 @@
 
 #include <cmath>
 
+#include "BLI_float4x4.hh"
 #include "BLI_jitter_2d.h"
 #include "BLI_listbase.h"
 #include "BLI_math.h"
@@ -15,6 +16,7 @@
 #include "BLI_string.h"
 #include "BLI_string_utils.h"
 #include "BLI_threads.h"
+#include "BLI_vector.hh"
 
 #include "BKE_armature.h"
 #include "BKE_camera.h"
@@ -26,6 +28,7 @@
 #include "BKE_key.h"
 #include "BKE_layer.h"
 #include "BKE_main.h"
+#include "BKE_node.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_scene.h"
@@ -40,6 +43,7 @@
 #include "DNA_brush_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_key_types.h"
+#include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 #include "DNA_view3d_types.h"
@@ -87,6 +91,9 @@
 #include "view3d_intern.h" /* own include */
 
 using blender::float4;
+using blender::float4x4;
+using blender::int2;
+using blender::Vector;
 
 #define M_GOLDEN_RATIO_CONJUGATE 0.618033988749895f
 
@@ -1535,8 +1542,78 @@ void view3d_draw_region_info(const bContext *C, ARegion *region)
 /** \name Draw Viewport Contents
  * \{ */
 
+static void view3d_virtual_camera_stage_set(Main *bmain, const bool virtual_stage)
+{
+  LISTBASE_FOREACH (Camera *, camera, &bmain->cameras) {
+    camera->runtime.virtual_camera_stage = virtual_stage;
+  }
+}
+
+static void view3d_virtual_camera_update(const bContext *C, ARegion *region, Object *object)
+{
+  BLI_assert(object->type == OB_CAMERA);
+  Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+  Scene *scene = CTX_data_scene(C);
+  View3D *v3d = CTX_wm_view3d(C);
+  int2 resolution(1920 / 2, 1080 / 2);
+  Camera *camera = static_cast<Camera *>(object->data);
+  RenderEngineType *engine_type = ED_view3d_engine_type(scene, OB_RENDER);
+
+  if (camera->runtime.virtual_display_texture == nullptr) {
+    camera->runtime.virtual_display_texture = GPU_offscreen_create(
+        UNPACK2(resolution), true, GPU_RGBA16F, nullptr);
+  }
+  GPUOffScreen *offscreen = camera->runtime.virtual_display_texture;
+  GPU_offscreen_bind(offscreen, true);
+  DRW_draw_render_loop_offscreen(
+      depsgraph, engine_type, region, v3d, true, false, false, offscreen, nullptr);
+  GPU_offscreen_unbind(offscreen, true);
+}
+
+static void view3d_draw_virtual_camera(const bContext *C, ARegion *region)
+{
+  Main *bmain = CTX_data_main(C);
+
+  // create a custom view3d offscreen rendering.
+  Vector<Object *> virtual_cameras;
+
+  LISTBASE_FOREACH (Material *, material, &bmain->materials) {
+    if (!material->nodetree) {
+      continue;
+    }
+
+    LISTBASE_FOREACH (bNode *, node, &material->nodetree->nodes) {
+      if (node->type != SH_NODE_VIRTUAL_CAMERA) {
+        continue;
+      }
+      Object *ob = static_cast<Object *>(static_cast<void *>(node->id));
+      if (ob == nullptr || ob->type != OB_CAMERA) {
+        continue;
+      }
+      virtual_cameras.append(ob);
+    }
+  }
+
+  if (virtual_cameras.is_empty()) {
+    /* No virtual cameras, so skip updating. */
+    return;
+  }
+
+  // go over each camera and set the flag to virtual camera.
+  view3d_virtual_camera_stage_set(bmain, true);
+
+  for (Object *object : virtual_cameras) {
+    view3d_virtual_camera_update(C, region, object);
+  }
+
+  // get reference of the gpu texture and change its ownership
+  // go over eah camera and set the flag back to main camera.
+  view3d_virtual_camera_stage_set(bmain, false);
+}
+
 static void view3d_draw_view(const bContext *C, ARegion *region)
 {
+  view3d_draw_virtual_camera(C, region);
   ED_view3d_draw_setup_view(CTX_wm_manager(C),
                             CTX_wm_window(C),
                             CTX_data_expect_evaluated_depsgraph(C),
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index 17136308cdd..553ca219617 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -20,6 +20,7 @@
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
+#include "GPU_framebuffer.h"
 #include "GPU_texture.h"
 #include "GPU_vertex_format.h"
 
@@ -115,6 +116,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType
       link->users++;
       break;
     case GPU_NODE_LINK_IMAGE:
+    case GPU_NODE_LINK_IMAGE_CAMERA:
     case GPU_NODE_LINK_IMAGE_TILED:
     case GPU_NODE_LINK_IMAGE_SKY:
     case GPU_NODE_LINK_COLORBAND:
@@ -635,15 +637,12 @@ GPUNodeLink *GPU_image_camera(GPUMaterial *mat, Camera *camera, eGPUSamplerState
 {
   GPUNodeGraph *graph = gpu_material_node_graph(mat);
   GPUNodeLink *link = gpu_node_link_create();
-  link->link_type = GPU_NODE_LINK_IMAGE;
-  link->texture = gpu_node_graph_add_texture(graph,
-                                             NULL,
-                                             NULL,
-                                             NULL,
-                                             NULL,
-                                             &camera->runtime.virtual_display_texture,
-                                             link->link_type,
-                                             sampler_state);
+  GPUTexture *texture = camera->runtime.virtual_camera_stage ?
+                            NULL :
+                            GPU_offscreen_color_texture(camera->runtime.virtual_display_texture);
+  link->link_type = GPU_NODE_LINK_IMAGE_CAMERA;
+  link->texture = gpu_node_graph_add_texture(
+      graph, NULL, NULL, NULL, NULL, &texture, link->link_type, sampler_state);
   return link;
 }
 
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index de0a0687b13..6417f7d0a47 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -50,6 +50,7 @@ typedef enum {
   GPU_NODE_LINK_IMAGE_TILED,
   GPU_NODE_LINK_IMAGE_TILED_MAPPING,
   GPU_NODE_LINK_IMAGE_SKY,
+  GPU_NODE_LINK_IMAGE_CAMERA,
   GPU_NODE_LINK_OUTPUT,
   GPU_NODE_LINK_UNIFORM,
   GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN,
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl
index 05bc6f90686..26d15292e6a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl
@@ -4,8 +4,13 @@ void node_virtual_camera_empty(vec3 co, out vec4 color, out float alpha)
   alpha = 0.0;
 }
 
-void node_virtual_camera(vec3 co, sampler2D ima, out vec4 color, out float alpha)
+void node_virtual_camera(vec3 co, sampler2D ima, float mix, out vec4 color, out float alpha)
 {
+  if (mix == 1.0) {
+    node_virtual_camera_empty(co, color, alpha);
+    return;
+  }
+
   color = texture(ima, co.xy);
   alpha = color.a;
 }
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index b6a5b95e404..a257f3b876b 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -76,7 +76,7 @@ typedef struct Camera_Runtime {
    * when scene camera/main camera is evaluated. */
   int virtual_camera_stage;
   int _pad[1];
-  struct GPUTexture *virtual_display_texture;
+  struct GPUOffScreen *virtual_display_texture;
 } Camera_Runtime;
 
 typedef struct Camera {
diff --git a/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc b/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc
index 1e26ee2fe63..f9af9356242 100644
--- a/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc
@@ -5,6 +5,8 @@
 
 #include "DNA_camera_types.h"
 
+#include "DEG_depsgraph_query.h"
+
 namespace blender::nodes::node_shader_virtual_camera_cc {
 
 static void sh_node_virtual_camera_declare(NodeDeclarationBuilder &b)
@@ -25,21 +27,21 @@ static int node_shader_gpu_virtual_camera(GPUMaterial *mat,
     return GPU_stack_link(mat, node, "node_virtual_camera_empty", in, out);
   }
 
-  Camera *cam = static_cast<Camera *>(object->data);
+  Object *orig_object = DEG_get_original_object(object);
+
+  Camera *cam = static_cast<Camera *>(orig_object->data);
   const bool virtual_camera_stage = cam->runtime.virtual_camera_stage;
-  if (virtual_camera_stage || cam->runtime.virtual_display_texture == nullptr) {
-    return GPU_stack_link(mat, node, "node_virtual_camera_empty", in, out);
-  }
+  const float stage_mix = virtual_camera_stage ? 1.0f : 0.0f;
 
-  GPUNodeLink **texco = &in[0].link;
-  if (!*texco) {
-    *texco = GPU_attribute(mat, CD_AUTO_FROM_NAME, "");
-    node_shader_gpu_bump_tex_coord(mat, node, texco);
-  }
-  node_shader_gpu_tex_mapping(mat, node, in, out);
+  node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
 
-  return GPU_stack_link(
-      mat, node, "node_virtual_camera", in, out, GPU_image_camera(mat, cam, GPU_SAMPLER_DEFAULT));
+  return GPU_stack_link(mat,
+                        node,
+                        "node_virtual_camera",
+                        in,
+                        out,
+                        GPU_image_camera(mat, cam, GPU_SAMPLER_DEFAULT),
+                        GPU_uniform(&stage_mix));
 }
 
 }  // namespace blender::nodes::node_shader_virtual_camera_cc



More information about the Bf-blender-cvs mailing list