The old implementation was a simple rounding operation and was not implemented for full-frame compositor. The issue with the old implementation is that it will not give satisfactory results for images with high frequency details, including cases when is used for a preview on Cycles render with low number of samples. Additionally, when applied on animated footage it produces very noisy result. The new algorithm uses an explicit pixel size setting, which allows the node to be used on its own, without need to have scale-down and scale-up nodes. It also uses neighbour averaging, which produces better looking result during animation and noisy input images. The old tiled compositor setup will render without changes with this change. This commit does not include modifications in the GPU compositor implementation. Ref #88150 Pull Request: https://projects.blender.org/blender/blender/pulls/117223
69 lines
1.7 KiB
C++
69 lines
1.7 KiB
C++
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#pragma once
|
|
|
|
#include "COM_MultiThreadedOperation.h"
|
|
|
|
namespace blender::compositor {
|
|
|
|
/**
|
|
* \brief Pixelate operation
|
|
*
|
|
* The Tile compositor is by default sub-pixel accurate.
|
|
* For some setups you don want this.
|
|
* This operation will remove the sub-pixel accuracy
|
|
*/
|
|
class PixelateOperation : public MultiThreadedOperation {
|
|
private:
|
|
/**
|
|
* \brief cached reference to the input operation
|
|
*/
|
|
SocketReader *input_operation_;
|
|
|
|
int pixel_size_;
|
|
|
|
public:
|
|
PixelateOperation();
|
|
|
|
void set_pixel_size(const int pixel_size)
|
|
{
|
|
if (pixel_size < 1) {
|
|
pixel_size_ = 1;
|
|
return;
|
|
}
|
|
pixel_size_ = pixel_size;
|
|
}
|
|
|
|
/**
|
|
* \brief initialization of the execution
|
|
*/
|
|
void init_execution() override;
|
|
|
|
/**
|
|
* \brief de-initialization of the execution
|
|
*/
|
|
void deinit_execution() override;
|
|
|
|
bool determine_depending_area_of_interest(rcti *input,
|
|
ReadBufferOperation *read_operation,
|
|
rcti *output) override;
|
|
|
|
/**
|
|
* \brief execute_pixel
|
|
* \param output: result
|
|
* \param x: x-coordinate
|
|
* \param y: y-coordinate
|
|
* \param sampler: sampler
|
|
*/
|
|
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
|
|
|
|
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
|
|
void update_memory_buffer_partial(MemoryBuffer *output,
|
|
const rcti &area,
|
|
Span<MemoryBuffer *> inputs) override;
|
|
};
|
|
|
|
} // namespace blender::compositor
|