diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-02-03 23:16:28 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-02-03 23:17:59 +0300 |
commit | 1dddcfbaff14ff2871918b044714c87c7024e589 (patch) | |
tree | b33ad2b5571738e0ad50346acc60cffd0b07e21c /source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp | |
parent | c69458985cdb0cc1b388b81f61e5091c73461003 (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/compositor/operations/COM_PlaneDistortCommonOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp | 152 |
1 files changed, 99 insertions, 53 deletions
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; } |