diff options
Diffstat (limited to 'source/blender/compositor')
-rw-r--r-- | source/blender/compositor/operations/COM_TextureOperation.cc | 73 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_TextureOperation.h | 12 |
2 files changed, 75 insertions, 10 deletions
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cc b/source/blender/compositor/operations/COM_TextureOperation.cc index 059a289ae4d..c8e0844d35f 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cc +++ b/source/blender/compositor/operations/COM_TextureOperation.cc @@ -157,14 +157,8 @@ void TextureBaseOperation::executePixelSampled(float output[4], m_sceneColorManage, false); - if (texres.talpha) { - output[3] = texres.ta; - } - else { - output[3] = texres.tin; - } - - if ((retval & TEX_RGB)) { + output[3] = texres.talpha ? texres.ta : texres.tin; + if (retval & TEX_RGB) { output[0] = texres.tr; output[1] = texres.tg; output[2] = texres.tb; @@ -174,4 +168,67 @@ void TextureBaseOperation::executePixelSampled(float output[4], } } +void TextureBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) +{ + const int op_width = this->getWidth(); + const int op_height = this->getHeight(); + const float center_x = op_width / 2; + const float center_y = op_height / 2; + TexResult tex_result = {0}; + float vec[3]; + const int thread_id = WorkScheduler::current_thread_id(); + for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) { + const float *tex_offset = it.in(0); + const float *tex_size = it.in(1); + float u = (it.x - center_x) / op_width * 2; + float v = (it.y - center_y) / op_height * 2; + + /* When no interpolation/filtering happens in multitex() force nearest interpolation. + * We do it here because (a) we can't easily say multitex() that we want nearest + * interpolation and (b) in such configuration multitex() simply floor's the value + * which often produces artifacts. + */ + if (m_texture != nullptr && (m_texture->imaflag & TEX_INTERPOL) == 0) { + u += 0.5f / center_x; + v += 0.5f / center_y; + } + + vec[0] = tex_size[0] * (u + tex_offset[0]); + vec[1] = tex_size[1] * (v + tex_offset[1]); + vec[2] = tex_size[2] * tex_offset[2]; + + const int retval = multitex_ext(this->m_texture, + vec, + nullptr, + nullptr, + 0, + &tex_result, + thread_id, + m_pool, + m_sceneColorManage, + false); + + it.out[3] = tex_result.talpha ? tex_result.ta : tex_result.tin; + if (retval & TEX_RGB) { + it.out[0] = tex_result.tr; + it.out[1] = tex_result.tg; + it.out[2] = tex_result.tb; + } + else { + it.out[0] = it.out[1] = it.out[2] = it.out[3]; + } + } +} + +void TextureAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) +{ + MemoryBuffer texture(DataType::Color, area); + TextureBaseOperation::update_memory_buffer_partial(&texture, area, inputs); + output->copy_from(&texture, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); +} + } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h index 6fec9ab8f33..1e95cb270d0 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.h +++ b/source/blender/compositor/operations/COM_TextureOperation.h @@ -19,7 +19,7 @@ #pragma once #include "BLI_listbase.h" -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedOperation.h" #include "DNA_texture_types.h" #include "MEM_guardedalloc.h" @@ -33,7 +33,7 @@ namespace blender::compositor { * * \todo Rename to operation. */ -class TextureBaseOperation : public NodeOperation { +class TextureBaseOperation : public MultiThreadedOperation { private: Tex *m_texture; const RenderData *m_rd; @@ -71,6 +71,10 @@ class TextureBaseOperation : public NodeOperation { { this->m_sceneColorManage = sceneColorManage; } + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) override; }; class TextureOperation : public TextureBaseOperation { @@ -81,6 +85,10 @@ class TextureAlphaOperation : public TextureBaseOperation { public: TextureAlphaOperation(); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) override; }; } // namespace blender::compositor |