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:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-02-03 23:16:28 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-02-03 23:17:59 +0300
commit1dddcfbaff14ff2871918b044714c87c7024e589 (patch)
treeb33ad2b5571738e0ad50346acc60cffd0b07e21c /source/blender
parentc69458985cdb0cc1b388b81f61e5091c73461003 (diff)
Compositor: Implement sampled motion blur for plane track deform node
Quite striaghtforward change, and in theory we can even try supporting motion blur for the corner pin node (which is tricky because coordinates actually coming from sockets, but with some black magic should be doable).
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenloader/intern/versioning_270.c17
-rw-r--r--source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp8
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp152
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h39
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cpp50
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.h2
-rw-r--r--source/blender/editors/space_node/drawnode.c7
-rw-r--r--source/blender/makesdna/DNA_node_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c15
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c3
11 files changed, 230 insertions, 79 deletions
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index a6320ed597b..096fc315f39 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -542,4 +542,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
part->child_flag |= PART_CHILD_USE_ROUGH_CURVE;
}
}
+
+ if (!DNA_struct_elem_find(fd->filesdna, "NodePlaneTrackDeformData", "char", "flag")) {
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_COMPOSIT) {
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (ELEM(node->type, CMP_NODE_PLANETRACKDEFORM)) {
+ NodePlaneTrackDeformData *data = node->storage;
+ data->flag = 0;
+ data->motion_blur_samples = 16;
+ data->motion_blur_shutter = 0.5f;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END
+ }
}
diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
index 9b69bc5a46e..379b9f193e8 100644
--- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
+++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
@@ -54,6 +54,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C
warp_image_operation->setTrackingObject(data->tracking_object);
warp_image_operation->setPlaneTrackName(data->plane_track_name);
warp_image_operation->setFramenumber(frame_number);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ warp_image_operation->setMotionBlurSamples(data->motion_blur_samples);
+ warp_image_operation->setMotionBlurShutter(data->motion_blur_shutter);
+ }
converter.addOperation(warp_image_operation);
converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0));
@@ -64,6 +68,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C
plane_mask_operation->setTrackingObject(data->tracking_object);
plane_mask_operation->setPlaneTrackName(data->plane_track_name);
plane_mask_operation->setFramenumber(frame_number);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ plane_mask_operation->setMotionBlurSamples(data->motion_blur_samples);
+ plane_mask_operation->setMotionBlurShutter(data->motion_blur_shutter);
+ }
converter.addOperation(plane_mask_operation);
converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket());
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
index fe272000b6e..fb8730c9fa0 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
@@ -135,7 +135,7 @@ void *PlaneCornerPinMaskOperation::initializeTileData(rcti *rect)
getInputSocketReader(3) };
float corners[4][2];
readCornersFromSockets(rect, readers, corners);
- calculateCorners(corners, true);
+ calculateCorners(corners, true, 0);
m_corners_ready = true;
}
@@ -194,8 +194,7 @@ void *PlaneCornerPinWarpImageOperation::initializeTileData(rcti *rect)
getInputSocketReader(4) };
float corners[4][2];
readCornersFromSockets(rect, readers, corners);
- calculateCorners(corners, true);
- calculatePerspectiveMatrix();
+ calculateCorners(corners, true, 0);
m_corners_ready = true;
}
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
index c507b4cfa98..e3095f74b99 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
@@ -56,36 +56,38 @@ PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() :
this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
this->addOutputSocket(COM_DT_COLOR);
this->m_pixelReader = NULL;
+ this->m_motion_blur_samples = 1;
+ this->m_motion_blur_shutter = 0.5f;
this->setComplex(true);
}
-void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], bool normalized)
+void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ const int width = this->m_pixelReader->getWidth();
+ const int height = this->m_pixelReader->getHeight();
+ float frame_corners[4][2] = {{0.0f, 0.0f},
+ {(float) width, 0.0f},
+ {(float) width, (float) height},
+ {0.0f, (float) height}};
+ MotionSample *sample_data = &this->m_samples[sample];
if (normalized) {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
}
}
else {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0];
- this->m_frameSpaceCorners[i][1] = corners[i][1];
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
}
}
-}
-
-void PlaneDistortWarpImageOperation::calculatePerspectiveMatrix()
-{
- const int width = this->m_pixelReader->getWidth();
- const int height = this->m_pixelReader->getHeight();
- float frame_corners[4][2] = {{0.0f, 0.0f},
- {(float) width, 0.0f},
- {(float) width, (float) height},
- {0.0f, (float) height}};
- BKE_tracking_homography_between_two_quads(this->m_frameSpaceCorners,
+ BKE_tracking_homography_between_two_quads(sample_data->frameSpaceCorners,
frame_corners,
- this->m_perspectiveMatrix);
+ sample_data->perspectiveMatrix);
}
void PlaneDistortWarpImageOperation::initExecution()
@@ -100,35 +102,47 @@ void PlaneDistortWarpImageOperation::deinitExecution()
void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float xy[2] = {x, y};
float uv[2];
float deriv[2][2];
-
- pixelTransform(xy, uv, deriv);
-
- m_pixelReader->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR);
-}
-
-void PlaneDistortWarpImageOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2])
-{
- warpCoord(xy[0], xy[1], m_perspectiveMatrix, r_uv, r_deriv);
+ if (this->m_motion_blur_samples == 1) {
+ warpCoord(x, y, this->m_samples[0].perspectiveMatrix, uv, deriv);
+ m_pixelReader->readFiltered(output,
+ uv[0], uv[1],
+ deriv[0], deriv[1],
+ COM_PS_BILINEAR);
+ }
+ else {
+ zero_v4(output);
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ float color[4];
+ warpCoord(x, y, this->m_samples[sample].perspectiveMatrix, uv, deriv);
+ m_pixelReader->readFiltered(color,
+ uv[0], uv[1],
+ deriv[0], deriv[1],
+ COM_PS_BILINEAR);
+ add_v4_v4(output, color);
+ }
+ mul_v4_fl(output, 1.0f / (float)this->m_motion_blur_samples);
+ }
}
bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- float UVs[4][2];
- float deriv[2][2];
-
- /* TODO(sergey): figure out proper way to do this. */
- warpCoord(input->xmin - 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[0], deriv);
- warpCoord(input->xmax + 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[1], deriv);
- warpCoord(input->xmax + 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[2], deriv);
- warpCoord(input->xmin - 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[3], deriv);
-
float min[2], max[2];
INIT_MINMAX2(min, max);
- for (int i = 0; i < 4; i++) {
- minmax_v2v2_v2(min, max, UVs[i]);
+
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ float UVs[4][2];
+ float deriv[2][2];
+ MotionSample *sample_data = &this->m_samples[sample];
+ /* TODO(sergey): figure out proper way to do this. */
+ warpCoord(input->xmin - 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[0], deriv);
+ warpCoord(input->xmax + 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[1], deriv);
+ warpCoord(input->xmax + 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[2], deriv);
+ warpCoord(input->xmin - 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[3], deriv);
+ for (int i = 0; i < 4; i++) {
+ minmax_v2v2_v2(min, max, UVs[i]);
+ }
}
rcti newInput;
@@ -151,20 +165,26 @@ PlaneDistortMaskOperation::PlaneDistortMaskOperation() :
/* Currently hardcoded to 8 samples. */
m_osa = 8;
+ this->m_motion_blur_samples = 1;
+ this->m_motion_blur_shutter = 0.5f;
}
-void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2], bool normalized)
+void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ MotionSample *sample_data = &this->m_samples[sample];
if (normalized) {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
}
}
else {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0];
- this->m_frameSpaceCorners[i][1] = corners[i][1];
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
}
}
}
@@ -177,18 +197,44 @@ void PlaneDistortMaskOperation::initExecution()
void PlaneDistortMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float point[2];
-
int inside_counter = 0;
- for (int sample = 0; sample < this->m_osa; sample++) {
- point[0] = x + this->m_jitter[sample][0];
- point[1] = y + this->m_jitter[sample][1];
-
- if (isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[1], this->m_frameSpaceCorners[2]) ||
- isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[2], this->m_frameSpaceCorners[3]))
+ if (this->m_motion_blur_samples == 1) {
+ MotionSample *sample_data = &this->m_samples[0];
+ for (int sample = 0; sample < this->m_osa; sample++) {
+ point[0] = x + this->m_jitter[sample][0];
+ point[1] = y + this->m_jitter[sample][1];
+ if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[1],
+ sample_data->frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[2],
+ sample_data->frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
+ output[0] = (float)inside_counter / this->m_osa;
+ }
+ else {
+ for (int motion_sample = 0;
+ motion_sample < this->m_motion_blur_samples;
+ ++motion_sample)
{
- inside_counter++;
+ MotionSample *sample_data = &this->m_samples[motion_sample];
+ for (int osa_sample = 0; osa_sample < this->m_osa; ++osa_sample) {
+ point[0] = x + this->m_jitter[osa_sample][0];
+ point[1] = y + this->m_jitter[osa_sample][1];
+ if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[1],
+ sample_data->frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[2],
+ sample_data->frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
}
+ output[0] = (float)inside_counter / (this->m_osa * this->m_motion_blur_samples);
}
-
- output[0] = (float) inside_counter / this->m_osa;
}
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
index ee2874c6b46..6ceb476f5f9 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
@@ -33,43 +33,68 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
+#define PLANE_DISTORT_MAX_SAMPLES 64
class PlaneDistortWarpImageOperation : public NodeOperation {
protected:
+ struct MotionSample {
+ float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ float perspectiveMatrix[3][3];
+ };
SocketReader *m_pixelReader;
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
- float m_perspectiveMatrix[3][3];
+ MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
+ int m_motion_blur_samples;
+ float m_motion_blur_shutter;
public:
PlaneDistortWarpImageOperation();
- void calculateCorners(const float corners[4][2], bool normalized);
- void calculatePerspectiveMatrix();
+ void calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample);
void initExecution();
void deinitExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
- void pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ void setMotionBlurSamples(int samples) {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter) { this->m_motion_blur_shutter = shutter; }
};
class PlaneDistortMaskOperation : public NodeOperation {
protected:
+ struct MotionSample {
+ float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ };
int m_osa;
+ MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
float m_jitter[32][2];
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ int m_motion_blur_samples;
+ float m_motion_blur_shutter;
public:
PlaneDistortMaskOperation();
- void calculateCorners(const float corners[4][2], bool normalized);
+ void calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample);
void initExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+
+ void setMotionBlurSamples(int samples) {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter) { this->m_motion_blur_shutter = shutter; }
};
#endif
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
index fec39cbfde0..f6152981ee7 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
@@ -46,7 +46,7 @@ PlaneTrackCommon::PlaneTrackCommon()
this->m_planeTrackName[0] = '\0';
}
-void PlaneTrackCommon::readCornersFromTrack(float corners[4][2])
+void PlaneTrackCommon::readCornersFromTrack(float corners[4][2], float frame)
{
MovieTracking *tracking;
MovieTrackingObject *object;
@@ -64,13 +64,13 @@ void PlaneTrackCommon::readCornersFromTrack(float corners[4][2])
if (plane_track) {
MovieTrackingPlaneMarker *plane_marker;
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);
-
+ float clip_framenr =
+ BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip,
+ frame);
plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
- copy_v2_v2(corners[0], plane_marker->corners[0]);
- copy_v2_v2(corners[1], plane_marker->corners[1]);
- copy_v2_v2(corners[2], plane_marker->corners[2]);
- copy_v2_v2(corners[3], plane_marker->corners[3]);
+ BKE_tracking_plane_marker_get_subframe_corners(plane_track,
+ clip_framenr,
+ corners);
}
}
}
@@ -98,10 +98,21 @@ void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned
void PlaneTrackMaskOperation::initExecution()
{
PlaneDistortMaskOperation::initExecution();
-
float corners[4][2];
- readCornersFromTrack(corners);
- calculateCorners(corners, true);
+ if (this->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
+ const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ readCornersFromTrack(corners, frame_iter);
+ calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
}
/* ******** PlaneTrackWarpImageOperation ******** */
@@ -109,9 +120,20 @@ void PlaneTrackMaskOperation::initExecution()
void PlaneTrackWarpImageOperation::initExecution()
{
PlaneDistortWarpImageOperation::initExecution();
-
+ /* TODO(sergey): De-duplicate with mask operation. */
float corners[4][2];
- readCornersFromTrack(corners);
- calculateCorners(corners, true);
- calculatePerspectiveMatrix();
+ if (this->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
+ const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ readCornersFromTrack(corners, frame_iter);
+ calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
index 3c5dd783542..b355c64a1ca 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
@@ -43,7 +43,7 @@ protected:
/* note: this class is not an operation itself (to prevent virtual inheritance issues)
* implementation classes must make wrappers to use these methods, see below.
*/
- void readCornersFromTrack(float corners[4][2]);
+ void readCornersFromTrack(float corners[4][2], float frame);
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
public:
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 394d148de54..c986a249663 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -2314,6 +2314,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
+ NodePlaneTrackDeformData *data = node->storage;
uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
@@ -2342,6 +2343,12 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
uiItemR(layout, ptr, "plane_track_name", 0, "", ICON_ANIM_DATA);
}
}
+
+ uiItemR(layout, ptr, "use_motion_blur", 0, NULL, ICON_NONE);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ uiItemR(layout, ptr, "motion_blur_samples", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_shutter", 0, NULL, ICON_NONE);
+ }
}
static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout), bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 5d1793e479a..f08b3ea9590 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -825,6 +825,10 @@ typedef struct NodeTranslateData {
typedef struct NodePlaneTrackDeformData {
char tracking_object[64];
char plane_track_name[64];
+ char flag;
+ char motion_blur_samples;
+ char pad[2];
+ float motion_blur_shutter;
} NodePlaneTrackDeformData;
typedef struct NodeShaderScript {
@@ -1080,4 +1084,11 @@ enum {
/* viewer and cmposite output */
#define CMP_NODE_OUTPUT_IGNORE_ALPHA 1
+/* Plane track deform node */
+enum {
+ CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR = 1,
+};
+
+#define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64
+
#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 7f574c41b1f..8d2a44136e8 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -6231,6 +6231,21 @@ static void def_cmp_planetrackdeform(StructRNA *srna)
RNA_def_property_string_sdna(prop, NULL, "plane_track_name");
RNA_def_property_ui_text(prop, "Plane Track", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR);
+ RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled motion blur of the mask");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX);
+ RNA_def_property_ui_text(prop, "Samples", "Number of motion blur samples");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 1.0f);
+ RNA_def_property_ui_text(prop, "Shutter", "Exposure for motion blur as a factor of FPS");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_sunbeams(StructRNA *srna)
diff --git a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
index 7a15d6364dc..415427c360f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
+++ b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
@@ -47,7 +47,8 @@ static bNodeSocketTemplate cmp_node_planetrackdeform_out[] = {
static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodePlaneTrackDeformData *data = MEM_callocN(sizeof(NodePlaneTrackDeformData), "node plane track deform data");
-
+ data->motion_blur_samples = 16;
+ data->motion_blur_shutter = 0.5f;
node->storage = data;
}