Blender V4.3
COM_ConvertDepthToRadiusOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_base.hh"
6
7#include "DNA_camera_types.h"
8#include "DNA_node_types.h"
9#include "DNA_object_types.h"
10#include "DNA_scene_types.h"
11
12#include "BKE_camera.h"
13
15
16namespace blender::compositor {
17
25
27{
28 depth_input_operation_ = this->get_input_socket_reader(0);
29 image_input_operation_ = this->get_input_socket_reader(1);
30
31 f_stop = get_f_stop();
32 focal_length = get_focal_length();
33 max_radius = data_->maxblur;
34 pixels_per_meter = compute_pixels_per_meter();
35 distance_to_image_of_focus = compute_distance_to_image_of_focus();
36
37 NodeBlurData blur_data;
38 blur_data.sizex = compute_maximum_defocus_radius();
39 blur_data.sizey = blur_data.sizex;
40 blur_data.relative = false;
41 blur_data.filtertype = R_FILTER_GAUSS;
42
43 blur_x_operation_->set_data(&blur_data);
44 blur_x_operation_->set_size(1.0f);
45 blur_y_operation_->set_data(&blur_data);
46 blur_y_operation_->set_size(1.0f);
47}
48
49/* Given a depth texture, compute the radius of the circle of confusion in pixels based on equation
50 * (8) of the paper:
51 *
52 * Potmesil, Michael, and Indranil Chakravarty. "A lens and aperture camera model for synthetic
53 * image generation." ACM SIGGRAPH Computer Graphics 15.3 (1981): 297-305. */
55 const rcti &area,
57{
58 for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
59 const float depth = *it.in(0);
60
61 /* Compute `Vu` in equation (7). */
62 const float distance_to_image_of_object = (focal_length * depth) / (depth - focal_length);
63
64 /* Compute C in equation (8). Notice that the last multiplier was included in the absolute
65 * since it is negative when the object distance is less than the focal length, as noted in
66 * equation (7). */
67 float diameter = abs((distance_to_image_of_object - distance_to_image_of_focus) *
68 (focal_length / (f_stop * distance_to_image_of_object)));
69
70 /* The diameter is in meters, so multiply by the pixels per meter. */
71 float radius = (diameter / 2.0f) * pixels_per_meter;
72
73 *it.out = math::min(max_radius, radius);
74 }
75}
76
77/* Computes the maximum possible defocus radius in pixels. */
78float ConvertDepthToRadiusOperation::compute_maximum_defocus_radius() const
79{
80 const float maximum_diameter = compute_maximum_diameter_of_circle_of_confusion();
81 const float pixels_per_meter = compute_pixels_per_meter();
82 const float radius = (maximum_diameter / 2.0f) * pixels_per_meter;
83 return math::min(radius, data_->maxblur);
84}
85
86/* Computes the diameter of the circle of confusion at infinity. This computes the limit in
87 * figure (5) of the paper:
88 *
89 * Potmesil, Michael, and Indranil Chakravarty. "A lens and aperture camera model for synthetic
90 * image generation." ACM SIGGRAPH Computer Graphics 15.3 (1981): 297-305.
91 *
92 * Notice that the diameter is asymmetric around the focus point, and we are computing the
93 * limiting diameter at infinity, while another limiting diameter exist at zero distance from the
94 * lens. This is a limitation of the implementation, as it assumes far defocusing only. */
95float ConvertDepthToRadiusOperation::compute_maximum_diameter_of_circle_of_confusion() const
96{
97 const float f_stop = get_f_stop();
98 const float focal_length = get_focal_length();
99 const float distance_to_image_of_focus = compute_distance_to_image_of_focus();
100 return math::abs((distance_to_image_of_focus / (f_stop * focal_length)) -
101 (focal_length / f_stop));
102}
103
104/* Computes the distance in meters to the image of the focus point across a lens of the specified
105 * focal length. This computes `Vp` in equation (7) of the paper:
106 *
107 * Potmesil, Michael, and Indranil Chakravarty. "A lens and aperture camera model for synthetic
108 * image generation." ACM SIGGRAPH Computer Graphics 15.3 (1981): 297-305. */
109float ConvertDepthToRadiusOperation::compute_distance_to_image_of_focus() const
110{
111 const float focal_length = get_focal_length();
112 const float focus_distance = compute_focus_distance();
113 return (focal_length * focus_distance) / (focus_distance - focal_length);
114}
115
116/* Returns the focal length in meters. Fallback to 50 mm in case of an invalid camera. Ensure a
117 * minimum of 1e-6. */
118float ConvertDepthToRadiusOperation::get_focal_length() const
119{
120 const Camera *camera = get_camera();
121 return camera ? math::max(1e-6f, camera->lens / 1000.0f) : 50.0f / 1000.0f;
122}
123
124/* Computes the distance to the point that is completely in focus. Default to 10 meters for null
125 * camera. */
126float ConvertDepthToRadiusOperation::compute_focus_distance() const
127{
128 const Object *camera_object = get_camera_object();
129 if (!camera_object) {
130 return 10.0f;
131 }
132 return BKE_camera_object_dof_distance(camera_object);
133}
134
135/* Computes the number of pixels per meter of the sensor size. This is essentially the resolution
136 * over the sensor size, using the sensor fit axis. Fallback to DEFAULT_SENSOR_WIDTH in case of
137 * an invalid camera. Note that the stored sensor size is in millimeter, so convert to meters. */
138float ConvertDepthToRadiusOperation::compute_pixels_per_meter() const
139{
140 const int2 size = int2(image_input_operation_->get_width(),
141 image_input_operation_->get_height());
142 const Camera *camera = get_camera();
143 const float default_value = size.x / (DEFAULT_SENSOR_WIDTH / 1000.0f);
144 if (!camera) {
145 return default_value;
146 }
147
148 switch (camera->sensor_fit) {
150 return size.x / (camera->sensor_x / 1000.0f);
152 return size.y / (camera->sensor_y / 1000.0f);
154 return size.x > size.y ? size.x / (camera->sensor_x / 1000.0f) :
155 size.y / (camera->sensor_y / 1000.0f);
156 }
157 default:
158 break;
159 }
160
161 return default_value;
162}
163
164/* Returns the f-stop number. Fallback to 1e-3 for zero f-stop. */
165float ConvertDepthToRadiusOperation::get_f_stop() const
166{
167 return math::max(1e-3f, data_->fstop);
168}
169
170const Camera *ConvertDepthToRadiusOperation::get_camera() const
171{
172 const Object *camera_object = get_camera_object();
173 if (!camera_object || camera_object->type != OB_CAMERA) {
174 return nullptr;
175 }
176
177 return reinterpret_cast<Camera *>(camera_object->data);
178}
179
180const Object *ConvertDepthToRadiusOperation::get_camera_object() const
181{
182 return scene_->camera;
183}
184
185} // namespace blender::compositor
Camera data-block and utility functions.
float BKE_camera_object_dof_distance(const struct Object *ob)
@ CAMERA_SENSOR_FIT_HOR
@ CAMERA_SENSOR_FIT_AUTO
@ CAMERA_SENSOR_FIT_VERT
struct Camera Camera
#define DEFAULT_SENSOR_WIDTH
Object is a sort of wrapper for general info.
@ OB_CAMERA
struct Object Object
@ R_FILTER_GAUSS
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define output
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
a MemoryBuffer contains access to the data
void add_output_socket(DataType datatype)
SocketReader * get_input_socket_reader(unsigned int index)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
T min(const T &a, const T &b)
T max(const T &a, const T &b)
T abs(const T &a)
VecBase< int32_t, 2 > int2
static blender::bke::bNodeSocketTemplate inputs[]
ccl_device_inline int abs(int x)
Definition util/math.h:120