diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2013-12-04 14:56:36 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2013-12-04 15:09:13 +0400 |
commit | 45fc80153a40fb01db6b1e25b4ab575a06a331b8 (patch) | |
tree | 898972a78c5074ef1fc3f4f90c9f9791225c538f /source/blender/compositor/operations/COM_MultilayerImageOperation.cpp | |
parent | a698709d956f01ff4a2a1c0d27450c6880dd2ad5 (diff) |
Fix for interpolation errors on lower-left borders in compositor image
inputs.
http://wiki.blender.org/uploads/4/4c/Compo_image_interpolation_borders.png
Problem is that all image buffer reader nodes (RenderLayer, Image,
MovieClip) were clipping pixel coordinates to 0..N range (N being width
or height respectively). Bilinear interpolation works ok then on the
upper-right borders (x, N) and (N, y), since the last (N-1) pixel fades
out to N (background). But the lower-left (x, 0) and (0, y) borders are
not correctly interpolated because the nodes cut off the negative pixels
before the interpolation function can calculate their value.
To fix this, the interpolation functions are now entirely responsible
for handling "out of range" cases, i.e. setting (0,0,0,0) results for
invalid pixels, while also handling interpolation for borders.
Callers should not do pixel range checks themselves, which also makes
the code simpler. Should not have any real performance penalty,
the interpolation functions do this check anyway, so is probably even
slightly faster.
Diffstat (limited to 'source/blender/compositor/operations/COM_MultilayerImageOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_MultilayerImageOperation.cpp | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index 84c1fdfb6f5..ffa319f20a8 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -44,9 +44,7 @@ ImBuf *MultilayerBaseOperation::getImBuf() void MultilayerColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - int yi = y; - int xi = x; - if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) { + if (this->m_imageFloatBuffer == NULL) { zero_v4(output); } else { @@ -64,34 +62,48 @@ void MultilayerColorOperation::executePixelSampled(float output[4], float x, flo } } else { - int offset = (yi * this->getWidth() + xi) * 3; - copy_v3_v3(output, &this->m_imageFloatBuffer[offset]); + int yi = y; + int xi = x; + if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight()) + zero_v4(output); + else { + int offset = (yi * this->getWidth() + xi) * 3; + copy_v3_v3(output, &this->m_imageFloatBuffer[offset]); + } } } } void MultilayerValueOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - int yi = y; - int xi = x; - if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) { + if (this->m_imageFloatBuffer == NULL) { output[0] = 0.0f; } else { - float result = this->m_imageFloatBuffer[yi * this->getWidth() + xi]; - output[0] = result; + int yi = y; + int xi = x; + if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight()) + output[0] = 0.0f; + else { + float result = this->m_imageFloatBuffer[yi * this->getWidth() + xi]; + output[0] = result; + } } } void MultilayerVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { - int yi = y; - int xi = x; - if (this->m_imageFloatBuffer == NULL || xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight() ) { + if (this->m_imageFloatBuffer == NULL) { output[0] = 0.0f; } else { - int offset = (yi * this->getWidth() + xi) * 3; - copy_v3_v3(output, &this->m_imageFloatBuffer[offset]); + int yi = y; + int xi = x; + if (xi < 0 || yi < 0 || (unsigned int)xi >= this->getWidth() || (unsigned int)yi >= this->getHeight()) + output[0] = 0.0f; + else { + int offset = (yi * this->getWidth() + xi) * 3; + copy_v3_v3(output, &this->m_imageFloatBuffer[offset]); + } } } |