Geometry Nodes: new Camera Info Node
This adds a new Camera Info node to Geometry Nodes. It provides information about the passed in camera like its projection matrix and focus distance. This can be used for camera culling which was must more complex before. It also allows building other view-dependent effects. Pull Request: https://projects.blender.org/blender/blender/pulls/135311
This commit is contained in:
committed by
Jacques Lucke
parent
98c4d107ea
commit
ade8576bf7
@@ -328,6 +328,7 @@ class NODE_MT_geometry_node_GEO_INPUT_SCENE(Menu):
|
||||
if context.space_data.geometry_nodes_type == 'TOOL':
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeTool3DCursor")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeInputActiveCamera")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCameraInfo")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeImageInfo")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
|
||||
|
||||
@@ -53,3 +53,11 @@
|
||||
return a.m1 == b.m1 && a.m2 == b.m2 && a.m3 == b.m3 && a.m4 == b.m4 && a.m5 == b.m5; \
|
||||
} \
|
||||
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)
|
||||
|
||||
#define BLI_STRUCT_EQUALITY_OPERATORS_6(Type, m1, m2, m3, m4, m5, m6) \
|
||||
friend bool operator==(const Type &a, const Type &b) \
|
||||
{ \
|
||||
return a.m1 == b.m1 && a.m2 == b.m2 && a.m3 == b.m3 && a.m4 == b.m4 && a.m5 == b.m5 && \
|
||||
a.m6 == b.m6; \
|
||||
} \
|
||||
BLI_STRUCT_DERIVED_UNEQUAL_OPERATOR(Type)
|
||||
|
||||
@@ -12451,6 +12451,7 @@ static void rna_def_nodes(BlenderRNA *brna)
|
||||
define("GeometryNode", "GeometryNodeBake", rna_def_geo_bake);
|
||||
define("GeometryNode", "GeometryNodeBlurAttribute");
|
||||
define("GeometryNode", "GeometryNodeBoundBox");
|
||||
define("GeometryNode", "GeometryNodeCameraInfo");
|
||||
define("GeometryNode", "GeometryNodeCaptureAttribute", rna_def_geo_capture_attribute);
|
||||
define("GeometryNode", "GeometryNodeCollectionInfo");
|
||||
define("GeometryNode", "GeometryNodeConvexHull");
|
||||
|
||||
@@ -152,6 +152,11 @@ static void add_object_relation(
|
||||
DEG_add_customdata_mask(ctx->node, &object, &dependency_data_mask);
|
||||
}
|
||||
}
|
||||
if (object.type == OB_CAMERA) {
|
||||
if (info.camera_parameters) {
|
||||
DEG_add_object_relation(ctx->node, &object, DEG_OB_COMP_PARAMETERS, "Nodes Modifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
@@ -218,7 +223,9 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont
|
||||
}
|
||||
if (eval_deps.needs_active_camera) {
|
||||
DEG_add_scene_camera_relation(ctx->node, ctx->scene, DEG_OB_COMP_TRANSFORM, "Nodes Modifier");
|
||||
/* Active camera is a scene parameter that can change, so we need a relation for that, too. */
|
||||
}
|
||||
/* Active camera is a scene parameter that can change, so we need a relation for that, too. */
|
||||
if (eval_deps.needs_active_camera || eval_deps.needs_scene_render_params) {
|
||||
DEG_add_scene_relation(ctx->node, ctx->scene, DEG_SCENE_COMP_PARAMETERS, "Nodes Modifier");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,11 @@ struct GeometryNodesEvalDependencies {
|
||||
struct ObjectDependencyInfo {
|
||||
bool transform = false;
|
||||
bool geometry = false;
|
||||
bool camera_parameters = false;
|
||||
|
||||
BLI_STRUCT_EQUALITY_OPERATORS_2(ObjectDependencyInfo, transform, geometry);
|
||||
BLI_STRUCT_EQUALITY_OPERATORS_3(ObjectDependencyInfo, transform, geometry, camera_parameters);
|
||||
};
|
||||
static constexpr ObjectDependencyInfo all_object_deps{true, true};
|
||||
static constexpr ObjectDependencyInfo all_object_deps{true, true, true};
|
||||
|
||||
/**
|
||||
* Maps `session_uid` to the corresponding data-block.
|
||||
@@ -41,6 +42,7 @@ struct GeometryNodesEvalDependencies {
|
||||
|
||||
bool needs_own_transform = false;
|
||||
bool needs_active_camera = false;
|
||||
bool needs_scene_render_params = false;
|
||||
bool time_dependent = false;
|
||||
|
||||
/**
|
||||
@@ -67,11 +69,12 @@ struct GeometryNodesEvalDependencies {
|
||||
*/
|
||||
void merge(const GeometryNodesEvalDependencies &other);
|
||||
|
||||
BLI_STRUCT_EQUALITY_OPERATORS_5(GeometryNodesEvalDependencies,
|
||||
BLI_STRUCT_EQUALITY_OPERATORS_6(GeometryNodesEvalDependencies,
|
||||
ids,
|
||||
objects_info,
|
||||
needs_own_transform,
|
||||
needs_active_camera,
|
||||
needs_scene_render_params,
|
||||
time_dependent);
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ set(SRC
|
||||
nodes/node_geo_blur_attribute.cc
|
||||
nodes/node_geo_boolean.cc
|
||||
nodes/node_geo_bounding_box.cc
|
||||
nodes/node_geo_camera_info.cc
|
||||
nodes/node_geo_collection_info.cc
|
||||
nodes/node_geo_common.cc
|
||||
nodes/node_geo_convex_hull.cc
|
||||
|
||||
85
source/blender/nodes/geometry/nodes/node_geo_camera_info.cc
Normal file
85
source/blender/nodes/geometry/nodes/node_geo_camera_info.cc
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "BKE_camera.h"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_camera_info_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.use_custom_socket_order();
|
||||
|
||||
b.add_output<decl::Matrix>("Projection Matrix").description("Camera projection matrix");
|
||||
b.add_output<decl::Float>("Focal Length").description("Perspective camera focal length");
|
||||
b.add_output<decl::Vector>("Sensor").description("Size of the camera sensor");
|
||||
b.add_output<decl::Vector>("Shift").description("Camera shift");
|
||||
b.add_output<decl::Float>("Clip Start").description("Camera near clipping distance");
|
||||
b.add_output<decl::Float>("Clip End").description("Camera far clipping distance");
|
||||
b.add_output<decl::Float>("Focus Distance")
|
||||
.description("Distance to the focus point for depth of field");
|
||||
b.add_output<decl::Bool>("Is Orthographic")
|
||||
.description("Whether the camera is using orthographic projection");
|
||||
b.add_output<decl::Float>("Orthographic Scale")
|
||||
.description("Orthographic camera scale (similar to zoom)");
|
||||
|
||||
b.add_input<decl::Object>("Camera").hide_label();
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
const Scene *scene = DEG_get_evaluated_scene(params.depsgraph());
|
||||
if (!scene) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
const Object *camera_obj = params.get_input<Object *>("Camera");
|
||||
|
||||
if (!camera_obj || camera_obj->type != OB_CAMERA) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
Camera *camera = static_cast<Camera *>(camera_obj->data);
|
||||
if (!camera) {
|
||||
params.set_default_remaining_outputs();
|
||||
return;
|
||||
}
|
||||
|
||||
CameraParams camera_params;
|
||||
BKE_camera_params_init(&camera_params);
|
||||
BKE_camera_params_from_object(&camera_params, camera_obj);
|
||||
BKE_camera_params_compute_viewplane(
|
||||
&camera_params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
|
||||
BKE_camera_params_compute_matrix(&camera_params);
|
||||
|
||||
const float4x4 projection_matrix(camera_params.winmat);
|
||||
float focus_distance = BKE_camera_object_dof_distance(camera_obj);
|
||||
|
||||
params.set_output("Projection Matrix", projection_matrix);
|
||||
params.set_output("Focal Length", camera_params.lens);
|
||||
params.set_output("Sensor", float3{camera_params.sensor_x, camera_params.sensor_y, 0.0f});
|
||||
params.set_output("Shift", float3{camera_params.shiftx, camera_params.shifty, 0.0f});
|
||||
params.set_output("Clip Start", camera_params.clip_start);
|
||||
params.set_output("Clip End", camera_params.clip_end);
|
||||
params.set_output("Focus Distance", focus_distance);
|
||||
params.set_output("Is Orthographic", camera_params.is_ortho);
|
||||
params.set_output("Orthographic Scale", camera_params.ortho_scale);
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static blender::bke::bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, "GeometryNodeCameraInfo");
|
||||
ntype.ui_name = "Camera Info";
|
||||
ntype.ui_description = "Retrieve information from a camera object";
|
||||
ntype.nclass = NODE_CLASS_INPUT;
|
||||
ntype.geometry_node_execute = node_geo_exec;
|
||||
ntype.declare = node_declare;
|
||||
blender::bke::node_register_type(ntype);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
} // namespace blender::nodes::node_geo_camera_info_cc
|
||||
@@ -44,6 +44,7 @@ void GeometryNodesEvalDependencies::add_object(Object *object,
|
||||
object_deps);
|
||||
deps.geometry |= object_deps.geometry;
|
||||
deps.transform |= object_deps.transform;
|
||||
deps.camera_parameters |= object_deps.camera_parameters;
|
||||
}
|
||||
|
||||
void GeometryNodesEvalDependencies::merge(const GeometryNodesEvalDependencies &other)
|
||||
@@ -58,6 +59,7 @@ void GeometryNodesEvalDependencies::merge(const GeometryNodesEvalDependencies &o
|
||||
}
|
||||
this->needs_own_transform |= other.needs_own_transform;
|
||||
this->needs_active_camera |= other.needs_active_camera;
|
||||
this->needs_scene_render_params |= other.needs_scene_render_params;
|
||||
this->time_dependent |= other.time_dependent;
|
||||
}
|
||||
|
||||
@@ -165,6 +167,20 @@ static void add_own_transform_dependencies(const bNodeTree &tree,
|
||||
deps.needs_own_transform |= needs_own_transform;
|
||||
}
|
||||
|
||||
static bool needs_scene_render_params(const bNodeTree &ntree)
|
||||
{
|
||||
for (const bNode *node : ntree.nodes_by_type("GeometryNodeCameraInfo")) {
|
||||
if (node->is_muted()) {
|
||||
continue;
|
||||
}
|
||||
const bNodeSocket &projection_matrix_socket = node->output_by_identifier("Projection Matrix");
|
||||
if (projection_matrix_socket.is_logically_linked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gather_geometry_nodes_eval_dependencies(
|
||||
const bNodeTree &ntree,
|
||||
GeometryNodesEvalDependencies &deps,
|
||||
@@ -175,6 +191,7 @@ static void gather_geometry_nodes_eval_dependencies(
|
||||
add_eval_dependencies_from_socket(*socket, deps);
|
||||
}
|
||||
deps.needs_active_camera |= has_enabled_nodes_of_type(ntree, "GeometryNodeInputActiveCamera");
|
||||
deps.needs_scene_render_params |= needs_scene_render_params(ntree);
|
||||
deps.time_dependent |= has_enabled_nodes_of_type(ntree, "GeometryNodeSimulationInput") ||
|
||||
has_enabled_nodes_of_type(ntree, "GeometryNodeInputSceneTime");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user