Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jeroen@blender.org>2022-11-02 15:17:35 +0300
committerJeroen Bakker <jeroen@blender.org>2022-11-02 15:17:35 +0300
commita083b23cebee4a35c7b658ce6f5c15bd7db9db58 (patch)
tree92deec27cd8d29c7482ae9852958b6863fff3806
parent638bf05a23e1ef7dddd3b5d42d9521d8849a4375 (diff)
First iteration of a virtual camera node.
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/node.cc2
-rw-r--r--source/blender/draw/intern/draw_manager_data.cc5
-rw-r--r--source/blender/editors/space_node/drawnode.cc17
-rw-r--r--source/blender/gpu/CMakeLists.txt1
-rw-r--r--source/blender/gpu/GPU_material.h5
-rw-r--r--source/blender/gpu/intern/gpu_codegen.cc4
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c30
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl11
-rw-r--r--source/blender/makesdna/DNA_camera_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c15
-rw-r--r--source/blender/nodes/NOD_shader.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/shader/CMakeLists.txt1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc58
16 files changed, 155 insertions, 6 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index ecf7a556459..cf78c954e44 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1222,6 +1222,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define SH_NODE_COMBINE_COLOR 711
#define SH_NODE_SEPARATE_COLOR 712
#define SH_NODE_MIX 713
+#define SH_NODE_VIRTUAL_CAMERA 714
/** \} */
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 7c1193d80ab..71ef05e9a4f 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -137,6 +137,8 @@ static void camera_blend_read_data(BlendDataReader *reader, ID *id)
bgpic->flag &= ~CAM_BGIMG_FLAG_OVERRIDE_LIBRARY_LOCAL;
}
}
+ ca->runtime.virtual_camera_stage = false;
+ ca->runtime.virtual_display_texture = NULL;
}
static void camera_blend_read_lib(BlendLibReader *reader, ID *id)
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 8f8cd02e119..d6beb423b5a 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4667,6 +4667,8 @@ static void registerShaderNodes()
register_node_type_sh_tex_pointdensity();
register_node_type_sh_tex_ies();
register_node_type_sh_tex_white_noise();
+
+ register_node_type_sh_virtual_camera();
}
static void registerTextureNodes()
diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc
index 4aa27e2288c..bae99a945d2 100644
--- a/source/blender/draw/intern/draw_manager_data.cc
+++ b/source/blender/draw/intern/draw_manager_data.cc
@@ -1835,6 +1835,11 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *mater
DRW_shgroup_uniform_texture_ex(
grp, tex->sampler_name, *tex->sky, eGPUSamplerState(tex->sampler_state));
}
+ else if (tex->camera) {
+ /* Sky */
+ DRW_shgroup_uniform_texture_ex(
+ grp, tex->sampler_name, *tex->camera, eGPUSamplerState(tex->sampler_state));
+ }
}
GPUUniformBuf *ubo = GPU_material_uniform_buffer_get(material);
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index df31a0342cb..b713b225638 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -432,6 +432,20 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr, false, true);
}
+static void node_shader_buts_virtual_camera(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ uiTemplateID(layout,
+ C,
+ ptr,
+ "camera",
+ nullptr,
+ nullptr,
+ nullptr,
+ UI_TEMPLATE_ID_FILTER_ALL,
+ false,
+ nullptr);
+}
+
static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
@@ -499,6 +513,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
ntype->draw_buttons = node_shader_buts_tex_environment;
ntype->draw_buttons_ex = node_shader_buts_tex_environment_ex;
break;
+ case SH_NODE_VIRTUAL_CAMERA:
+ ntype->draw_buttons = node_shader_buts_virtual_camera;
+ break;
case SH_NODE_DISPLACEMENT:
case SH_NODE_VECTOR_DISPLACEMENT:
ntype->draw_buttons = node_shader_buts_displacement;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index bfbbf1be225..a636fcb86f0 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -506,6 +506,7 @@ set(GLSL_SRC
shaders/material/gpu_shader_material_vector_rotate.glsl
shaders/material/gpu_shader_material_velvet.glsl
shaders/material/gpu_shader_material_vertex_color.glsl
+ shaders/material/gpu_shader_material_virtual_camera.glsl
shaders/material/gpu_shader_material_volume_absorption.glsl
shaders/material/gpu_shader_material_volume_principled.glsl
shaders/material/gpu_shader_material_volume_scatter.glsl
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 3dad2a1a19a..48eb53d662f 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -35,6 +35,7 @@ struct Material;
struct Scene;
struct bNode;
struct bNodeTree;
+struct Camera;
typedef struct GPUMaterial GPUMaterial;
typedef struct GPUNode GPUNode;
@@ -178,6 +179,9 @@ GPUNodeLink *GPU_image_sky(GPUMaterial *mat,
const float *pixels,
float *layer,
eGPUSamplerState sampler_state);
+GPUNodeLink *GPU_image_camera(GPUMaterial *mat,
+ struct Camera *camera,
+ eGPUSamplerState sampler_state);
GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row);
/**
@@ -322,6 +326,7 @@ typedef struct GPUMaterialTexture {
bool iuser_available;
struct GPUTexture **colorband;
struct GPUTexture **sky;
+ struct GPUTexture **camera;
char sampler_name[32]; /* Name of sampler in GLSL. */
char tiled_mapping_name[32]; /* Name of tile mapping sampler in GLSL. */
int users;
diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc
index 4adeac1b49a..2ce03f88693 100644
--- a/source/blender/gpu/intern/gpu_codegen.cc
+++ b/source/blender/gpu/intern/gpu_codegen.cc
@@ -392,6 +392,10 @@ void GPUCodegen::generate_resources()
const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
info.sampler(0, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
}
+ else if (tex->camera) {
+ const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
+ info.sampler(0, ImageType::FLOAT_2D, name, Frequency::PASS);
+ }
else if (tex->tiled_mapping_name[0] != '\0') {
const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
info.sampler(slot++, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index c72e7097b33..17136308cdd 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -12,6 +12,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_camera_types.h"
#include "DNA_node_types.h"
#include "BLI_ghash.h"
@@ -470,6 +471,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
ImageUser *iuser,
struct GPUTexture **colorband,
struct GPUTexture **sky,
+ struct GPUTexture **camera,
GPUNodeLinkType link_type,
eGPUSamplerState sampler_state)
{
@@ -478,7 +480,7 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
GPUMaterialTexture *tex = graph->textures.first;
for (; tex; tex = tex->next) {
if (tex->ima == ima && tex->colorband == colorband && tex->sky == sky &&
- tex->sampler_state == sampler_state) {
+ tex->camera == camera && tex->sampler_state == sampler_state) {
break;
}
num_textures++;
@@ -625,7 +627,23 @@ GPUNodeLink *GPU_image(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, NULL, link->link_type, sampler_state);
+ graph, ima, iuser, NULL, NULL, NULL, link->link_type, sampler_state);
+ return link;
+}
+
+GPUNodeLink *GPU_image_camera(GPUMaterial *mat, Camera *camera, eGPUSamplerState sampler_state)
+{
+ 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);
return link;
}
@@ -642,7 +660,7 @@ GPUNodeLink *GPU_image_sky(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_SKY;
link->texture = gpu_node_graph_add_texture(
- graph, NULL, NULL, NULL, sky, link->link_type, sampler_state);
+ graph, NULL, NULL, NULL, sky, NULL, link->link_type, sampler_state);
return link;
}
@@ -655,7 +673,7 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat,
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, NULL, link->link_type, sampler_state);
+ graph, ima, iuser, NULL, NULL, NULL, link->link_type, sampler_state);
return link;
}
@@ -665,7 +683,7 @@ GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, Image *ima, ImageUser *iu
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_IMAGE_TILED_MAPPING;
link->texture = gpu_node_graph_add_texture(
- graph, ima, iuser, NULL, NULL, link->link_type, GPU_SAMPLER_MAX);
+ graph, ima, iuser, NULL, NULL, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
@@ -678,7 +696,7 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro
GPUNodeLink *link = gpu_node_link_create();
link->link_type = GPU_NODE_LINK_COLORBAND;
link->texture = gpu_node_graph_add_texture(
- graph, NULL, NULL, colorband, NULL, link->link_type, GPU_SAMPLER_MAX);
+ graph, NULL, NULL, colorband, NULL, NULL, link->link_type, GPU_SAMPLER_MAX);
return link;
}
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
new file mode 100644
index 00000000000..05bc6f90686
--- /dev/null
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_virtual_camera.glsl
@@ -0,0 +1,11 @@
+void node_virtual_camera_empty(vec3 co, out vec4 color, out float alpha)
+{
+ color = vec4(0.0);
+ alpha = 0.0;
+}
+
+void node_virtual_camera(vec3 co, sampler2D ima, out vec4 color, out float alpha)
+{
+ 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 10a6c936be1..b6a5b95e404 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -71,6 +71,12 @@ typedef struct Camera_Runtime {
float drw_depth[2];
float drw_focusmat[4][4];
float drw_normalmat[4][4];
+
+ /* XXX(jbakker): Yuck but we are experimenting... true when virtual camera is evaluated, false
+ * when scene camera/main camera is evaluated. */
+ int virtual_camera_stage;
+ int _pad[1];
+ struct GPUTexture *virtual_display_texture;
} Camera_Runtime;
typedef struct Camera {
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 865399df9ef..1c903ce1dcd 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -5885,6 +5885,21 @@ static void def_sh_tex_coord(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_sh_virtual_camera(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Camera_object_poll");
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_ui_text(prop, "Camera", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ // TODO: add poll function show all cameras in active scene, excluding scene camera.
+}
+
static void def_sh_vect_transform(StructRNA *srna)
{
static const EnumPropertyItem prop_vect_type_items[] = {
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 8fe77bffaad..681851eab85 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -129,6 +129,8 @@ void register_node_type_sh_bump(void);
void register_node_type_sh_tex_ies(void);
void register_node_type_sh_tex_white_noise(void);
+void register_node_type_sh_virtual_camera(void);
+
void register_node_type_sh_custom_group(bNodeType *ntype);
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 9671f8148ec..1a3311c6fe6 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -123,6 +123,7 @@ DefNode(ShaderNode, SH_NODE_CURVE_FLOAT, def_float_curve, "CUR
DefNode(ShaderNode, SH_NODE_COMBINE_COLOR, def_sh_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "Create a color from individual components using multiple models")
DefNode(ShaderNode, SH_NODE_SEPARATE_COLOR, def_sh_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "Split a color into its individual components using multiple models")
DefNode(ShaderNode, SH_NODE_MIX, def_sh_mix, "MIX", Mix, "Mix", "Mix values by a factor")
+DefNode(ShaderNode, SH_NODE_VIRTUAL_CAMERA, def_sh_virtual_camera, "VIRTUAL_CAMERA", VirtualCamera, "Virtual Camera", "Virtual Camera")
DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode(CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt
index e6f90449843..9a429307542 100644
--- a/source/blender/nodes/shader/CMakeLists.txt
+++ b/source/blender/nodes/shader/CMakeLists.txt
@@ -113,6 +113,7 @@ set(SRC
nodes/node_shader_vector_rotate.cc
nodes/node_shader_vector_transform.cc
nodes/node_shader_vertex_color.cc
+ nodes/node_shader_virtual_camera.cc
nodes/node_shader_volume_absorption.cc
nodes/node_shader_volume_info.cc
nodes/node_shader_volume_principled.cc
diff --git a/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc b/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc
new file mode 100644
index 00000000000..1e26ee2fe63
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_virtual_camera.cc
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2005 Blender Foundation. All rights reserved. */
+
+#include "node_shader_util.hh"
+
+#include "DNA_camera_types.h"
+
+namespace blender::nodes::node_shader_virtual_camera_cc {
+
+static void sh_node_virtual_camera_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Vector")).implicit_field(implicit_field_inputs::position);
+ b.add_output<decl::Color>(N_("Color")).no_muted_links();
+ b.add_output<decl::Float>(N_("Alpha")).no_muted_links();
+}
+
+static int node_shader_gpu_virtual_camera(GPUMaterial *mat,
+ bNode *node,
+ bNodeExecData * /*execdata*/,
+ GPUNodeStack *in,
+ GPUNodeStack *out)
+{
+ Object *object = (Object *)node->id;
+ if (object == nullptr || object->type != OB_CAMERA) {
+ return GPU_stack_link(mat, node, "node_virtual_camera_empty", in, out);
+ }
+
+ Camera *cam = static_cast<Camera *>(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);
+ }
+
+ 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);
+
+ return GPU_stack_link(
+ mat, node, "node_virtual_camera", in, out, GPU_image_camera(mat, cam, GPU_SAMPLER_DEFAULT));
+}
+
+} // namespace blender::nodes::node_shader_virtual_camera_cc
+
+void register_node_type_sh_virtual_camera()
+{
+ namespace file_ns = blender::nodes::node_shader_virtual_camera_cc;
+
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_VIRTUAL_CAMERA, "Virtual Camera", NODE_CLASS_TEXTURE);
+ ntype.declare = file_ns::sh_node_virtual_camera_declare;
+ node_type_gpu(&ntype, file_ns::node_shader_gpu_virtual_camera);
+
+ nodeRegisterType(&ntype);
+}