forked from bartvdbraak/blender
Fix T40448: Blurring bug in the compositor
This commit pretty much reverts all the changes related on tile-ability of the fast gaussian blur. It's not tilable by definition and would almost always give you seams on the tile boundaries. Atmind already met the issue and tried to solve it by increasing some magic constant, which is pretty much likely simply made it so compositor switched to full-frame calculation in that particular .blend file. Fast gaussian is really not a production thing and need to be avoided. We're to improve speed of normal gaussian blur instead.
This commit is contained in:
parent
fd781c1095
commit
9016d6d7a0
@ -109,13 +109,4 @@ typedef enum OrderOfChunks {
|
||||
|
||||
#define COM_BLUR_BOKEH_PIXELS 512
|
||||
|
||||
/**
|
||||
* The fast gaussien blur is not an accurate blur.
|
||||
* This setting can be used to increase/decrease the
|
||||
* amount of the input data. (dependent area of interest)
|
||||
*
|
||||
* Fix for: T39307
|
||||
*/
|
||||
#define COM_FAST_GAUSSIAN_MULTIPLIER 3
|
||||
|
||||
#endif /* __COM_DEFINES_H__ */
|
||||
|
@ -53,7 +53,6 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon
|
||||
if (data->filtertype == R_FILTER_FAST_GAUSS) {
|
||||
FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
|
||||
operationfgb->setData(data);
|
||||
operationfgb->setChunksize(context.getChunksize());
|
||||
converter.addOperation(operationfgb);
|
||||
|
||||
converter.mapInputSocket(getInputSocket(1), operationfgb->getInputSocket(1));
|
||||
|
@ -29,7 +29,6 @@
|
||||
FastGaussianBlurOperation::FastGaussianBlurOperation() : BlurBaseOperation(COM_DT_COLOR)
|
||||
{
|
||||
this->m_iirgaus = NULL;
|
||||
this->m_chunksize = 256;
|
||||
}
|
||||
|
||||
void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void *data)
|
||||
@ -38,57 +37,22 @@ void FastGaussianBlurOperation::executePixel(float output[4], int x, int y, void
|
||||
newData->read(output, x, y);
|
||||
}
|
||||
|
||||
// Calculate the depending area of interest. This depends on the
|
||||
// size of the blur operation; if the blur is large it is faster
|
||||
// to just calculate the whole image at once.
|
||||
// Returns true if the area is just a tile and false if it is
|
||||
// the whole image.
|
||||
bool FastGaussianBlurOperation::getDAI(rcti *rect, rcti *output)
|
||||
{
|
||||
// m_data.sizex * m_size should be enough? For some reason there
|
||||
// seem to be errors in the boundary between tiles.
|
||||
float size = this->m_size * COM_FAST_GAUSSIAN_MULTIPLIER;
|
||||
int sx = this->m_data.sizex * size;
|
||||
if (sx < 1)
|
||||
sx = 1;
|
||||
int sy = this->m_data.sizey * size;
|
||||
if (sy < 1)
|
||||
sy = 1;
|
||||
|
||||
if (sx >= this->m_chunksize || sy >= this->m_chunksize) {
|
||||
output->xmin = 0;
|
||||
output->xmax = this->getWidth();
|
||||
output->ymin = 0;
|
||||
output->ymax = this->getHeight();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
output->xmin = rect->xmin - sx - 1;
|
||||
output->xmax = rect->xmax + sx + 1;
|
||||
output->ymin = rect->ymin - sy - 1;
|
||||
output->ymax = rect->ymax + sy + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool FastGaussianBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
|
||||
{
|
||||
rcti newInput;
|
||||
|
||||
if (!this->m_sizeavailable) {
|
||||
rcti sizeInput;
|
||||
sizeInput.xmin = 0;
|
||||
sizeInput.ymin = 0;
|
||||
sizeInput.xmax = 5;
|
||||
sizeInput.ymax = 5;
|
||||
|
||||
NodeOperation *operation = this->getInputOperation(1);
|
||||
if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (this->m_sizeavailable) {
|
||||
getDAI(input, &newInput);
|
||||
else {
|
||||
if (this->m_iirgaus) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
newInput.xmin = 0;
|
||||
@ -117,7 +81,6 @@ void FastGaussianBlurOperation::deinitExecution()
|
||||
|
||||
void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
|
||||
{
|
||||
#if 0
|
||||
lockMutex();
|
||||
if (!this->m_iirgaus) {
|
||||
MemoryBuffer *newBuf = (MemoryBuffer *)this->m_inputProgram->initializeTileData(rect);
|
||||
@ -146,68 +109,8 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
|
||||
}
|
||||
unlockMutex();
|
||||
return this->m_iirgaus;
|
||||
#else
|
||||
|
||||
lockMutex();
|
||||
if (this->m_iirgaus) {
|
||||
// if this->m_iirgaus is set, we don't do tile rendering, so
|
||||
// we can return the already calculated cache
|
||||
unlockMutex();
|
||||
return this->m_iirgaus;
|
||||
}
|
||||
updateSize();
|
||||
rcti dai;
|
||||
bool use_tiles = getDAI(rect, &dai);
|
||||
if (use_tiles) {
|
||||
unlockMutex();
|
||||
}
|
||||
|
||||
MemoryBuffer *buffer = (MemoryBuffer *)this->m_inputProgram->initializeTileData(NULL);
|
||||
rcti *buf_rect = buffer->getRect();
|
||||
|
||||
dai.xmin = max(dai.xmin, buf_rect->xmin);
|
||||
dai.xmax = min(dai.xmax, buf_rect->xmax);
|
||||
dai.ymin = max(dai.ymin, buf_rect->ymin);
|
||||
dai.ymax = min(dai.ymax, buf_rect->ymax);
|
||||
|
||||
MemoryBuffer *tile = new MemoryBuffer(NULL, &dai);
|
||||
tile->copyContentFrom(buffer);
|
||||
|
||||
int c;
|
||||
float sx = this->m_data.sizex * this->m_size / 2.0f;
|
||||
float sy = this->m_data.sizey * this->m_size / 2.0f;
|
||||
|
||||
if ((sx == sy) && (sx > 0.f)) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
IIR_gauss(tile, sx, c, 3);
|
||||
}
|
||||
else {
|
||||
if (sx > 0.0f) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
IIR_gauss(tile, sx, c, 1);
|
||||
}
|
||||
if (sy > 0.0f) {
|
||||
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
|
||||
IIR_gauss(tile, sy, c, 2);
|
||||
}
|
||||
}
|
||||
if (!use_tiles) {
|
||||
this->m_iirgaus = tile;
|
||||
unlockMutex();
|
||||
}
|
||||
return tile;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FastGaussianBlurOperation::deinitializeTileData(rcti *rect, void *data)
|
||||
{
|
||||
if (!this->m_iirgaus && data) {
|
||||
MemoryBuffer *tile = (MemoryBuffer *)data;
|
||||
delete tile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsigned int chan, unsigned int xy)
|
||||
{
|
||||
double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3];
|
||||
|
@ -28,19 +28,16 @@
|
||||
|
||||
class FastGaussianBlurOperation : public BlurBaseOperation {
|
||||
private:
|
||||
float m_sx;
|
||||
float m_sy;
|
||||
MemoryBuffer *m_iirgaus;
|
||||
int m_chunksize;
|
||||
|
||||
public:
|
||||
FastGaussianBlurOperation();
|
||||
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
|
||||
void executePixel(float output[4], int x, int y, void *data);
|
||||
void setChunksize(int size) { this->m_chunksize = size; }
|
||||
|
||||
static void IIR_gauss(MemoryBuffer *src, float sigma, unsigned int channel, unsigned int xy);
|
||||
bool getDAI(rcti *rect, rcti *output);
|
||||
void *initializeTileData(rcti *rect);
|
||||
void deinitializeTileData(rcti *rect, void *data);
|
||||
void deinitExecution();
|
||||
void initExecution();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user