diff options
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; } |