diff options
author | Manuel Castilla <manzanillawork@gmail.com> | 2021-08-23 16:30:18 +0300 |
---|---|---|
committer | Manuel Castilla <manzanillawork@gmail.com> | 2021-08-23 18:07:37 +0300 |
commit | 344aca3b1bf2718904455ea6cef1ffd8bedf51a6 (patch) | |
tree | e71d120e19ed64c1475250e226082c4325bfe2c1 /source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc | |
parent | 064167fce70e3d7c382c374334a1bd0b520fe9fe (diff) |
Compositor: Full frame distort nodes
Adds full frame implementation to "Displace", "Crop", "Flip",
"Plane Track Deform", "Corner Pin", "Movie Distortion",
"Lens Distortion" and "Map UV" nodes.
The other nodes in "Distort" sub-menu are implemented
separately in other commits.
No functional changes.
Part of T88150.
Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D12166
Diffstat (limited to 'source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc')
-rw-r--r-- | source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc | 115 |
1 files changed, 113 insertions, 2 deletions
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc index 4edcc206f5b..a80cbbe942a 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc @@ -85,8 +85,9 @@ void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], { PlaneDistortBaseOperation::calculateCorners(corners, normalized, sample); - const int width = this->m_pixelReader->getWidth(); - const int height = this->m_pixelReader->getHeight(); + const NodeOperation *image = get_input_operation(0); + const int width = image->getWidth(); + const int height = image->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]; @@ -127,6 +128,34 @@ void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], } } +void PlaneDistortWarpImageOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) +{ + const MemoryBuffer *input_img = inputs[0]; + float uv[2]; + float deriv[2][2]; + BuffersIterator<float> it = output->iterate_with({}, area); + if (this->m_motion_blur_samples == 1) { + for (; !it.is_end(); ++it) { + warpCoord(it.x, it.y, this->m_samples[0].perspectiveMatrix, uv, deriv); + input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], it.out); + } + } + else { + for (; !it.is_end(); ++it) { + zero_v4(it.out); + for (const int sample : IndexRange(this->m_motion_blur_samples)) { + float color[4]; + warpCoord(it.x, it.y, this->m_samples[sample].perspectiveMatrix, uv, deriv); + input_img->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], color); + add_v4_v4(it.out, color); + } + mul_v4_fl(it.out, 1.0f / (float)this->m_motion_blur_samples); + } + } +} + bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest( rcti *input, ReadBufferOperation *readOperation, rcti *output) { @@ -157,6 +186,51 @@ bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest( return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); } +void PlaneDistortWarpImageOperation::get_area_of_interest(const int input_idx, + const rcti &output_area, + rcti &r_input_area) +{ + if (input_idx != 0) { + r_input_area = output_area; + return; + } + + /* TODO: figure out the area needed for warping and EWA filtering. */ + r_input_area.xmin = 0; + r_input_area.ymin = 0; + r_input_area.xmax = get_input_operation(0)->getWidth(); + r_input_area.ymax = get_input_operation(0)->getHeight(); + +/* Old implemention but resulting coordinates are way out of input operation bounds and in some + * cases the area result may incorrectly cause cropping. */ +#if 0 + float min[2], max[2]; + INIT_MINMAX2(min, max); + 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( + output_area.xmin - 2, output_area.ymin - 2, sample_data->perspectiveMatrix, UVs[0], deriv); + warpCoord( + output_area.xmax + 2, output_area.ymin - 2, sample_data->perspectiveMatrix, UVs[1], deriv); + warpCoord( + output_area.xmax + 2, output_area.ymax + 2, sample_data->perspectiveMatrix, UVs[2], deriv); + warpCoord( + output_area.xmin - 2, output_area.ymax + 2, sample_data->perspectiveMatrix, UVs[3], deriv); + for (int i = 0; i < 4; i++) { + minmax_v2v2_v2(min, max, UVs[i]); + } + } + + r_input_area.xmin = min[0] - 1; + r_input_area.ymin = min[1] - 1; + r_input_area.xmax = max[0] + 1; + r_input_area.ymax = max[1] + 1; +#endif +} + /* ******** PlaneDistort Mask ******** */ PlaneDistortMaskOperation::PlaneDistortMaskOperation() : PlaneDistortBaseOperation() @@ -219,4 +293,41 @@ void PlaneDistortMaskOperation::executePixelSampled(float output[4], } } +void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> UNUSED(inputs)) +{ + for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { + int inside_count = 0; + for (const int motion_sample : IndexRange(this->m_motion_blur_samples)) { + MotionSample &sample = this->m_samples[motion_sample]; + inside_count += get_jitter_samples_inside_count(it.x, it.y, sample); + } + *it.out = (float)inside_count / (this->m_osa * this->m_motion_blur_samples); + } +} + +int PlaneDistortMaskOperation::get_jitter_samples_inside_count(int x, + int y, + MotionSample &sample_data) +{ + float point[2]; + int inside_count = 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_count++; + } + } + return inside_count; +} + } // namespace blender::compositor |