diff options
Diffstat (limited to 'source/blender/compositor')
212 files changed, 4818 insertions, 697 deletions
diff --git a/source/blender/compositor/intern/COM_CPUDevice.cc b/source/blender/compositor/intern/COM_CPUDevice.cc index 93c0b233752..916c7e1a411 100644 --- a/source/blender/compositor/intern/COM_CPUDevice.cc +++ b/source/blender/compositor/intern/COM_CPUDevice.cc @@ -16,7 +16,7 @@ void CPUDevice::execute(WorkPackage *work_package) { switch (work_package->type) { case eWorkPackageType::Tile: { - const unsigned int chunk_number = work_package->chunk_number; + const uint chunk_number = work_package->chunk_number; ExecutionGroup *execution_group = work_package->execution_group; execution_group->get_output_operation()->execute_region(&work_package->rect, chunk_number); diff --git a/source/blender/compositor/intern/COM_ChunkOrder.cc b/source/blender/compositor/intern/COM_ChunkOrder.cc index 38298840bf0..acc19155049 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.cc +++ b/source/blender/compositor/intern/COM_ChunkOrder.cc @@ -7,7 +7,7 @@ namespace blender::compositor { -void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots) +void ChunkOrder::update_distance(ChunkOrderHotspot *hotspots, uint len_hotspots) { double new_distance = DBL_MAX; for (int index = 0; index < len_hotspots; index++) { diff --git a/source/blender/compositor/intern/COM_ChunkOrder.h b/source/blender/compositor/intern/COM_ChunkOrder.h index 927eab97ccd..ef65d90dd3a 100644 --- a/source/blender/compositor/intern/COM_ChunkOrder.h +++ b/source/blender/compositor/intern/COM_ChunkOrder.h @@ -7,20 +7,22 @@ # include "MEM_guardedalloc.h" #endif +#include "BLI_sys_types.h" + #include "COM_ChunkOrderHotspot.h" namespace blender::compositor { /** Helper to determine the order how chunks are prioritized during execution. */ struct ChunkOrder { - unsigned int index = 0; + uint index = 0; int x = 0; int y = 0; double distance = 0.0; friend bool operator<(const ChunkOrder &a, const ChunkOrder &b); - void update_distance(ChunkOrderHotspot *hotspots, unsigned int len_hotspots); + void update_distance(ChunkOrderHotspot *hotspots, uint len_hotspots); #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:ChunkOrderHotspot") diff --git a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc index b9179c0a910..5b9d2fa2797 100644 --- a/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc +++ b/source/blender/compositor/intern/COM_ChunkOrderHotspot.cc @@ -10,8 +10,8 @@ double ChunkOrderHotspot::calc_distance(int x, int y) { int dx = this->x - x; int dy = this->y - y; - double result = sqrt((double)(dx * dx + dy * dy)); - result += (double)this->addition; + double result = sqrt(double(dx * dx + dy * dy)); + result += double(this->addition); return result; } diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc index d0f0be590f6..a670af5eaca 100644 --- a/source/blender/compositor/intern/COM_Debug.cc +++ b/source/blender/compositor/intern/COM_Debug.cc @@ -305,7 +305,7 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma for (NodeOperation *operation : group->operations_) { - sprintf(strbuf, "_%p", group); + BLI_snprintf(strbuf, sizeof(strbuf), "_%p", group); op_groups[operation].push_back(std::string(strbuf)); len += graphviz_operation( @@ -428,7 +428,7 @@ void DebugInfo::graphviz(const ExecutionSystem *system, StringRefNull name) else { BLI_strncpy(basename, (name + ".dot").c_str(), sizeof(basename)); } - BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_session(), basename); + BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), basename); file_index_++; std::cout << "Writing compositor debug to: " << filepath << "\n"; diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc index 6f2d4faffb1..c9002b535ed 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cc +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc @@ -126,7 +126,7 @@ void ExecutionGroup::init_work_packages() work_packages_.clear(); if (chunks_len_ != 0) { work_packages_.resize(chunks_len_); - for (unsigned int index = 0; index < chunks_len_; index++) { + for (uint index = 0; index < chunks_len_; index++) { work_packages_[index].type = eWorkPackageType::Tile; work_packages_[index].state = eWorkPackageState::NotScheduled; work_packages_[index].execution_group = this; @@ -138,7 +138,7 @@ void ExecutionGroup::init_work_packages() void ExecutionGroup::init_read_buffer_operations() { - unsigned int max_offset = 0; + uint max_offset = 0; for (NodeOperation *operation : operations_) { if (operation->get_flags().is_read_buffer_operation) { ReadBufferOperation *read_operation = static_cast<ReadBufferOperation *>(operation); @@ -167,7 +167,7 @@ void ExecutionGroup::deinit_execution() bTree_ = nullptr; } -void ExecutionGroup::determine_resolution(unsigned int resolution[2]) +void ExecutionGroup::determine_resolution(uint resolution[2]) { NodeOperation *operation = this->get_output_operation(); resolution[0] = operation->get_width(); @@ -193,9 +193,9 @@ void ExecutionGroup::init_number_of_chunks() } } -blender::Array<unsigned int> ExecutionGroup::get_execution_order() const +blender::Array<uint> ExecutionGroup::get_execution_order() const { - blender::Array<unsigned int> chunk_order(chunks_len_); + blender::Array<uint> chunk_order(chunks_len_); for (int chunk_index = 0; chunk_index < chunks_len_; chunk_index++) { chunk_order[chunk_index] = chunk_index; } @@ -218,7 +218,7 @@ blender::Array<unsigned int> ExecutionGroup::get_execution_order() const switch (order_type) { case ChunkOrdering::Random: { static blender::RandomNumberGenerator rng; - blender::MutableSpan<unsigned int> span = chunk_order.as_mutable_span(); + blender::MutableSpan<uint> span = chunk_order.as_mutable_span(); /* Shuffle twice to make it more random. */ rng.shuffle(span); rng.shuffle(span); @@ -243,12 +243,12 @@ blender::Array<unsigned int> ExecutionGroup::get_execution_order() const break; } case ChunkOrdering::RuleOfThirds: { - unsigned int tx = border_width / 6; - unsigned int ty = border_height / 6; - unsigned int mx = border_width / 2; - unsigned int my = border_height / 2; - unsigned int bx = mx + 2 * tx; - unsigned int by = my + 2 * ty; + uint tx = border_width / 6; + uint ty = border_height / 6; + uint mx = border_width / 2; + uint my = border_height / 2; + uint bx = mx + 2 * tx; + uint by = my + 2 * ty; float addition = chunks_len_ / COM_RULE_OF_THIRDS_DIVIDER; ChunkOrderHotspot hotspots[9]{ @@ -300,21 +300,21 @@ void ExecutionGroup::execute(ExecutionSystem *graph) if (chunks_len_ == 0) { return; } /** \note Early break out. */ - unsigned int chunk_index; + uint chunk_index; execution_start_time_ = PIL_check_seconds_timer(); chunks_finished_ = 0; bTree_ = bTree; - blender::Array<unsigned int> chunk_order = get_execution_order(); + blender::Array<uint> chunk_order = get_execution_order(); DebugInfo::execution_group_started(this); DebugInfo::graphviz(graph); bool breaked = false; bool finished = false; - unsigned int start_index = 0; + uint start_index = 0; const int max_number_evaluated = BLI_system_thread_count() * 2; while (!finished && !breaked) { @@ -399,7 +399,7 @@ void ExecutionGroup::finalize_chunk_execution(int chunk_number, MemoryBuffer **m atomic_add_and_fetch_u(&chunks_finished_, 1); if (memory_buffers) { - for (unsigned int index = 0; index < max_read_buffer_offset_; index++) { + for (uint index = 0; index < max_read_buffer_offset_; index++) { MemoryBuffer *buffer = memory_buffers[index]; if (buffer) { if (buffer->is_temporarily()) { @@ -424,8 +424,8 @@ void ExecutionGroup::finalize_chunk_execution(int chunk_number, MemoryBuffer **m } inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect, - const unsigned int x_chunk, - const unsigned int y_chunk) const + const uint x_chunk, + const uint y_chunk) const { const int border_width = BLI_rcti_size_x(&viewer_border_); const int border_height = BLI_rcti_size_y(&viewer_border_); @@ -434,10 +434,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect, BLI_rcti_init(r_rect, viewer_border_.xmin, border_width, viewer_border_.ymin, border_height); } else { - const unsigned int minx = x_chunk * chunk_size_ + viewer_border_.xmin; - const unsigned int miny = y_chunk * chunk_size_ + viewer_border_.ymin; - const unsigned int width = MIN2((unsigned int)viewer_border_.xmax, width_); - const unsigned int height = MIN2((unsigned int)viewer_border_.ymax, height_); + const uint minx = x_chunk * chunk_size_ + viewer_border_.xmin; + const uint miny = y_chunk * chunk_size_ + viewer_border_.ymin; + const uint width = MIN2(uint(viewer_border_.xmax), width_); + const uint height = MIN2(uint(viewer_border_.ymax), height_); BLI_rcti_init(r_rect, MIN2(minx, width_), MIN2(minx + chunk_size_, width), @@ -446,10 +446,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect, } } -void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const unsigned int chunk_number) const +void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const uint chunk_number) const { - const unsigned int y_chunk = chunk_number / x_chunks_len_; - const unsigned int x_chunk = chunk_number - (y_chunk * x_chunks_len_); + const uint y_chunk = chunk_number / x_chunks_len_; + const uint x_chunk = chunk_number - (y_chunk * x_chunks_len_); determine_chunk_rect(r_rect, x_chunk, y_chunk); } @@ -480,14 +480,14 @@ bool ExecutionGroup::schedule_area_when_possible(ExecutionSystem *graph, rcti *a int maxx = min_ii(area->xmax - viewer_border_.xmin, viewer_border_.xmax - viewer_border_.xmin); int miny = max_ii(area->ymin - viewer_border_.ymin, 0); int maxy = min_ii(area->ymax - viewer_border_.ymin, viewer_border_.ymax - viewer_border_.ymin); - int minxchunk = minx / (int)chunk_size_; - int maxxchunk = (maxx + (int)chunk_size_ - 1) / (int)chunk_size_; - int minychunk = miny / (int)chunk_size_; - int maxychunk = (maxy + (int)chunk_size_ - 1) / (int)chunk_size_; + int minxchunk = minx / int(chunk_size_); + int maxxchunk = (maxx + int(chunk_size_) - 1) / int(chunk_size_); + int minychunk = miny / int(chunk_size_); + int maxychunk = (maxy + int(chunk_size_) - 1) / int(chunk_size_); minxchunk = max_ii(minxchunk, 0); minychunk = max_ii(minychunk, 0); - maxxchunk = min_ii(maxxchunk, (int)x_chunks_len_); - maxychunk = min_ii(maxychunk, (int)y_chunks_len_); + maxxchunk = min_ii(maxxchunk, int(x_chunks_len_)); + maxychunk = min_ii(maxychunk, int(y_chunks_len_)); bool result = true; for (indexx = minxchunk; indexx < maxxchunk; indexx++) { @@ -501,7 +501,7 @@ bool ExecutionGroup::schedule_area_when_possible(ExecutionSystem *graph, rcti *a return result; } -bool ExecutionGroup::schedule_chunk(unsigned int chunk_number) +bool ExecutionGroup::schedule_chunk(uint chunk_number) { WorkPackage &work_package = work_packages_[chunk_number]; if (work_package.state == eWorkPackageState::NotScheduled) { @@ -516,10 +516,10 @@ bool ExecutionGroup::schedule_chunk_when_possible(ExecutionSystem *graph, const int chunk_x, const int chunk_y) { - if (chunk_x < 0 || chunk_x >= (int)x_chunks_len_) { + if (chunk_x < 0 || chunk_x >= int(x_chunks_len_)) { return true; } - if (chunk_y < 0 || chunk_y >= (int)y_chunks_len_) { + if (chunk_y < 0 || chunk_y >= int(y_chunks_len_)) { return true; } diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc index ceb52feb9b4..11e3c1507d9 100644 --- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc +++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc @@ -271,7 +271,7 @@ void FullFrameExecutionModel::update_progress_bar() { const bNodeTree *tree = context_.get_bnodetree(); if (tree) { - const float progress = num_operations_finished_ / static_cast<float>(operations_.size()); + const float progress = num_operations_finished_ / float(operations_.size()); tree->progress(tree->prh, progress); char buf[128]; diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc index ea2a85e8ea9..539e1179bc8 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc @@ -133,8 +133,8 @@ MemoryBuffer *MemoryBuffer::inflate() const float MemoryBuffer::get_max_value() const { float result = buffer_[0]; - const unsigned int size = this->buffer_len(); - unsigned int i; + const uint size = this->buffer_len(); + uint i; const float *fp_src = buffer_; @@ -266,7 +266,7 @@ void MemoryBuffer::copy_from(const uchar *src, const float *row_end = to_elem + width * this->elem_stride; while (to_elem < row_end) { for (int i = 0; i < elem_size; i++) { - to_elem[i] = ((float)from_elem[i]) * (1.0f / 255.0f); + to_elem[i] = float(from_elem[i]) * (1.0f / 255.0f); } to_elem += this->elem_stride; from_elem += elem_stride; @@ -427,7 +427,7 @@ void MemoryBuffer::read_elem_filtered( const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}}; - float inv_width = 1.0f / (float)this->get_width(), inv_height = 1.0f / (float)this->get_height(); + float inv_width = 1.0f / float(this->get_width()), inv_height = 1.0f / float(this->get_height()); /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives, * but compositor uses pixel space. For now let's just divide the values and * switch compositor to normalized space for EWA later. @@ -463,8 +463,8 @@ void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivat } else { BLI_assert(datatype_ == DataType::Color); - float inv_width = 1.0f / (float)this->get_width(), - inv_height = 1.0f / (float)this->get_height(); + float inv_width = 1.0f / float(this->get_width()), + inv_height = 1.0f / float(this->get_height()); /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives, * but compositor uses pixel space. For now let's just divide the values and * switch compositor to normalized space for EWA later. diff --git a/source/blender/compositor/intern/COM_MemoryProxy.cc b/source/blender/compositor/intern/COM_MemoryProxy.cc index 42d0f86843d..723e8b3ab9b 100644 --- a/source/blender/compositor/intern/COM_MemoryProxy.cc +++ b/source/blender/compositor/intern/COM_MemoryProxy.cc @@ -14,7 +14,7 @@ MemoryProxy::MemoryProxy(DataType datatype) datatype_ = datatype; } -void MemoryProxy::allocate(unsigned int width, unsigned int height) +void MemoryProxy::allocate(uint width, uint height) { rcti result; result.xmin = 0; diff --git a/source/blender/compositor/intern/COM_MetaData.cc b/source/blender/compositor/intern/COM_MetaData.cc index 9ee3d7e5c22..94a0bc8706b 100644 --- a/source/blender/compositor/intern/COM_MetaData.cc +++ b/source/blender/compositor/intern/COM_MetaData.cc @@ -72,7 +72,7 @@ void MetaDataExtractCallbackData::set_cryptomatte_keys(blender::StringRef crypto void MetaDataExtractCallbackData::extract_cryptomatte_meta_data(void *_data, const char *propname, char *propvalue, - int UNUSED(len)) + int /*len*/) { MetaDataExtractCallbackData *data = static_cast<MetaDataExtractCallbackData *>(_data); blender::StringRefNull key(propname); diff --git a/source/blender/compositor/intern/COM_MultiThreadedOperation.h b/source/blender/compositor/intern/COM_MultiThreadedOperation.h index 9ec81fa834e..355081c374d 100644 --- a/source/blender/compositor/intern/COM_MultiThreadedOperation.h +++ b/source/blender/compositor/intern/COM_MultiThreadedOperation.h @@ -24,9 +24,9 @@ class MultiThreadedOperation : public NodeOperation { /** * Called before an update memory buffer pass is executed. Single-threaded calls. */ - virtual void update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), - Span<MemoryBuffer *> UNUSED(inputs)) + virtual void update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, + Span<MemoryBuffer *> /*inputs*/) { } @@ -40,9 +40,9 @@ class MultiThreadedOperation : public NodeOperation { /** * Called after an update memory buffer pass is executed. Single-threaded calls. */ - virtual void update_memory_buffer_finished(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), - Span<MemoryBuffer *> UNUSED(inputs)) + virtual void update_memory_buffer_finished(MemoryBuffer * /*output*/, + const rcti & /*area*/, + Span<MemoryBuffer *> /*inputs*/) { } diff --git a/source/blender/compositor/intern/COM_Node.cc b/source/blender/compositor/intern/COM_Node.cc index a71c7868518..c1a8740d8ea 100644 --- a/source/blender/compositor/intern/COM_Node.cc +++ b/source/blender/compositor/intern/COM_Node.cc @@ -53,10 +53,10 @@ Node::Node(bNode *editor_node, bool create_sockets) Node::~Node() { while (!outputs_.is_empty()) { - delete (outputs_.pop_last()); + delete outputs_.pop_last(); } while (!inputs_.is_empty()) { - delete (inputs_.pop_last()); + delete inputs_.pop_last(); } } @@ -81,12 +81,12 @@ void Node::add_output_socket(DataType datatype, bNodeSocket *bSocket) outputs_.append(socket); } -NodeOutput *Node::get_output_socket(unsigned int index) const +NodeOutput *Node::get_output_socket(uint index) const { return outputs_[index]; } -NodeInput *Node::get_input_socket(unsigned int index) const +NodeInput *Node::get_input_socket(uint index) const { return inputs_[index]; } diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc index 3867b1d5c10..ab9b5ad1ad6 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cc +++ b/source/blender/compositor/intern/COM_NodeOperation.cc @@ -84,12 +84,12 @@ std::optional<NodeOperationHash> NodeOperation::generate_hash() return hash; } -NodeOperationOutput *NodeOperation::get_output_socket(unsigned int index) +NodeOperationOutput *NodeOperation::get_output_socket(uint index) { return &outputs_[index]; } -NodeOperationInput *NodeOperation::get_input_socket(unsigned int index) +NodeOperationInput *NodeOperation::get_input_socket(uint index) { return &inputs_[index]; } @@ -106,7 +106,7 @@ void NodeOperation::add_output_socket(DataType datatype) void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) { - unsigned int used_canvas_index = 0; + uint used_canvas_index = 0; if (canvas_input_index_ == RESOLUTION_INPUT_ANY) { for (NodeOperationInput &input : inputs_) { rcti any_area = COM_AREA_NONE; @@ -130,7 +130,7 @@ void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) rcti unused_area = COM_AREA_NONE; const rcti &local_preferred_area = r_area; - for (unsigned int index = 0; index < inputs_.size(); index++) { + for (uint index = 0; index < inputs_.size(); index++) { if (index == used_canvas_index) { continue; } @@ -141,7 +141,7 @@ void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) } } -void NodeOperation::set_canvas_input_index(unsigned int index) +void NodeOperation::set_canvas_input_index(uint index) { this->canvas_input_index_ = index; } @@ -197,7 +197,7 @@ void NodeOperation::unset_canvas() flags_.is_canvas_set = false; } -SocketReader *NodeOperation::get_input_socket_reader(unsigned int index) +SocketReader *NodeOperation::get_input_socket_reader(uint index) { return this->get_input_socket(index)->get_reader(); } diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index aa9e4329ab6..a00ac1352fe 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -628,9 +628,9 @@ class NodeOperation { /** * Executes operation updating output memory buffer. Single-threaded calls. */ - virtual void update_memory_buffer(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), - Span<MemoryBuffer *> UNUSED(inputs)) + virtual void update_memory_buffer(MemoryBuffer * /*output*/, + const rcti & /*area*/, + Span<MemoryBuffer *> /*inputs*/) { } diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc index 1fdec43eb3b..8212be5ec26 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc @@ -576,7 +576,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, /* try to find existing write buffer operation */ if (target->get_operation().get_flags().is_write_buffer_operation) { BLI_assert(write_operation == nullptr); /* there should only be one write op connected */ - write_operation = (WriteBufferOperation *)(&target->get_operation()); + write_operation = (WriteBufferOperation *)&target->get_operation(); } else { /* remove all links to other nodes */ diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cc b/source/blender/compositor/intern/COM_OpenCLDevice.cc index d951ebef172..188389b88c9 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cc +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cc @@ -56,7 +56,7 @@ OpenCLDevice::~OpenCLDevice() void OpenCLDevice::execute(WorkPackage *work_package) { - const unsigned int chunk_number = work_package->chunk_number; + const uint chunk_number = work_package->chunk_number; ExecutionGroup *execution_group = work_package->execution_group; MemoryBuffer **input_buffers = execution_group->get_input_buffers_opencl(chunk_number); @@ -187,8 +187,8 @@ void OpenCLDevice::COM_cl_enqueue_range(cl_kernel kernel, MemoryBuffer *output_m { cl_int error; const size_t size[] = { - (size_t)output_memory_buffer->get_width(), - (size_t)output_memory_buffer->get_height(), + size_t(output_memory_buffer->get_width()), + size_t(output_memory_buffer->get_height()), }; error = clEnqueueNDRangeKernel(queue_, kernel, 2, nullptr, size, nullptr, 0, nullptr, nullptr); diff --git a/source/blender/compositor/intern/COM_TiledExecutionModel.cc b/source/blender/compositor/intern/COM_TiledExecutionModel.cc index cf8d3e9a084..54e8e8f315a 100644 --- a/source/blender/compositor/intern/COM_TiledExecutionModel.cc +++ b/source/blender/compositor/intern/COM_TiledExecutionModel.cc @@ -23,7 +23,7 @@ TiledExecutionModel::TiledExecutionModel(CompositorContext &context, const bNodeTree *node_tree = context.get_bnodetree(); node_tree->stats_draw(node_tree->sdh, TIP_("Compositing | Determining resolution")); - unsigned int resolution[2]; + uint resolution[2]; for (ExecutionGroup *group : groups_) { resolution[0] = 0; resolution[1] = 0; @@ -45,7 +45,7 @@ TiledExecutionModel::TiledExecutionModel(CompositorContext &context, static void update_read_buffer_offset(Span<NodeOperation *> operations) { - unsigned int order = 0; + uint order = 0; for (NodeOperation *operation : operations) { if (operation->get_flags().is_read_buffer_operation) { ReadBufferOperation *read_operation = (ReadBufferOperation *)operation; diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc index 1f93a3d9bfa..9067807d98c 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ b/source/blender/compositor/intern/COM_WorkScheduler.cc @@ -185,7 +185,7 @@ static void opencl_initialize(const bool use_opencl) cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN( sizeof(cl_platform_id) * number_of_platforms, __func__); error = clGetPlatformIDs(number_of_platforms, platforms, nullptr); - unsigned int index_platform; + uint index_platform; for (index_platform = 0; index_platform < number_of_platforms; index_platform++) { cl_platform_id platform = platforms[index_platform]; cl_uint number_of_devices = 0; @@ -240,7 +240,7 @@ static void opencl_initialize(const bool use_opencl) MEM_freeN(build_log); } else { - unsigned int index_devices; + uint index_devices; for (index_devices = 0; index_devices < number_of_devices; index_devices++) { cl_device_id device = cldevices[index_devices]; cl_int vendorID = 0; @@ -377,7 +377,7 @@ static void threading_model_queue_deinitialize() /** \name Task Scheduling * \{ */ -static void threading_model_task_execute(TaskPool *__restrict UNUSED(pool), void *task_data) +static void threading_model_task_execute(TaskPool *__restrict /*pool*/, void *task_data) { WorkPackage *package = static_cast<WorkPackage *>(task_data); CPUDevice device(BLI_task_parallel_thread_id(nullptr)); diff --git a/source/blender/compositor/intern/COM_compositor.cc b/source/blender/compositor/intern/COM_compositor.cc index 519ad93bcaf..1ffc749ce64 100644 --- a/source/blender/compositor/intern/COM_compositor.cc +++ b/source/blender/compositor/intern/COM_compositor.cc @@ -25,15 +25,15 @@ static void compositor_init_node_previews(const RenderData *render_data, bNodeTr /* We fit the aspect into COM_PREVIEW_SIZE x COM_PREVIEW_SIZE image to avoid * insane preview resolution, which might even overflow preview dimensions. */ const float aspect = render_data->xsch > 0 ? - (float)render_data->ysch / (float)render_data->xsch : + float(render_data->ysch) / float(render_data->xsch) : 1.0f; int preview_width, preview_height; if (aspect < 1.0f) { preview_width = blender::compositor::COM_PREVIEW_SIZE; - preview_height = (int)(blender::compositor::COM_PREVIEW_SIZE * aspect); + preview_height = int(blender::compositor::COM_PREVIEW_SIZE * aspect); } else { - preview_width = (int)(blender::compositor::COM_PREVIEW_SIZE / aspect); + preview_width = int(blender::compositor::COM_PREVIEW_SIZE / aspect); preview_height = blender::compositor::COM_PREVIEW_SIZE; } BKE_node_preview_init_tree(node_tree, preview_width, preview_height); diff --git a/source/blender/compositor/nodes/COM_CombineColorNode.cc b/source/blender/compositor/nodes/COM_CombineColorNode.cc index 36ff24cb9c3..7802a585c05 100644 --- a/source/blender/compositor/nodes/COM_CombineColorNode.cc +++ b/source/blender/compositor/nodes/COM_CombineColorNode.cc @@ -12,7 +12,7 @@ CombineColorNode::CombineColorNode(bNode *editor_node) : Node(editor_node) } void CombineColorNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &UNUSED(context)) const + const CompositorContext & /*context*/) const { NodeInput *input_rsocket = this->get_input_socket(0); NodeInput *input_gsocket = this->get_input_socket(1); diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.cc b/source/blender/compositor/nodes/COM_CombineXYZNode.cc index 0b46f7ba0d4..dd09dabef02 100644 --- a/source/blender/compositor/nodes/COM_CombineXYZNode.cc +++ b/source/blender/compositor/nodes/COM_CombineXYZNode.cc @@ -12,7 +12,7 @@ CombineXYZNode::CombineXYZNode(bNode *editor_node) : Node(editor_node) } void CombineXYZNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &UNUSED(context)) const + const CompositorContext & /*context*/) const { NodeInput *input_x_socket = this->get_input_socket(0); NodeInput *input_y_socket = this->get_input_socket(1); diff --git a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc index 7d557de66e4..d26b649e30b 100644 --- a/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc +++ b/source/blender/compositor/nodes/COM_ConvertColorSpaceNode.cc @@ -25,7 +25,7 @@ ConvertColorSpaceNode::ConvertColorSpaceNode(bNode *editorNode) : Node(editorNod } void ConvertColorSpaceNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &UNUSED(context)) const + const CompositorContext & /*context*/) const { const bNode *b_node = get_bnode(); diff --git a/source/blender/compositor/nodes/COM_CropNode.cc b/source/blender/compositor/nodes/COM_CropNode.cc index 849fb80a8a8..80f345e8762 100644 --- a/source/blender/compositor/nodes/COM_CropNode.cc +++ b/source/blender/compositor/nodes/COM_CropNode.cc @@ -16,8 +16,8 @@ void CropNode::convert_to_operations(NodeConverter &converter, { const bNode *node = get_bnode(); NodeTwoXYs *crop_settings = (NodeTwoXYs *)node->storage; - bool relative = (bool)node->custom2; - bool crop_image = (bool)node->custom1; + bool relative = bool(node->custom2); + bool crop_image = bool(node->custom1); CropBaseOperation *operation; if (crop_image) { operation = new CropImageOperation(); diff --git a/source/blender/compositor/nodes/COM_CryptomatteNode.cc b/source/blender/compositor/nodes/COM_CryptomatteNode.cc index 42d699af01b..ee31fce0ea8 100644 --- a/source/blender/compositor/nodes/COM_CryptomatteNode.cc +++ b/source/blender/compositor/nodes/COM_CryptomatteNode.cc @@ -10,6 +10,7 @@ #include "COM_MultilayerImageOperation.h" #include "COM_RenderLayersProg.h" #include "COM_SetAlphaMultiplyOperation.h" +#include "COM_SetAlphaReplaceOperation.h" #include "COM_SetColorOperation.h" namespace blender::compositor { @@ -48,7 +49,7 @@ void CryptomatteBaseNode::convert_to_operations(NodeConverter &converter, converter.map_output_socket(output_image_socket, apply_mask_operation->get_output_socket(0)); NodeOutput *output_pick_socket = this->get_output_socket(2); - SetAlphaMultiplyOperation *extract_pick_operation = new SetAlphaMultiplyOperation(); + SetAlphaReplaceOperation *extract_pick_operation = new SetAlphaReplaceOperation(); converter.add_operation(extract_pick_operation); converter.add_input_value(extract_pick_operation->get_input_socket(1), 1.0f); converter.add_link(cryptomatte_operation->get_output_socket(0), @@ -240,8 +241,8 @@ CryptomatteOperation *CryptomatteNode::create_cryptomatte_operation( CryptomatteOperation *CryptomatteLegacyNode::create_cryptomatte_operation( NodeConverter &converter, - const CompositorContext &UNUSED(context), - const bNode &UNUSED(node), + const CompositorContext & /*context*/, + const bNode & /*node*/, const NodeCryptomatte *cryptomatte_settings) const { const int num_inputs = inputs_.size() - 1; diff --git a/source/blender/compositor/nodes/COM_MapUVNode.cc b/source/blender/compositor/nodes/COM_MapUVNode.cc index ed9bff657f3..0ff86cabd4d 100644 --- a/source/blender/compositor/nodes/COM_MapUVNode.cc +++ b/source/blender/compositor/nodes/COM_MapUVNode.cc @@ -17,7 +17,7 @@ void MapUVNode::convert_to_operations(NodeConverter &converter, const bNode *node = this->get_bnode(); MapUVOperation *operation = new MapUVOperation(); - operation->set_alpha((float)node->custom1); + operation->set_alpha(float(node->custom1)); operation->set_canvas_input_index(1); converter.add_operation(operation); diff --git a/source/blender/compositor/nodes/COM_MaskNode.cc b/source/blender/compositor/nodes/COM_MaskNode.cc index f92e307328d..3c6812d606f 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cc +++ b/source/blender/compositor/nodes/COM_MaskNode.cc @@ -41,7 +41,7 @@ void MaskNode::convert_to_operations(NodeConverter &converter, operation->set_mask(mask); operation->set_framenumber(context.get_framenumber()); - operation->set_feather((bool)(editor_node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0); + operation->set_feather(bool(editor_node->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0); if ((editor_node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) && (editor_node->custom2 > 1) && (editor_node->custom3 > FLT_EPSILON)) { diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cc b/source/blender/compositor/nodes/COM_OutputFileNode.cc index c83bcf42efd..50989f73986 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cc +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cc @@ -65,7 +65,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter, if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) { const bool use_half_float = (storage->format.depth == R_IMF_CHAN_DEPTH_16); - /* single output operation for the multilayer file */ + /* Single output operation for the multi-layer file. */ OutputOpenExrMultiLayerOperation *output_operation; if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) { @@ -104,7 +104,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter, char path[FILE_MAX]; /* combine file path for the input */ - BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path); + BLI_path_join(path, FILE_MAX, storage->base_path, sockdata->path); NodeOperation *output_operation = nullptr; diff --git a/source/blender/compositor/nodes/COM_SceneTimeNode.cc b/source/blender/compositor/nodes/COM_SceneTimeNode.cc index edd6efdb67b..dd5784f03ee 100644 --- a/source/blender/compositor/nodes/COM_SceneTimeNode.cc +++ b/source/blender/compositor/nodes/COM_SceneTimeNode.cc @@ -20,7 +20,7 @@ void SceneTimeNode::convert_to_operations(NodeConverter &converter, const int frameNumber = context.get_framenumber(); const Scene *scene = context.get_scene(); - const double frameRate = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base); + const double frameRate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base)); SecondOperation->set_value(float(frameNumber / frameRate)); converter.add_operation(SecondOperation); diff --git a/source/blender/compositor/nodes/COM_SeparateColorNode.cc b/source/blender/compositor/nodes/COM_SeparateColorNode.cc index 28ebbb35e9a..6732396004f 100644 --- a/source/blender/compositor/nodes/COM_SeparateColorNode.cc +++ b/source/blender/compositor/nodes/COM_SeparateColorNode.cc @@ -12,7 +12,7 @@ SeparateColorNode::SeparateColorNode(bNode *editor_node) : Node(editor_node) } void SeparateColorNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &UNUSED(context)) const + const CompositorContext & /*context*/) const { NodeInput *image_socket = this->get_input_socket(0); NodeOutput *output_rsocket = this->get_output_socket(0); diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc index 4e7704dcdc8..7aa8de04c34 100644 --- a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc +++ b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc @@ -13,7 +13,7 @@ SeparateXYZNode::SeparateXYZNode(bNode *editor_node) : Node(editor_node) } void SeparateXYZNode::convert_to_operations(NodeConverter &converter, - const CompositorContext &UNUSED(context)) const + const CompositorContext & /*context*/) const { NodeInput *vector_socket = this->get_input_socket(0); NodeOutput *output_x_socket = this->get_output_socket(0); diff --git a/source/blender/compositor/nodes/COM_TimeNode.cc b/source/blender/compositor/nodes/COM_TimeNode.cc index 4f4f6f7bf8a..4004a5f718f 100644 --- a/source/blender/compositor/nodes/COM_TimeNode.cc +++ b/source/blender/compositor/nodes/COM_TimeNode.cc @@ -31,7 +31,7 @@ void TimeNode::convert_to_operations(NodeConverter &converter, fac = 1.0f; } else if (node->custom1 < node->custom2) { - fac = (context.get_framenumber() - node->custom1) / (float)(node->custom2 - node->custom1); + fac = (context.get_framenumber() - node->custom1) / float(node->custom2 - node->custom1); } BKE_curvemapping_init((CurveMapping *)node->storage); diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cc b/source/blender/compositor/operations/COM_AntiAliasOperation.cc index 0c297c20eef..e0083b702e1 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cc +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cc @@ -34,7 +34,7 @@ static int extrapolate9(float *E0, do { \ *DST = *SRC; \ } while (0) - if ((!PEQ(B, H)) && (!PEQ(D, F))) { + if (!PEQ(B, H) && !PEQ(D, F)) { if (PEQ(D, B)) { PCPY(E0, D); } @@ -144,12 +144,12 @@ void AntiAliasOperation::execute_pixel(float output[4], int x, int y, void *data /* Some rounding magic to so make weighting correct with the * original coefficients. */ - unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] + - 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] + - 3 * ninepix[8]) * - 255.0f + - 19.0f) / - 38.0f; + uchar result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] + + 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] + + 3 * ninepix[8]) * + 255.0f + + 19.0f) / + 38.0f; output[0] = result / 255.0f; } else { @@ -234,12 +234,12 @@ void AntiAliasOperation::update_memory_buffer_partial(MemoryBuffer *output, &row_next[x_offset + input->elem_stride])) { /* Some rounding magic to make weighting correct with the * original coefficients. */ - unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + - 5 * ninepix[3] + 6 * ninepix[4] + 5 * ninepix[5] + - 3 * ninepix[6] + 5 * ninepix[7] + 3 * ninepix[8]) * - 255.0f + - 19.0f) / - 38.0f; + uchar result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + 5 * ninepix[3] + + 6 * ninepix[4] + 5 * ninepix[5] + 3 * ninepix[6] + 5 * ninepix[7] + + 3 * ninepix[8]) * + 255.0f + + 19.0f) / + 38.0f; out[0] = result / 255.0f; } else { diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc index 3711851e8f5..c808ec02690 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cc +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cc @@ -95,7 +95,7 @@ bool BilateralBlurOperation::determine_depending_area_of_interest( return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void BilateralBlurOperation::get_area_of_interest(const int UNUSED(input_idx), +void BilateralBlurOperation::get_area_of_interest(const int /*input_idx*/, const rcti &output_area, rcti &r_input_area) { diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cc b/source/blender/compositor/operations/COM_BlurBaseOperation.cc index b278997eced..53a5cebaf5d 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cc +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cc @@ -71,7 +71,7 @@ float *BlurBaseOperation::make_gausstab(float rad, int size) sum = 0.0f; float fac = (rad > 0.0f ? 1.0f / rad : 0.0f); for (i = -size; i <= size; i++) { - val = RE_filter_value(data_.filtertype, (float)i * fac); + val = RE_filter_value(data_.filtertype, float(i) * fac); sum += val; gausstab[i + size] = val; } @@ -107,7 +107,7 @@ float *BlurBaseOperation::make_dist_fac_inverse(float rad, int size, int falloff float fac = (rad > 0.0f ? 1.0f / rad : 0.0f); for (i = -size; i <= size; i++) { - val = 1.0f - fabsf((float)i * fac); + val = 1.0f - fabsf(float(i) * fac); /* keep in sync with rna_enum_proportional_falloff_curve_only_items */ switch (falloff) { diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cc b/source/blender/compositor/operations/COM_BokehImageOperation.cc index 42caa7aa3c0..b74ac9dac64 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cc +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cc @@ -16,13 +16,13 @@ void BokehImageOperation::init_execution() center_[1] = get_height() / 2; inverse_rounding_ = 1.0f - data_->rounding; circular_distance_ = get_width() / 2; - flap_rad_ = (float)(M_PI * 2) / data_->flaps; + flap_rad_ = float(M_PI * 2) / data_->flaps; flap_rad_add_ = data_->angle; while (flap_rad_add_ < 0.0f) { - flap_rad_add_ += (float)(M_PI * 2.0); + flap_rad_add_ += float(M_PI * 2.0); } - while (flap_rad_add_ > (float)M_PI) { - flap_rad_add_ -= (float)(M_PI * 2.0); + while (flap_rad_add_ > float(M_PI)) { + flap_rad_add_ -= float(M_PI * 2.0); } } void BokehImageOperation::detemine_start_point_of_flap(float r[2], int flap_number, float distance) @@ -43,8 +43,8 @@ float BokehImageOperation::is_inside_bokeh(float distance, float x, float y) point[1] = y; const float distance_to_center = len_v2v2(point, center_); - const float bearing = (atan2f(deltaX, deltaY) + (float)(M_PI * 2.0)); - int flap_number = (int)((bearing - flap_rad_add_) / flap_rad_); + const float bearing = (atan2f(deltaX, deltaY) + float(M_PI * 2.0)); + int flap_number = int((bearing - flap_rad_add_) / flap_rad_); detemine_start_point_of_flap(line_p1, flap_number, distance); detemine_start_point_of_flap(line_p2, flap_number + 1, distance); @@ -96,7 +96,7 @@ void BokehImageOperation::execute_pixel_sampled(float output[4], void BokehImageOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { const float shift = data_->lensshift; const float shift2 = shift / 2.0f; diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc index 5b3e00afe31..85ac9434647 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc @@ -19,10 +19,10 @@ void BoxMaskOperation::init_execution() { input_mask_ = this->get_input_socket_reader(0); input_value_ = this->get_input_socket_reader(1); - const double rad = (double)data_->rotation; + const double rad = double(data_->rotation); cosine_ = cos(rad); sine_ = sin(rad); - aspect_ratio_ = ((float)this->get_width()) / this->get_height(); + aspect_ratio_ = float(this->get_width()) / this->get_height(); } void BoxMaskOperation::execute_pixel_sampled(float output[4], diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cc b/source/blender/compositor/operations/COM_BrightnessOperation.cc index 764d5d64046..07d8035e615 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.cc +++ b/source/blender/compositor/operations/COM_BrightnessOperation.cc @@ -47,7 +47,7 @@ void BrightnessOperation::execute_pixel_sampled(float output[4], /* * The algorithm is by Werner D. Streidt * (http://visca.com/ffactory/archives/5-99/msg00021.html) - * Extracted of OpenCV demhist.c + * Extracted of OpenCV `demhist.c`. */ if (contrast > 0) { a = 1.0f - delta * 2.0f; @@ -84,7 +84,7 @@ void BrightnessOperation::update_memory_buffer_partial(MemoryBuffer *output, /* * The algorithm is by Werner D. Streidt * (http://visca.com/ffactory/archives/5-99/msg00021.html) - * Extracted of OpenCV demhist.c + * Extracted of OpenCV `demhist.c`. */ float a, b; if (contrast > 0) { diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc index 4e5832a7d34..9dbeabafa5a 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cc +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cc @@ -144,15 +144,15 @@ void CalculateMeanOperation::set_setting(int setting) } void CalculateMeanOperation::get_area_of_interest(int input_idx, - const rcti &UNUSED(output_area), + const rcti & /*output_area*/, rcti &r_input_area) { BLI_assert(input_idx == 0); r_input_area = get_input_operation(input_idx)->get_canvas(); } -void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), +void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (!iscalculated_) { @@ -164,7 +164,7 @@ void CalculateMeanOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(o void CalculateMeanOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { output->fill(area, &result_); } diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc index 881b894d66d..709218297b7 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cc @@ -74,15 +74,16 @@ void *CalculateStandardDeviationOperation::initialize_tile_data(rcti *rect) } } } - standard_deviation_ = sqrt(sum / (float)(pixels - 1)); + standard_deviation_ = sqrt(sum / float(pixels - 1)); iscalculated_ = true; } unlock_mutex(); return nullptr; } -void CalculateStandardDeviationOperation::update_memory_buffer_started( - MemoryBuffer *UNUSED(output), const rcti &UNUSED(area), Span<MemoryBuffer *> inputs) +void CalculateStandardDeviationOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, + Span<MemoryBuffer *> inputs) { if (!iscalculated_) { const MemoryBuffer *input = inputs[0]; @@ -98,13 +99,13 @@ void CalculateStandardDeviationOperation::update_memory_buffer_started( join.num_pixels += chunk.num_pixels; }); standard_deviation_ = total.num_pixels <= 1 ? 0.0f : - sqrt(total.sum / (float)(total.num_pixels - 1)); + sqrt(total.sum / float(total.num_pixels - 1)); iscalculated_ = true; } } void CalculateStandardDeviationOperation::update_memory_buffer_partial( - MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> UNUSED(inputs)) + MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> /*inputs*/) { output->fill(area, &standard_deviation_); } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cc b/source/blender/compositor/operations/COM_CompositorOperation.cc index c0cc3fa1ba4..1ff27607d09 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cc +++ b/source/blender/compositor/operations/COM_CompositorOperation.cc @@ -113,7 +113,7 @@ void CompositorOperation::deinit_execution() depth_input_ = nullptr; } -void CompositorOperation::execute_region(rcti *rect, unsigned int /*tile_number*/) +void CompositorOperation::execute_region(rcti *rect, uint /*tile_number*/) { float color[8]; /* 7 is enough. */ float *buffer = output_buffer_; @@ -197,7 +197,7 @@ void CompositorOperation::execute_region(rcti *rect, unsigned int /*tile_number* } } -void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output), +void CompositorOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, const rcti &area, Span<MemoryBuffer *> inputs) { @@ -213,7 +213,7 @@ void CompositorOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(outp depth_buf.copy_from(inputs[2], area); } -void CompositorOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area) +void CompositorOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) { int width, height; BKE_render_resolution(rd_, false, &width, &height); diff --git a/source/blender/compositor/operations/COM_ConstantOperation.cc b/source/blender/compositor/operations/COM_ConstantOperation.cc index 0977da5e37c..21c10f2b52a 100644 --- a/source/blender/compositor/operations/COM_ConstantOperation.cc +++ b/source/blender/compositor/operations/COM_ConstantOperation.cc @@ -19,7 +19,7 @@ bool ConstantOperation::can_get_constant_elem() const void ConstantOperation::update_memory_buffer(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { BLI_assert(output->is_a_single_elem()); const float *constant = get_constant_elem(); diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc index 89c1c7cb153..25d4b2d6a6c 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc @@ -46,8 +46,8 @@ void ConvertDepthToRadiusOperation::init_execution() } inverse_focal_distance_ = 1.0f / focal_distance; aspect_ = (this->get_width() > this->get_height()) ? - (this->get_height() / (float)this->get_width()) : - (this->get_width() / (float)this->get_height()); + (this->get_height() / float(this->get_width())) : + (this->get_width() / float(this->get_height())); aperture_ = 0.5f * (cam_lens_ / (aspect_ * cam_sensor)) / f_stop_; const float minsz = MIN2(get_width(), get_height()); dof_sp_ = minsz / ((cam_sensor / 2.0f) / diff --git a/source/blender/compositor/operations/COM_ConvertOperation.h b/source/blender/compositor/operations/COM_ConvertOperation.h index 16d1e2e6bb5..ffd02ed5a2f 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.h +++ b/source/blender/compositor/operations/COM_ConvertOperation.h @@ -98,7 +98,7 @@ class ConvertVectorToValueOperation : public ConvertBaseOperation { class ConvertRGBToYCCOperation : public ConvertBaseOperation { private: - /** YCbCr mode (Jpeg, ITU601, ITU709) */ + /** YCbCr mode (JPEG, ITU601, ITU709) */ int mode_; public: @@ -116,7 +116,7 @@ class ConvertRGBToYCCOperation : public ConvertBaseOperation { class ConvertYCCToRGBOperation : public ConvertBaseOperation { private: - /** YCbCr mode (Jpeg, ITU601, ITU709) */ + /** YCbCr mode (JPEG, ITU601, ITU709) */ int mode_; public: diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cc b/source/blender/compositor/operations/COM_CryptomatteOperation.cc index 69218576237..71e892cb7f1 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.cc +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cc @@ -42,8 +42,8 @@ void CryptomatteOperation::execute_pixel(float output[4], int x, int y, void *da ::memcpy(&m3hash, &input[0], sizeof(uint32_t)); /* Since the red channel is likely to be out of display range, * setting green and blue gives more meaningful images. */ - output[1] = ((float)(m3hash << 8) / (float)UINT32_MAX); - output[2] = ((float)(m3hash << 16) / (float)UINT32_MAX); + output[1] = (float(m3hash << 8) / float(UINT32_MAX)); + output[2] = (float(m3hash << 16) / float(UINT32_MAX)); } for (float hash : object_index_) { if (input[0] == hash) { @@ -71,8 +71,8 @@ void CryptomatteOperation::update_memory_buffer_partial(MemoryBuffer *output, ::memcpy(&m3hash, &input[0], sizeof(uint32_t)); /* Since the red channel is likely to be out of display range, * setting green and blue gives more meaningful images. */ - it.out[1] = ((float)(m3hash << 8) / (float)UINT32_MAX); - it.out[2] = ((float)(m3hash << 16) / (float)UINT32_MAX); + it.out[1] = (float(m3hash << 8) / float(UINT32_MAX)); + it.out[2] = (float(m3hash << 16) / float(UINT32_MAX)); } for (const float hash : object_index_) { if (input[0] == hash) { diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cc b/source/blender/compositor/operations/COM_DenoiseOperation.cc index 3f32eced0f8..5019c2bb158 100644 --- a/source/blender/compositor/operations/COM_DenoiseOperation.cc +++ b/source/blender/compositor/operations/COM_DenoiseOperation.cc @@ -89,7 +89,7 @@ class DenoiseFilter { } #else - void init_and_lock_denoiser(MemoryBuffer *UNUSED(output)) + void init_and_lock_denoiser(MemoryBuffer * /*output*/) { } @@ -97,11 +97,11 @@ class DenoiseFilter { { } - void set_image(const StringRef UNUSED(name), MemoryBuffer *UNUSED(buffer)) + void set_image(const StringRef /*name*/, MemoryBuffer * /*buffer*/) { } - template<typename T> void set(const StringRef UNUSED(option_name), T UNUSED(value)) + template<typename T> void set(const StringRef /*option_name*/, T /*value*/) { } @@ -132,8 +132,8 @@ bool DenoiseBaseOperation::determine_depending_area_of_interest( return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void DenoiseBaseOperation::get_area_of_interest(const int UNUSED(input_idx), - const rcti &UNUSED(output_area), +void DenoiseBaseOperation::get_area_of_interest(const int /*input_idx*/, + const rcti & /*output_area*/, rcti &r_input_area) { r_input_area = this->get_canvas(); @@ -178,7 +178,7 @@ static bool are_guiding_passes_noise_free(const NodeDenoise *settings) void DenoiseOperation::hash_output_params() { if (settings_) { - hash_params((int)settings_->hdr, are_guiding_passes_noise_free(settings_)); + hash_params(int(settings_->hdr), are_guiding_passes_noise_free(settings_)); } } @@ -251,7 +251,7 @@ void DenoiseOperation::generate_denoise(MemoryBuffer *output, } void DenoiseOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &UNUSED(area), + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (!output_rendered_) { @@ -304,7 +304,7 @@ void DenoisePrefilterOperation::generate_denoise(MemoryBuffer *output, MemoryBuf } void DenoisePrefilterOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &UNUSED(area), + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (!output_rendered_) { diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cc b/source/blender/compositor/operations/COM_DespeckleOperation.cc index cfc437a6324..a0c82ad531c 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.cc +++ b/source/blender/compositor/operations/COM_DespeckleOperation.cc @@ -99,7 +99,7 @@ void DespeckleOperation::execute_pixel(float output[4], int x, int y, void * /*d input_operation_->read(in1, x3, y3, nullptr); COLOR_ADD(TOT_DIV_CNR) - mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2))); + mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2)))); // mul_v4_fl(color_mid, 1.0f / w); if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) && @@ -214,7 +214,7 @@ void DespeckleOperation::update_memory_buffer_partial(MemoryBuffer *output, in1 = image->get_elem(x3, y3); COLOR_ADD(TOT_DIV_CNR) - mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * (float)M_SQRT1_2))); + mul_v4_fl(color_mid, 1.0f / (4.0f + (4.0f * float(M_SQRT1_2)))); // mul_v4_fl(color_mid, 1.0f / w); if ((w != 0.0f) && ((w / WTOT) > (threshold_neighbor_)) && diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cc b/source/blender/compositor/operations/COM_DilateErodeOperation.cc index a93571ebee4..9a2d5e09b33 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cc +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cc @@ -181,8 +181,8 @@ static float get_min_distance(DilateErodeThresholdOperation::PixelData &p) * true. */ const TCompare compare; float min_dist = p.distance; - const float *row = p.elem + ((intptr_t)p.ymin - p.y) * p.row_stride + - ((intptr_t)p.xmin - p.x) * p.elem_stride; + const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride + + (intptr_t(p.xmin) - p.x) * p.elem_stride; for (int yi = p.ymin; yi < p.ymax; yi++) { const float dy = yi - p.y; const float dist_y = dy * dy; @@ -410,8 +410,8 @@ static float get_distance_value(DilateDistanceOperation::PixelData &p, const flo const TCompare compare; const float min_dist = p.min_distance; float value = start_value; - const float *row = p.elem + ((intptr_t)p.ymin - p.y) * p.row_stride + - ((intptr_t)p.xmin - p.x) * p.elem_stride; + const float *row = p.elem + (intptr_t(p.ymin) - p.y) * p.row_stride + + (intptr_t(p.xmin) - p.x) * p.elem_stride; for (int yi = p.ymin; yi < p.ymax; yi++) { const float dy = yi - p.y; const float dist_y = dy * dy; diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc index 37e05de33db..5e292fa12c2 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cc @@ -30,7 +30,7 @@ void DirectionalBlurOperation::init_execution() const float height = get_height(); const float a = angle; - const float itsc = 1.0f / powf(2.0f, (float)iterations); + const float itsc = 1.0f / powf(2.0f, float(iterations)); float D; D = distance * sqrtf(width * width + height * height); @@ -128,7 +128,7 @@ bool DirectionalBlurOperation::determine_depending_area_of_interest( } void DirectionalBlurOperation::get_area_of_interest(const int input_idx, - const rcti &UNUSED(output_area), + const rcti & /*output_area*/, rcti &r_input_area) { BLI_assert(input_idx == 0); diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cc b/source/blender/compositor/operations/COM_DisplaceOperation.cc index 198cca0482e..1aec8e12242 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cc +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cc @@ -113,7 +113,7 @@ void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float num++; } if (num > 0) { - float numinv = 1.0f / (float)num; + float numinv = 1.0f / float(num); r_deriv[0][0] *= numinv; r_deriv[1][0] *= numinv; } @@ -130,7 +130,7 @@ void DisplaceOperation::pixel_transform(const float xy[2], float r_uv[2], float num++; } if (num > 0) { - float numinv = 1.0f / (float)num; + float numinv = 1.0f / float(num); r_deriv[0][1] *= numinv; r_deriv[1][1] *= numinv; } @@ -209,8 +209,8 @@ void DisplaceOperation::get_area_of_interest(const int input_idx, } } -void DisplaceOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), +void DisplaceOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { MemoryBuffer *vector = inputs[1]; @@ -227,7 +227,7 @@ void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output, { const MemoryBuffer *input_color = inputs[0]; for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { - const float xy[2] = {(float)it.x, (float)it.y}; + const float xy[2] = {float(it.x), float(it.y)}; float uv[2]; float deriv[2][2]; diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc index ea156cd19db..e120dd5f41a 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cc @@ -8,18 +8,13 @@ namespace blender::compositor { /* This part has been copied from the double edge mask. */ -static void do_adjacentKeepBorders(unsigned int t, - unsigned int rw, - const unsigned int *limask, - const unsigned int *lomask, - unsigned int *lres, - float *res, - unsigned int *rsize) +static void do_adjacentKeepBorders( + uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize) { int x; - unsigned int isz = 0; /* Inner edge size. */ - unsigned int osz = 0; /* Outer edge size. */ - unsigned int gsz = 0; /* Gradient fill area size. */ + uint isz = 0; /* Inner edge size. */ + uint osz = 0; /* Outer edge size. */ + uint gsz = 0; /* Gradient fill area size. */ /* Test the four corners */ /* Upper left corner. */ x = t - rw + 1; @@ -178,18 +173,13 @@ static void do_adjacentKeepBorders(unsigned int t, rsize[2] = gsz; } -static void do_adjacentBleedBorders(unsigned int t, - unsigned int rw, - const unsigned int *limask, - const unsigned int *lomask, - unsigned int *lres, - float *res, - unsigned int *rsize) +static void do_adjacentBleedBorders( + uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize) { int x; - unsigned int isz = 0; /* Inner edge size. */ - unsigned int osz = 0; /* Outer edge size. */ - unsigned int gsz = 0; /* Gradient fill area size. */ + uint isz = 0; /* Inner edge size. */ + uint osz = 0; /* Outer edge size. */ + uint gsz = 0; /* Gradient fill area size. */ /* Test the four corners */ /* Upper left corner. */ x = t - rw + 1; @@ -403,18 +393,13 @@ static void do_adjacentBleedBorders(unsigned int t, rsize[2] = gsz; } -static void do_allKeepBorders(unsigned int t, - unsigned int rw, - const unsigned int *limask, - const unsigned int *lomask, - unsigned int *lres, - float *res, - unsigned int *rsize) +static void do_allKeepBorders( + uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize) { int x; - unsigned int isz = 0; /* Inner edge size. */ - unsigned int osz = 0; /* Outer edge size. */ - unsigned int gsz = 0; /* Gradient fill area size. */ + uint isz = 0; /* Inner edge size. */ + uint osz = 0; /* Outer edge size. */ + uint gsz = 0; /* Gradient fill area size. */ /* Test the four corners. */ /* Upper left corner. */ x = t - rw + 1; @@ -565,18 +550,13 @@ static void do_allKeepBorders(unsigned int t, rsize[2] = gsz; } -static void do_allBleedBorders(unsigned int t, - unsigned int rw, - const unsigned int *limask, - const unsigned int *lomask, - unsigned int *lres, - float *res, - unsigned int *rsize) +static void do_allBleedBorders( + uint t, uint rw, const uint *limask, const uint *lomask, uint *lres, float *res, uint *rsize) { int x; - unsigned int isz = 0; /* Inner edge size. */ - unsigned int osz = 0; /* Outer edge size. */ - unsigned int gsz = 0; /* Gradient fill area size. */ + uint isz = 0; /* Inner edge size. */ + uint osz = 0; /* Outer edge size. */ + uint gsz = 0; /* Gradient fill area size. */ /* Test the four corners */ /* Upper left corner. */ x = t - rw + 1; @@ -782,16 +762,16 @@ static void do_allBleedBorders(unsigned int t, rsize[2] = gsz; } -static void do_allEdgeDetection(unsigned int t, - unsigned int rw, - const unsigned int *limask, - const unsigned int *lomask, - unsigned int *lres, +static void do_allEdgeDetection(uint t, + uint rw, + const uint *limask, + const uint *lomask, + uint *lres, float *res, - unsigned int *rsize, - unsigned int in_isz, - unsigned int in_osz, - unsigned int in_gsz) + uint *rsize, + uint in_isz, + uint in_osz, + uint in_gsz) { int x; /* Pixel loop counter. */ int a; /* Pixel loop counter. */ @@ -812,7 +792,7 @@ static void do_allEdgeDetection(unsigned int t, if (!limask[a]) { /* If the inner mask is empty. */ if (lomask[a]) { /* If the outer mask is full. */ /* - * Next we test all 4 directions around the current pixel: next/prev/up/down + * Next we test all 4 directions around the current pixel: next/previous/up/down * The test ensures that the outer mask is empty and that the inner mask * is also empty. If both conditions are true for any one of the 4 adjacent pixels * then the current pixel is counted as being a true outer edge pixel. @@ -853,16 +833,16 @@ static void do_allEdgeDetection(unsigned int t, rsize[2] = in_gsz; } -static void do_adjacentEdgeDetection(unsigned int t, - unsigned int rw, - const unsigned int *limask, - const unsigned int *lomask, - unsigned int *lres, +static void do_adjacentEdgeDetection(uint t, + uint rw, + const uint *limask, + const uint *lomask, + uint *lres, float *res, - unsigned int *rsize, - unsigned int in_isz, - unsigned int in_osz, - unsigned int in_gsz) + uint *rsize, + uint in_isz, + uint in_osz, + uint in_gsz) { int x; /* Pixel loop counter. */ int a; /* Pixel loop counter. */ @@ -882,7 +862,7 @@ static void do_adjacentEdgeDetection(unsigned int t, if (!limask[a]) { /* If the inner mask is empty. */ if (lomask[a]) { /* If the outer mask is full. */ /* - * Next we test all 4 directions around the current pixel: next/prev/up/down + * Next we test all 4 directions around the current pixel: next/previous/up/down * The test ensures that the outer mask is empty and that the inner mask * is also empty. If both conditions are true for any one of the 4 adjacent pixels * then the current pixel is counted as being a true outer edge pixel. @@ -925,30 +905,30 @@ static void do_adjacentEdgeDetection(unsigned int t, rsize[2] = in_gsz; } -static void do_createEdgeLocationBuffer(unsigned int t, - unsigned int rw, - const unsigned int *lres, +static void do_createEdgeLocationBuffer(uint t, + uint rw, + const uint *lres, float *res, - unsigned short *gbuf, - unsigned int *inner_edge_offset, - unsigned int *outer_edge_offset, - unsigned int isz, - unsigned int gsz) + ushort *gbuf, + uint *inner_edge_offset, + uint *outer_edge_offset, + uint isz, + uint gsz) { - int x; /* Pixel loop counter. */ - int a; /* Temporary pixel index buffer loop counter. */ - unsigned int ud; /* Unscaled edge distance. */ - unsigned int dmin; /* Minimum edge distance. */ + int x; /* Pixel loop counter. */ + int a; /* Temporary pixel index buffer loop counter. */ + uint ud; /* Unscaled edge distance. */ + uint dmin; /* Minimum edge distance. */ - unsigned int rsl; /* Long used for finding fast `1.0/sqrt`. */ - unsigned int gradient_fill_offset; + uint rsl; /* Long used for finding fast `1.0/sqrt`. */ + uint gradient_fill_offset; /* For looping inner edge pixel indexes, represents current position from offset. */ - unsigned int inner_accum = 0; + uint inner_accum = 0; /* For looping outer edge pixel indexes, represents current position from offset. */ - unsigned int outer_accum = 0; + uint outer_accum = 0; /* For looping gradient pixel indexes, represents current position from offset. */ - unsigned int gradient_accum = 0; + uint gradient_accum = 0; /* Disable clang-format to prevent line-wrapping. */ /* clang-format off */ @@ -958,12 +938,12 @@ static void do_createEdgeLocationBuffer(unsigned int t, * or outer edge. * * Allocation is done by requesting 4 bytes "sizeof(int)" per pixel, even - * though gbuf[] is declared as (unsigned short *) (2 bytes) because we don't + * though gbuf[] is declared as `(ushort *)` (2 bytes) because we don't * store the pixel indexes, we only store x,y location of pixel in buffer. * * This does make the assumption that x and y can fit in 16 unsigned bits * so if Blender starts doing renders greater than 65536 in either direction - * this will need to allocate gbuf[] as unsigned int *and allocate 8 bytes + * this will need to allocate gbuf[] as uint *and allocate 8 bytes * per flagged pixel. * * In general, the buffer on-screen: @@ -1028,20 +1008,20 @@ static void do_createEdgeLocationBuffer(unsigned int t, for (rsl = 0; rsl < rw; rsl++) { a = x + rsl; if (lres[a] == 2) { /* It is a gradient pixel flagged by 2. */ - ud = gradient_accum << 1; /* Double the index to reach correct unsigned short location. */ + ud = gradient_accum << 1; /* Double the index to reach correct ushort location. */ gbuf[ud] = dmin; /* Insert pixel's row into gradient pixel location buffer. */ gbuf[ud + 1] = rsl; /* Insert pixel's column into gradient pixel location buffer. */ gradient_accum++; /* Increment gradient index buffer pointer. */ } else if (lres[a] == 3) { /* It is an outer edge pixel flagged by 3. */ - ud = outer_accum << 1; /* Double the index to reach correct unsigned short location. */ + ud = outer_accum << 1; /* Double the index to reach correct ushort location. */ gbuf[ud] = dmin; /* Insert pixel's row into outer edge pixel location buffer. */ gbuf[ud + 1] = rsl; /* Insert pixel's column into outer edge pixel location buffer. */ outer_accum++; /* Increment outer edge index buffer pointer. */ res[a] = 0.0f; /* Set output pixel intensity now since it won't change later. */ } else if (lres[a] == 4) { /* It is an inner edge pixel flagged by 4. */ - ud = inner_accum << 1; /* Double int index to reach correct unsigned short location. */ + ud = inner_accum << 1; /* Double int index to reach correct ushort location. */ gbuf[ud] = dmin; /* Insert pixel's row into inner edge pixel location buffer. */ gbuf[ud + 1] = rsl; /* Insert pixel's column into inner edge pixel location buffer. */ inner_accum++; /* Increment inner edge index buffer pointer. */ @@ -1051,30 +1031,30 @@ static void do_createEdgeLocationBuffer(unsigned int t, } } -static void do_fillGradientBuffer(unsigned int rw, +static void do_fillGradientBuffer(uint rw, float *res, - const unsigned short *gbuf, - unsigned int isz, - unsigned int osz, - unsigned int gsz, - unsigned int inner_edge_offset, - unsigned int outer_edge_offset) + const ushort *gbuf, + uint isz, + uint osz, + uint gsz, + uint inner_edge_offset, + uint outer_edge_offset) { int x; /* Pixel loop counter. */ int a; /* Temporary pixel index buffer loop counter. */ int fsz; /* Size of the frame. */ - unsigned int rsl; /* Long used for finding fast `1.0/sqrt`. */ + uint rsl; /* Long used for finding fast `1.0/sqrt`. */ float rsf; /* Float used for finding fast `1.0/sqrt`. */ const float rsopf = 1.5f; /* Constant float used for finding fast `1.0/sqrt`. */ - unsigned int gradient_fill_offset; - unsigned int t; - unsigned int ud; /* Unscaled edge distance. */ - unsigned int dmin; /* Minimum edge distance. */ - float odist; /* Current outer edge distance. */ - float idist; /* Current inner edge distance. */ - int dx; /* X-delta (used for distance proportion calculation) */ - int dy; /* Y-delta (used for distance proportion calculation) */ + uint gradient_fill_offset; + uint t; + uint ud; /* Unscaled edge distance. */ + uint dmin; /* Minimum edge distance. */ + float odist; /* Current outer edge distance. */ + float idist; /* Current inner edge distance. */ + int dx; /* X-delta (used for distance proportion calculation) */ + int dy; /* Y-delta (used for distance proportion calculation) */ /* * The general algorithm used to color each gradient pixel is: @@ -1150,10 +1130,10 @@ static void do_fillGradientBuffer(unsigned int rw, dmin = ud; /* Set a new minimum equal to the new lower value. */ } } - odist = (float)(dmin); /* Cast outer min to a float. */ + odist = float(dmin); /* Cast outer min to a float. */ rsf = odist * 0.5f; - rsl = *(unsigned int *)&odist; /* Use some peculiar properties of the way bits are stored. */ - rsl = 0x5f3759df - (rsl >> 1); /* In floats vs. unsigned ints to compute an approximate. */ + rsl = *(uint *)&odist; /* Use some peculiar properties of the way bits are stored. */ + rsl = 0x5f3759df - (rsl >> 1); /* In floats vs. uints to compute an approximate. */ odist = *(float *)&rsl; /* Reciprocal square root. */ odist = odist * (rsopf - (rsf * odist * odist)); /* -- This line can be iterated for more accuracy. -- */ @@ -1171,9 +1151,9 @@ static void do_fillGradientBuffer(unsigned int rw, } /* Cast inner min to a float. */ - idist = (float)(dmin); + idist = float(dmin); rsf = idist * 0.5f; - rsl = *(unsigned int *)&idist; + rsl = *(uint *)&idist; /* See notes above. */ rsl = 0x5f3759df - (rsl >> 1); @@ -1195,24 +1175,22 @@ static void do_fillGradientBuffer(unsigned int rw, void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, float *res) { - unsigned int *lres; /* Pointer to output pixel buffer (for bit operations). */ - unsigned int *limask; /* Pointer to inner mask (for bit operations). */ - unsigned int *lomask; /* Pointer to outer mask (for bit operations). */ + uint *lres; /* Pointer to output pixel buffer (for bit operations). */ + uint *limask; /* Pointer to inner mask (for bit operations). */ + uint *lomask; /* Pointer to outer mask (for bit operations). */ int rw; /* Pixel row width. */ int t; /* Total number of pixels in buffer - 1 (used for loop starts). */ int fsz; /* Size of the frame. */ - unsigned int isz = 0; /* Size (in pixels) of inside edge pixel index buffer. */ - unsigned int osz = 0; /* Size (in pixels) of outside edge pixel index buffer. */ - unsigned int gsz = 0; /* Size (in pixels) of gradient pixel index buffer. */ - unsigned int rsize[3]; /* Size storage to pass to helper functions. */ - unsigned int inner_edge_offset = - 0; /* Offset into final buffer where inner edge pixel indexes start. */ - unsigned int outer_edge_offset = - 0; /* Offset into final buffer where outer edge pixel indexes start. */ + uint isz = 0; /* Size (in pixels) of inside edge pixel index buffer. */ + uint osz = 0; /* Size (in pixels) of outside edge pixel index buffer. */ + uint gsz = 0; /* Size (in pixels) of gradient pixel index buffer. */ + uint rsize[3]; /* Size storage to pass to helper functions. */ + uint inner_edge_offset = 0; /* Offset into final buffer where inner edge pixel indexes start. */ + uint outer_edge_offset = 0; /* Offset into final buffer where outer edge pixel indexes start. */ - unsigned short *gbuf; /* Gradient/inner/outer pixel location index buffer. */ + ushort *gbuf; /* Gradient/inner/outer pixel location index buffer. */ if (true) { /* If both input sockets have some data coming in... */ @@ -1223,9 +1201,9 @@ void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, fl sizeof(float) * (t + 1)); /* Clear output buffer (not all pixels will be written later). */ - lres = (unsigned int *)res; /* Pointer to output buffer (for bit level ops).. */ - limask = (unsigned int *)imask; /* Pointer to input mask (for bit level ops).. */ - lomask = (unsigned int *)omask; /* Pointer to output mask (for bit level ops).. */ + lres = (uint *)res; /* Pointer to output buffer (for bit level ops).. */ + limask = (uint *)imask; /* Pointer to input mask (for bit level ops).. */ + lomask = (uint *)omask; /* Pointer to output mask (for bit level ops).. */ /* * The whole buffer is broken up into 4 parts. The four CORNERS, the FIRST and LAST rows, the @@ -1291,7 +1269,7 @@ void DoubleEdgeMaskOperation::do_double_edge_mask(float *imask, float *omask, fl /* Calculate size of pixel index buffer needed. */ fsz = gsz + isz + osz; /* Allocate edge/gradient pixel index buffer. */ - gbuf = (unsigned short *)MEM_callocN(sizeof(unsigned short) * fsz * 2, "DEM"); + gbuf = (ushort *)MEM_callocN(sizeof(ushort) * fsz * 2, "DEM"); do_createEdgeLocationBuffer( t, rw, lres, res, gbuf, &inner_edge_offset, &outer_edge_offset, isz, gsz); @@ -1376,15 +1354,15 @@ void DoubleEdgeMaskOperation::deinit_execution() } } -void DoubleEdgeMaskOperation::get_area_of_interest(int UNUSED(input_idx), - const rcti &UNUSED(output_area), +void DoubleEdgeMaskOperation::get_area_of_interest(int /*input_idx*/, + const rcti & /*output_area*/, rcti &r_input_area) { r_input_area = this->get_canvas(); } void DoubleEdgeMaskOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &UNUSED(area), + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (!is_output_rendered_) { diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc index 508e5ea5712..064163801ea 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc @@ -19,10 +19,10 @@ void EllipseMaskOperation::init_execution() { input_mask_ = this->get_input_socket_reader(0); input_value_ = this->get_input_socket_reader(1); - const double rad = (double)data_->rotation; + const double rad = double(data_->rotation); cosine_ = cos(rad); sine_ = sin(rad); - aspect_ratio_ = ((float)this->get_width()) / this->get_height(); + aspect_ratio_ = float(this->get_width()) / this->get_height(); } void EllipseMaskOperation::execute_pixel_sampled(float output[4], diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc index 725751d15af..7557d1bc4bd 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc @@ -102,18 +102,15 @@ void *FastGaussianBlurOperation::initialize_tile_data(rcti *rect) return iirgaus_; } -void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, - float sigma, - unsigned int chan, - unsigned int xy) +void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, uint chan, uint xy) { BLI_assert(!src->is_a_single_elem()); double q, q2, sc, cf[4], tsM[9], tsu[3], tsv[3]; double *X, *Y, *W; - const unsigned int src_width = src->get_width(); - const unsigned int src_height = src->get_height(); - unsigned int x, y, src_dim_max; - unsigned int i; + const uint src_width = src->get_width(); + const uint src_height = src->get_height(); + uint x, y, src_dim_max; + uint i; float *buffer = src->get_buffer(); const uint8_t num_channels = src->get_num_channels(); @@ -194,7 +191,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, Y[L - 1] = cf[0] * W[L - 1] + cf[1] * tsv[0] + cf[2] * tsv[1] + cf[3] * tsv[2]; \ Y[L - 2] = cf[0] * W[L - 2] + cf[1] * Y[L - 1] + cf[2] * tsv[0] + cf[3] * tsv[1]; \ Y[L - 3] = cf[0] * W[L - 3] + cf[1] * Y[L - 2] + cf[2] * Y[L - 1] + cf[3] * tsv[0]; \ - /* 'i != UINT_MAX' is really 'i >= 0', but necessary for unsigned int wrapping */ \ + /* `i != UINT_MAX` is really `i >= 0`, but necessary for `uint` wrapping. */ \ for (i = L - 4; i != UINT_MAX; i--) { \ Y[i] = cf[0] * W[i] + cf[1] * Y[i + 1] + cf[2] * Y[i + 2] + cf[3] * Y[i + 3]; \ } \ @@ -387,15 +384,15 @@ void *FastGaussianBlurValueOperation::initialize_tile_data(rcti *rect) return iirgaus_; } -void FastGaussianBlurValueOperation::get_area_of_interest(const int UNUSED(input_idx), - const rcti &UNUSED(output_area), +void FastGaussianBlurValueOperation::get_area_of_interest(const int /*input_idx*/, + const rcti & /*output_area*/, rcti &r_input_area) { r_input_area = this->get_canvas(); } -void FastGaussianBlurValueOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), +void FastGaussianBlurValueOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (iirgaus_ == nullptr) { diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h index 157d3c7f32f..0f7064c19a5 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.h @@ -31,9 +31,9 @@ class FastGaussianBlurOperation : public BlurBaseOperation { void update_memory_buffer_started(MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> inputs) override; - void update_memory_buffer_partial(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), - Span<MemoryBuffer *> UNUSED(inputs)) override + void update_memory_buffer_partial(MemoryBuffer * /*output*/, + const rcti & /*area*/, + Span<MemoryBuffer *> /*inputs*/) override { } }; diff --git a/source/blender/compositor/operations/COM_FlipOperation.cc b/source/blender/compositor/operations/COM_FlipOperation.cc index 369f124622a..3d9d574b89d 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.cc +++ b/source/blender/compositor/operations/COM_FlipOperation.cc @@ -26,8 +26,8 @@ void FlipOperation::deinit_execution() void FlipOperation::execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) { - float nx = flip_x_ ? ((int)this->get_width() - 1) - x : x; - float ny = flip_y_ ? ((int)this->get_height() - 1) - y : y; + float nx = flip_x_ ? (int(this->get_width()) - 1) - x : x; + float ny = flip_y_ ? (int(this->get_height()) - 1) - y : y; input_operation_->read_sampled(output, nx, ny, sampler); } @@ -39,7 +39,7 @@ bool FlipOperation::determine_depending_area_of_interest(rcti *input, rcti new_input; if (flip_x_) { - const int w = (int)this->get_width() - 1; + const int w = int(this->get_width()) - 1; new_input.xmax = (w - input->xmin) + 1; new_input.xmin = (w - input->xmax) - 1; } @@ -48,7 +48,7 @@ bool FlipOperation::determine_depending_area_of_interest(rcti *input, new_input.xmax = input->xmax; } if (flip_y_) { - const int h = (int)this->get_height() - 1; + const int h = int(this->get_height()) - 1; new_input.ymax = (h - input->ymin) + 1; new_input.ymin = (h - input->ymax) - 1; } @@ -85,7 +85,7 @@ void FlipOperation::get_area_of_interest(const int input_idx, BLI_assert(input_idx == 0); UNUSED_VARS_NDEBUG(input_idx); if (flip_x_) { - const int w = (int)this->get_width() - 1; + const int w = int(this->get_width()) - 1; r_input_area.xmax = (w - output_area.xmin) + 1; r_input_area.xmin = (w - output_area.xmax) + 1; } @@ -94,7 +94,7 @@ void FlipOperation::get_area_of_interest(const int input_idx, r_input_area.xmax = output_area.xmax; } if (flip_y_) { - const int h = (int)this->get_height() - 1; + const int h = int(this->get_height()) - 1; r_input_area.ymax = (h - output_area.ymin) + 1; r_input_area.ymin = (h - output_area.ymax) + 1; } @@ -112,8 +112,8 @@ void FlipOperation::update_memory_buffer_partial(MemoryBuffer *output, const int input_offset_x = input_img->get_rect().xmin; const int input_offset_y = input_img->get_rect().ymin; for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { - const int nx = flip_x_ ? ((int)this->get_width() - 1) - it.x : it.x; - const int ny = flip_y_ ? ((int)this->get_height() - 1) - it.y : it.y; + const int nx = flip_x_ ? (int(this->get_width()) - 1) - it.x : it.x; + const int ny = flip_y_ ? (int(this->get_height()) - 1) - it.y : it.y; input_img->read_elem(input_offset_x + nx, input_offset_y + ny, it.out); } } diff --git a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc index f380abf42f0..75b2249b6a7 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc +++ b/source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc @@ -114,7 +114,7 @@ void GaussianAlphaBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer * float distfacinv_max = 1.0f; /* 0 to 1 */ const int step = QualityStepHelper::get_step(); - const float *in = it.in(0) + ((intptr_t)coord_min - coord) * elem_stride; + const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride; const int in_stride = elem_stride * step; int index = (coord_min - coord) + filtersize_; const int index_end = index + (coord_max - coord_min); diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc index 49669d70177..4a589d45275 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc +++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc @@ -73,7 +73,7 @@ void GaussianAlphaXBlurOperation::execute_pixel(float output[4], int x, int y, v /* *** this is the main part which is different to 'GaussianXBlurOperation' *** */ int step = get_step(); - int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth); + int bufferindex = (xmin - bufferstartx) + ((ymin - bufferstarty) * bufferwidth); /* gauss */ float alpha_accum = 0.0f; diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc index 0e73299f58e..e9ff756093c 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc +++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc @@ -86,7 +86,7 @@ void GaussianAlphaYBlurOperation::execute_pixel(float output[4], int x, int y, v float distfacinv_max = 1.0f; /* 0 to 1 */ for (int ny = ymin; ny < ymax; ny += step) { - int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth); + int bufferindex = (xmin - bufferstartx) + ((ny - bufferstarty) * bufferwidth); const int index = (ny - y) + filtersize_; float value = finv_test(buffer[bufferindex], do_invert); diff --git a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc index 3c66f74f284..b2b10e77012 100644 --- a/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc +++ b/source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc @@ -112,7 +112,7 @@ void GaussianBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *outpu float multiplier_accum = 0.0f; const int step = QualityStepHelper::get_step(); - const float *in = it.in(0) + ((intptr_t)coord_min - coord) * elem_stride; + const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride; const int in_stride = elem_stride * step; int gauss_idx = (coord_min - coord) + filtersize_; const int gauss_end = gauss_idx + (coord_max - coord_min); diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc index fa45034b00c..039e6a9bcc0 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc @@ -35,11 +35,11 @@ void GaussianBokehBlurOperation::init_data() } } - radxf_ = size_ * (float)data_.sizex; + radxf_ = size_ * float(data_.sizex); CLAMP(radxf_, 0.0f, width / 2.0f); /* Vertical. */ - radyf_ = size_ * (float)data_.sizey; + radyf_ = size_ * float(data_.sizey); CLAMP(radyf_, 0.0f, height / 2.0f); radx_ = ceil(radxf_); @@ -71,8 +71,8 @@ void GaussianBokehBlurOperation::update_gauss() float facy = (radyf_ > 0.0f ? 1.0f / radyf_ : 0.0f); for (int j = -rady_; j <= rady_; j++) { for (int i = -radx_; i <= radx_; i++, dgauss++) { - float fj = (float)j * facy; - float fi = (float)i * facx; + float fj = float(j) * facy; + float fi = float(i) * facx; float dist = sqrt(fj * fj + fi * fi); *dgauss = RE_filter_value(data_.filtertype, dist); @@ -105,10 +105,10 @@ void GaussianBokehBlurOperation::execute_pixel(float output[4], int x, int y, vo const float width = this->get_width(); const float height = this->get_height(); - radxf_ = size_ * (float)data_.sizex; + radxf_ = size_ * float(data_.sizex); CLAMP(radxf_, 0.0f, width / 2.0f); - radyf_ = size_ * (float)data_.sizey; + radyf_ = size_ * float(data_.sizey); CLAMP(radyf_, 0.0f, height / 2.0f); radx_ = ceil(radxf_); @@ -265,22 +265,22 @@ void GaussianBlurReferenceOperation::init_data() if (data_.relative) { switch (data_.aspect) { case CMP_NODE_BLUR_ASPECT_NONE: - data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_width); - data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_height); + data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width); + data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height); break; case CMP_NODE_BLUR_ASPECT_Y: - data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_width); - data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_width); + data_.sizex = int(data_.percentx * 0.01f * data_.image_in_width); + data_.sizey = int(data_.percenty * 0.01f * data_.image_in_width); break; case CMP_NODE_BLUR_ASPECT_X: - data_.sizex = (int)(data_.percentx * 0.01f * data_.image_in_height); - data_.sizey = (int)(data_.percenty * 0.01f * data_.image_in_height); + data_.sizex = int(data_.percentx * 0.01f * data_.image_in_height); + data_.sizey = int(data_.percenty * 0.01f * data_.image_in_height); break; } } /* Horizontal. */ - filtersizex_ = (float)data_.sizex; + filtersizex_ = float(data_.sizex); int imgx = get_width() / 2; if (filtersizex_ > imgx) { filtersizex_ = imgx; @@ -288,10 +288,10 @@ void GaussianBlurReferenceOperation::init_data() else if (filtersizex_ < 1) { filtersizex_ = 1; } - radx_ = (float)filtersizex_; + radx_ = float(filtersizex_); /* Vertical. */ - filtersizey_ = (float)data_.sizey; + filtersizey_ = float(data_.sizey); int imgy = get_height() / 2; if (filtersizey_ > imgy) { filtersizey_ = imgy; @@ -299,7 +299,7 @@ void GaussianBlurReferenceOperation::init_data() else if (filtersizey_ < 1) { filtersizey_ = 1; } - rady_ = (float)filtersizey_; + rady_ = float(filtersizey_); } void *GaussianBlurReferenceOperation::initialize_tile_data(rcti * /*rect*/) @@ -340,8 +340,8 @@ void GaussianBlurReferenceOperation::execute_pixel(float output[4], int x, int y float temp_size[4]; input_size_->read(temp_size, x, y, data); float ref_size = temp_size[0]; - int refradx = (int)(ref_size * radx_); - int refrady = (int)(ref_size * rady_); + int refradx = int(ref_size * radx_); + int refrady = int(ref_size * rady_); if (refradx > filtersizex_) { refradx = filtersizex_; } @@ -447,8 +447,8 @@ void GaussianBlurReferenceOperation::update_memory_buffer_partial(MemoryBuffer * MemoryBuffer *size_input = inputs[SIZE_INPUT_INDEX]; for (BuffersIterator<float> it = output->iterate_with({size_input}, area); !it.is_end(); ++it) { const float ref_size = *it.in(0); - int ref_radx = (int)(ref_size * radx_); - int ref_rady = (int)(ref_size * rady_); + int ref_radx = int(ref_size * radx_); + int ref_rady = int(ref_size * rady_); if (ref_radx > filtersizex_) { ref_radx = filtersizex_; } diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cc b/source/blender/compositor/operations/COM_GlareBaseOperation.cc index 13f55b5909c..93d3c2063ae 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cc +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cc @@ -56,7 +56,7 @@ bool GlareBaseOperation::determine_depending_area_of_interest(rcti * /*input*/, } void GlareBaseOperation::get_area_of_interest(const int input_idx, - const rcti &UNUSED(output_area), + const rcti & /*output_area*/, rcti &r_input_area) { BLI_assert(input_idx == 0); @@ -68,7 +68,7 @@ void GlareBaseOperation::get_area_of_interest(const int input_idx, } void GlareBaseOperation::update_memory_buffer(MemoryBuffer *output, - const rcti &UNUSED(area), + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (!is_output_rendered_) { diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc index ade3f11a8b3..4f7b1be9057 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc @@ -12,9 +12,9 @@ namespace blender::compositor { using fREAL = float; /* Returns next highest power of 2 of x, as well its log2 in L2. */ -static unsigned int next_pow2(unsigned int x, unsigned int *L2) +static uint next_pow2(uint x, uint *L2) { - unsigned int pw, x_notpow2 = x & (x - 1); + uint pw, x_notpow2 = x & (x - 1); *L2 = 0; while (x >>= 1) { ++(*L2); @@ -31,7 +31,7 @@ static unsigned int next_pow2(unsigned int x, unsigned int *L2) /* From FXT library by Joerg Arndt, faster in order bit-reversal * use: `r = revbin_upd(r, h)` where `h = N>>1`. */ -static unsigned int revbin_upd(unsigned int r, unsigned int h) +static uint revbin_upd(uint r, uint h) { while (!((r ^= h) & h)) { h >>= 1; @@ -39,14 +39,14 @@ static unsigned int revbin_upd(unsigned int r, unsigned int h) return r; } //------------------------------------------------------------------------------ -static void FHT(fREAL *data, unsigned int M, unsigned int inverse) +static void FHT(fREAL *data, uint M, uint inverse) { double tt, fc, dc, fs, ds, a = M_PI; fREAL t1, t2; int n2, bd, bl, istep, k, len = 1 << M, n = 1; int i, j = 0; - unsigned int Nh = len >> 1; + uint Nh = len >> 1; for (i = 1; i < (len - 1); i++) { j = revbin_upd(j, Nh); if (j > i) { @@ -75,8 +75,8 @@ static void FHT(fREAL *data, unsigned int M, unsigned int inverse) fREAL *data_nbd = &data_n[bd]; fREAL *data_bd = &data[bd]; for (k = bl; k < len; k += istep) { - t1 = fc * (double)data_n[k] + fs * (double)data_nbd[k]; - t2 = fs * (double)data_n[k] - fc * (double)data_nbd[k]; + t1 = fc * double(data_n[k]) + fs * double(data_nbd[k]); + t2 = fs * double(data_n[k]) - fc * double(data_nbd[k]); data_n[k] = data[k] - t1; data_nbd[k] = data_bd[k] - t2; data[k] += t1; @@ -112,10 +112,9 @@ static void FHT(fREAL *data, unsigned int M, unsigned int inverse) /* 2D Fast Hartley Transform, Mx/My -> log2 of width/height, * nzp -> the row where zero pad data starts, * inverse -> see above. */ -static void FHT2D( - fREAL *data, unsigned int Mx, unsigned int My, unsigned int nzp, unsigned int inverse) +static void FHT2D(fREAL *data, uint Mx, uint My, uint nzp, uint inverse) { - unsigned int i, j, Nx, Ny, maxy; + uint i, j, Nx, Ny, maxy; Nx = 1 << Mx; Ny = 1 << My; @@ -130,13 +129,13 @@ static void FHT2D( if (Nx == Ny) { /* Square. */ for (j = 0; j < Ny; j++) { for (i = j + 1; i < Nx; i++) { - unsigned int op = i + (j << Mx), np = j + (i << My); + uint op = i + (j << Mx), np = j + (i << My); SWAP(fREAL, data[op], data[np]); } } } else { /* Rectangular. */ - unsigned int k, Nym = Ny - 1, stm = 1 << (Mx + My); + uint k, Nym = Ny - 1, stm = 1 << (Mx + My); for (i = 0; stm > 0; i++) { #define PRED(k) (((k & Nym) << Mx) + (k >> My)) for (j = PRED(i); j > i; j = PRED(j)) { @@ -153,8 +152,8 @@ static void FHT2D( } } - SWAP(unsigned int, Nx, Ny); - SWAP(unsigned int, Mx, My); + SWAP(uint, Nx, Ny); + SWAP(uint, Mx, My); /* Now columns == transposed rows. */ for (j = 0; j < Ny; j++) { @@ -163,11 +162,11 @@ static void FHT2D( /* Finalize. */ for (j = 0; j <= (Ny >> 1); j++) { - unsigned int jm = (Ny - j) & (Ny - 1); - unsigned int ji = j << Mx; - unsigned int jmi = jm << Mx; + uint jm = (Ny - j) & (Ny - 1); + uint ji = j << Mx; + uint jmi = jm << Mx; for (i = 0; i <= (Nx >> 1); i++) { - unsigned int im = (Nx - i) & (Nx - 1); + uint im = (Nx - i) & (Nx - 1); fREAL A = data[ji + i]; fREAL B = data[jmi + i]; fREAL C = data[ji + im]; @@ -184,13 +183,13 @@ static void FHT2D( //------------------------------------------------------------------------------ /* 2D convolution calc, d1 *= d2, M/N - > log2 of width/height. */ -static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned int N) +static void fht_convolve(fREAL *d1, const fREAL *d2, uint M, uint N) { fREAL a, b; - unsigned int i, j, k, L, mj, mL; - unsigned int m = 1 << M, n = 1 << N; - unsigned int m2 = 1 << (M - 1), n2 = 1 << (N - 1); - unsigned int mn2 = m << (N - 1); + uint i, j, k, L, mj, mL; + uint m = 1 << M, n = 1 << N; + uint m2 = 1 << (M - 1), n2 = 1 << (N - 1); + uint mn2 = m << (N - 1); d1[0] *= d2[0]; d1[mn2] *= d2[mn2]; @@ -242,15 +241,15 @@ static void fht_convolve(fREAL *d1, const fREAL *d2, unsigned int M, unsigned in static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) { fREAL *data1, *data2, *fp; - unsigned int w2, h2, hw, hh, log2_w, log2_h; + uint w2, h2, hw, hh, log2_w, log2_h; fRGB wt, *colp; int x, y, ch; int xbl, ybl, nxb, nyb, xbsz, ybsz; bool in2done = false; - const unsigned int kernel_width = in2->get_width(); - const unsigned int kernel_height = in2->get_height(); - const unsigned int image_width = in1->get_width(); - const unsigned int image_height = in1->get_height(); + const uint kernel_width = in2->get_width(); + const uint kernel_height = in2->get_height(); + const uint image_width = in1->get_width(); + const uint image_height = in1->get_height(); float *kernel_buffer = in2->get_buffer(); float *image_buffer = in1->get_buffer(); @@ -361,14 +360,14 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2) /* Data again transposed, so in order again. */ /* Overlap-add result. */ - for (y = 0; y < (int)h2; y++) { + for (y = 0; y < int(h2); y++) { const int yy = ybl * ybsz + y - hh; if ((yy < 0) || (yy >= image_height)) { continue; } fp = &data2[y * w2]; colp = (fRGB *)&rdst->get_buffer()[yy * image_width * COM_DATA_TYPE_COLOR_CHANNELS]; - for (x = 0; x < (int)w2; x++) { + for (x = 0; x < int(w2); x++) { const int xx = xbl * xbsz + x - hw; if ((xx < 0) || (xx >= image_width)) { continue; @@ -397,7 +396,7 @@ void GlareFogGlowOperation::generate_glare(float *data, float scale, u, v, r, w, d; fRGB fcol; MemoryBuffer *ckrn; - unsigned int sz = 1 << settings->size; + uint sz = 1 << settings->size; const float cs_r = 1.0f, cs_g = 1.0f, cs_b = 1.0f; /* Temp. src image @@ -406,12 +405,12 @@ void GlareFogGlowOperation::generate_glare(float *data, BLI_rcti_init(&kernel_rect, 0, sz, 0, sz); ckrn = new MemoryBuffer(DataType::Color, kernel_rect); - scale = 0.25f * sqrtf((float)(sz * sz)); + scale = 0.25f * sqrtf(float(sz * sz)); for (y = 0; y < sz; y++) { - v = 2.0f * (y / (float)sz) - 1.0f; + v = 2.0f * (y / float(sz)) - 1.0f; for (x = 0; x < sz; x++) { - u = 2.0f * (x / (float)sz) - 1.0f; + u = 2.0f * (x / float(sz)) - 1.0f; r = (u * u + v * v) * scale; d = -sqrtf(sqrtf(sqrtf(r))) * 9.0f; fcol[0] = expf(d * cs_r); @@ -420,7 +419,7 @@ void GlareFogGlowOperation::generate_glare(float *data, /* Linear window good enough here, visual result counts, not scientific analysis: * `w = (1.0f-fabs(u))*(1.0f-fabs(v));` * actually, Hanning window is ok, `cos^2` for some reason is slower. */ - w = (0.5f + 0.5f * cosf(u * (float)M_PI)) * (0.5f + 0.5f * cosf(v * (float)M_PI)); + w = (0.5f + 0.5f * cosf(u * float(M_PI))) * (0.5f + 0.5f * cosf(v * float(M_PI))); mul_v3_fl(fcol, w); ckrn->write_pixel(x, y, fcol); } diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cc b/source/blender/compositor/operations/COM_GlareGhostOperation.cc index 13b7af2329e..5ba0901231d 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cc +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cc @@ -23,7 +23,7 @@ void GlareGhostOperation::generate_glare(float *data, const NodeGlare *settings) { const int qt = 1 << settings->quality; - const float s1 = 4.0f / (float)qt, s2 = 2.0f * s1; + const float s1 = 4.0f / float(qt), s2 = 2.0f * s1; int x, y, n, p, np; fRGB c, tc, cm[64]; float sc, isc, u, v, sm, s, t, ofs, scalef[64]; @@ -79,7 +79,7 @@ void GlareGhostOperation::generate_glare(float *data, if (y == 3) { fRGB_rgbmult(cm[x], cmo, 1.0f, cmo); } - scalef[x] = 2.1f * (1.0f - (x + ofs) / (float)(settings->iter * 4)); + scalef[x] = 2.1f * (1.0f - (x + ofs) / float(settings->iter * 4)); if (x & 1) { scalef[x] = -0.99f / scalef[x]; } @@ -88,9 +88,9 @@ void GlareGhostOperation::generate_glare(float *data, sc = 2.13; isc = -0.97; for (y = 0; y < gbuf.get_height() && (!breaked); y++) { - v = ((float)y + 0.5f) / (float)gbuf.get_height(); + v = (float(y) + 0.5f) / float(gbuf.get_height()); for (x = 0; x < gbuf.get_width(); x++) { - u = ((float)x + 0.5f) / (float)gbuf.get_width(); + u = (float(x) + 0.5f) / float(gbuf.get_width()); s = (u - 0.5f) * sc + 0.5f; t = (v - 0.5f) * sc + 0.5f; tbuf1.read_bilinear(c, s * gbuf.get_width(), t * gbuf.get_height()); @@ -114,9 +114,9 @@ void GlareGhostOperation::generate_glare(float *data, tbuf1.get_width() * tbuf1.get_height() * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float)); for (n = 1; n < settings->iter && (!breaked); n++) { for (y = 0; y < gbuf.get_height() && (!breaked); y++) { - v = ((float)y + 0.5f) / (float)gbuf.get_height(); + v = (float(y) + 0.5f) / float(gbuf.get_height()); for (x = 0; x < gbuf.get_width(); x++) { - u = ((float)x + 0.5f) / (float)gbuf.get_width(); + u = (float(x) + 0.5f) / float(gbuf.get_width()); tc[0] = tc[1] = tc[2] = 0.0f; for (p = 0; p < 4; p++) { np = (n << 2) + p; diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc index e4f06eb0e50..c544e13cf34 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cc +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cc @@ -10,9 +10,9 @@ void GlareStreaksOperation::generate_glare(float *data, const NodeGlare *settings) { int x, y, n; - unsigned int nump = 0; + uint nump = 0; float c1[4], c2[4], c3[4], c4[4]; - float a, ang = DEG2RADF(360.0f) / (float)settings->streaks; + float a, ang = DEG2RADF(360.0f) / float(settings->streaks); int size = input_tile->get_width() * input_tile->get_height(); int size4 = size * 4; @@ -26,14 +26,14 @@ void GlareStreaksOperation::generate_glare(float *data, for (a = 0.0f; a < DEG2RADF(360.0f) && (!breaked); a += ang) { const float an = a + settings->angle_ofs; - const float vx = cos((double)an), vy = sin((double)an); + const float vx = cos(double(an)), vy = sin(double(an)); for (n = 0; n < settings->iter && (!breaked); n++) { - const float p4 = pow(4.0, (double)n); + const float p4 = pow(4.0, double(n)); const float vxp = vx * p4, vyp = vy * p4; - const float wt = pow((double)settings->fade, (double)p4); + const float wt = pow(double(settings->fade), double(p4)); /* Color-modulation amount relative to current pass. */ - const float cmo = 1.0f - (float)pow((double)settings->colmod, (double)n + 1); + const float cmo = 1.0f - float(pow(double(settings->colmod), double(n) + 1)); float *tdstcol = tdst.get_buffer(); for (y = 0; y < tsrc.get_height() && (!breaked); y++) { @@ -72,7 +72,7 @@ void GlareStreaksOperation::generate_glare(float *data, } float *sourcebuffer = tsrc.get_buffer(); - float factor = 1.0f / (float)(6 - settings->iter); + float factor = 1.0f / float(6 - settings->iter); for (int i = 0; i < size4; i += 4) { madd_v3_v3fl(&data[i], &sourcebuffer[i], factor); data[i + 3] = 1.0f; diff --git a/source/blender/compositor/operations/COM_ImageOperation.cc b/source/blender/compositor/operations/COM_ImageOperation.cc index a9ab414670f..e1ac5e42be3 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cc +++ b/source/blender/compositor/operations/COM_ImageOperation.cc @@ -90,7 +90,7 @@ void BaseImageOperation::deinit_execution() } } -void BaseImageOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area) +void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) { ImBuf *stackbuf = get_im_buf(); @@ -120,7 +120,7 @@ static void sample_image_at_location( } } else { - unsigned char byte_color[4]; + uchar byte_color[4]; switch (sampler) { case PixelSampler::Nearest: nearest_interpolation_color(ibuf, byte_color, nullptr, x, y); @@ -155,7 +155,7 @@ void ImageOperation::execute_pixel_sampled(float output[4], float x, float y, Pi void ImageOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { output->copy_from(buffer_, area, true); } @@ -179,7 +179,7 @@ void ImageAlphaOperation::execute_pixel_sampled(float output[4], void ImageAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { output->copy_from(buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); } @@ -205,7 +205,7 @@ void ImageDepthOperation::execute_pixel_sampled(float output[4], void ImageDepthOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { if (depth_buffer_) { output->copy_from(depth_buffer_, area); diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cc b/source/blender/compositor/operations/COM_InpaintOperation.cc index 12533c26a53..a2e02e9f045 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.cc +++ b/source/blender/compositor/operations/COM_InpaintOperation.cc @@ -267,7 +267,7 @@ bool InpaintSimpleOperation::determine_depending_area_of_interest( } void InpaintSimpleOperation::get_area_of_interest(const int input_idx, - const rcti &UNUSED(output_area), + const rcti & /*output_area*/, rcti &r_input_area) { BLI_assert(input_idx == 0); diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc index 71699f23a4b..a63789f06c3 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc @@ -48,7 +48,7 @@ void KeyingBlurOperation::execute_pixel(float output[4], int x, int y, void *dat } } - average /= (float)count; + average /= float(count); output[0] = average; } @@ -75,7 +75,7 @@ bool KeyingBlurOperation::determine_depending_area_of_interest(rcti *input, return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void KeyingBlurOperation::get_area_of_interest(const int UNUSED(input_idx), +void KeyingBlurOperation::get_area_of_interest(const int /*input_idx*/, const rcti &output_area, rcti &r_input_area) { diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cc b/source/blender/compositor/operations/COM_KeyingClipOperation.cc index bb951aaa938..2cbdfaa6a01 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cc @@ -47,7 +47,7 @@ void KeyingClipOperation::execute_pixel(float output[4], int x, int y, void *dat end_y = min_ff(y + delta - 1, buffer_height - 1); int count = 0, total_count = (end_x - start_x + 1) * (end_y - start_y + 1) - 1; - int threshold_count = ceil((float)total_count * 0.9f); + int threshold_count = ceil(float(total_count) * 0.9f); if (delta == 0) { ok = true; @@ -147,7 +147,7 @@ void KeyingClipOperation::update_memory_buffer_partial(MemoryBuffer *output, const int y_len = end_y - start_y; const int total_count = x_len * y_len - 1; - const int threshold_count = ceil((float)total_count * 0.9f); + const int threshold_count = ceil(float(total_count) * 0.9f); bool ok = false; if (delta == 0) { ok = true; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc index 0db9b7e6a04..5c5bf5534a7 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc @@ -150,11 +150,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); } else { - unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect; + uchar *rrgb = (uchar *)pattern_ibuf->rect; - site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f); - site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f); - site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f); + site->color[0] += srgb_to_linearrgb(float(rrgb[4 * j + 0]) / 255.0f); + site->color[1] += srgb_to_linearrgb(float(rrgb[4 * j + 1]) / 255.0f); + site->color[2] += srgb_to_linearrgb(float(rrgb[4 * j + 2]) / 255.0f); } } @@ -204,11 +204,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t minmax_v2v2_v2(min, max, b->co); minmax_v2v2_v2(min, max, c->co); - rect->xmin = (int)min[0]; - rect->ymin = (int)min[1]; + rect->xmin = int(min[0]); + rect->ymin = int(min[1]); - rect->xmax = (int)max[0] + 1; - rect->ymax = (int)max[1] + 1; + rect->xmax = int(max[0]) + 1; + rect->ymax = int(max[1]) + 1; } } @@ -311,7 +311,7 @@ void KeyingScreenOperation::execute_pixel(float output[4], int x, int y, void *d TriangulationData *triangulation = cached_triangulation_; TileData *tile_data = (TileData *)data; int i; - float co[2] = {(float)x, (float)y}; + float co[2] = {float(x), float(y)}; for (i = 0; i < tile_data->triangles_total; i++) { int triangle_idx = tile_data->triangles[i]; @@ -356,7 +356,7 @@ void KeyingScreenOperation::update_memory_buffer_partial(MemoryBuffer *output, for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) { copy_v4_v4(it.out, COM_COLOR_BLACK); - const float co[2] = {(float)it.x, (float)it.y}; + const float co[2] = {float(it.x), float(it.y)}; for (int i = 0; i < num_triangles; i++) { const int triangle_idx = triangles[i]; const rcti *rect = &triangulation->triangles_AABB[triangle_idx]; diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cc b/source/blender/compositor/operations/COM_MapUVOperation.cc index 40f91a04134..c300508268e 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cc +++ b/source/blender/compositor/operations/COM_MapUVOperation.cc @@ -124,7 +124,7 @@ void MapUVOperation::pixel_transform(const float xy[2], num++; } if (num > 0) { - float numinv = 1.0f / (float)num; + float numinv = 1.0f / float(num); r_deriv[0][0] *= numinv; r_deriv[1][0] *= numinv; } @@ -141,7 +141,7 @@ void MapUVOperation::pixel_transform(const float xy[2], num++; } if (num > 0) { - float numinv = 1.0f / (float)num; + float numinv = 1.0f / float(num); r_deriv[0][1] *= numinv; r_deriv[1][1] *= numinv; } @@ -201,8 +201,8 @@ void MapUVOperation::get_area_of_interest(const int input_idx, } } -void MapUVOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), +void MapUVOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { const MemoryBuffer *uv_input = inputs[UV_INPUT_INDEX]; @@ -217,7 +217,7 @@ void MapUVOperation::update_memory_buffer_partial(MemoryBuffer *output, { const MemoryBuffer *input_image = inputs[IMAGE_INPUT_INDEX]; for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { - float xy[2] = {(float)it.x, (float)it.y}; + float xy[2] = {float(it.x), float(it.y)}; float uv[2]; float deriv[2][2]; float alpha; diff --git a/source/blender/compositor/operations/COM_MaskOperation.cc b/source/blender/compositor/operations/COM_MaskOperation.cc index 29d0c0c2b9c..53f59f831db 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cc +++ b/source/blender/compositor/operations/COM_MaskOperation.cc @@ -33,7 +33,7 @@ void MaskOperation::init_execution() } else { /* make a throw away copy of the mask */ - const float frame = (float)frame_number_ - frame_shutter_; + const float frame = float(frame_number_) - frame_shutter_; const float frame_step = (frame_shutter_ * 2.0f) / raster_mask_handle_tot_; float frame_iter = frame; @@ -52,7 +52,7 @@ void MaskOperation::init_execution() } } - for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) { + for (uint i = 0; i < raster_mask_handle_tot_; i++) { raster_mask_handles_[i] = BKE_maskrasterize_handle_new(); /* re-eval frame info */ @@ -76,7 +76,7 @@ void MaskOperation::init_execution() void MaskOperation::deinit_execution() { - for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) { + for (uint i = 0; i < raster_mask_handle_tot_; i++) { if (raster_mask_handles_[i]) { BKE_maskrasterize_handle_free(raster_mask_handles_[i]); raster_mask_handles_[i] = nullptr; @@ -118,7 +118,7 @@ void MaskOperation::execute_pixel_sampled(float output[4], /* In case loop below fails. */ output[0] = 0.0f; - for (unsigned int i = 0; i < raster_mask_handle_tot_; i++) { + for (uint i = 0; i < raster_mask_handle_tot_; i++) { if (raster_mask_handles_[i]) { output[0] += BKE_maskrasterize_handle_sample(raster_mask_handles_[i], xy); } @@ -131,7 +131,7 @@ void MaskOperation::execute_pixel_sampled(float output[4], void MaskOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { Vector<MaskRasterHandle *> handles = get_non_null_handles(); if (handles.size() == 0) { diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cc b/source/blender/compositor/operations/COM_MovieClipOperation.cc index b62d972e807..bbc762bf667 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cc +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cc @@ -53,7 +53,7 @@ void MovieClipBaseOperation::deinit_execution() } } -void MovieClipBaseOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area) +void MovieClipBaseOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) { r_area = COM_AREA_NONE; if (movie_clip_) { @@ -94,7 +94,7 @@ void MovieClipBaseOperation::execute_pixel_sampled(float output[4], void MovieClipBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { if (movie_clip_buffer_) { output->copy_from(movie_clip_buffer_, area); @@ -126,7 +126,7 @@ void MovieClipAlphaOperation::execute_pixel_sampled(float output[4], void MovieClipAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { if (movie_clip_buffer_) { output->copy_from(movie_clip_buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc index ea3aad20792..b89a48f2a39 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc @@ -81,10 +81,10 @@ void MovieDistortionOperation::execute_pixel_sampled(float output[4], if (distortion_ != nullptr) { /* float overscan = 0.0f; */ const float pixel_aspect = pixel_aspect_; - const float w = (float)this->get_width() /* / (1 + overscan) */; - const float h = (float)this->get_height() /* / (1 + overscan) */; - const float aspx = w / (float)calibration_width_; - const float aspy = h / (float)calibration_height_; + const float w = float(this->get_width()) /* / (1 + overscan) */; + const float h = float(this->get_height()) /* / (1 + overscan) */; + const float aspx = w / float(calibration_width_); + const float aspy = h / float(calibration_height_); float in[2]; float out[2]; @@ -143,10 +143,10 @@ void MovieDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output /* `float overscan = 0.0f;` */ const float pixel_aspect = pixel_aspect_; - const float w = (float)this->get_width() /* `/ (1 + overscan)` */; - const float h = (float)this->get_height() /* `/ (1 + overscan)` */; - const float aspx = w / (float)calibration_width_; - const float aspy = h / (float)calibration_height_; + const float w = float(this->get_width()) /* `/ (1 + overscan)` */; + const float h = float(this->get_height()) /* `/ (1 + overscan)` */; + const float aspx = w / float(calibration_width_); + const float aspy = h / float(calibration_height_); float xy[2]; float distorted_xy[2]; for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc index 11f80c16c2f..9a825939deb 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cc +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cc @@ -37,7 +37,7 @@ ImBuf *MultilayerBaseOperation::get_im_buf() void MultilayerBaseOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { output->copy_from(buffer_, area); } @@ -93,8 +93,7 @@ void MultilayerColorOperation::execute_pixel_sampled(float output[4], else { int yi = y; int xi = x; - if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() || - (unsigned int)yi >= this->get_height()) { + if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) { zero_v4(output); } else { @@ -116,8 +115,7 @@ void MultilayerValueOperation::execute_pixel_sampled(float output[4], else { int yi = y; int xi = x; - if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() || - (unsigned int)yi >= this->get_height()) { + if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) { output[0] = 0.0f; } else { @@ -138,8 +136,7 @@ void MultilayerVectorOperation::execute_pixel_sampled(float output[4], else { int yi = y; int xi = x; - if (xi < 0 || yi < 0 || (unsigned int)xi >= this->get_width() || - (unsigned int)yi >= this->get_height()) { + if (xi < 0 || yi < 0 || uint(xi) >= this->get_width() || uint(yi) >= this->get_height()) { output[0] = 0.0f; } else { diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cc b/source/blender/compositor/operations/COM_NormalizeOperation.cc index 1131fc28439..b408964c35f 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cc +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cc @@ -114,15 +114,15 @@ void NormalizeOperation::deinitialize_tile_data(rcti * /*rect*/, void * /*data*/ /* pass */ } -void NormalizeOperation::get_area_of_interest(const int UNUSED(input_idx), - const rcti &UNUSED(output_area), +void NormalizeOperation::get_area_of_interest(const int /*input_idx*/, + const rcti & /*output_area*/, rcti &r_input_area) { r_input_area = get_input_operation(0)->get_canvas(); } -void NormalizeOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), +void NormalizeOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (cached_instance_ == nullptr) { diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc index 760ed94f882..7650746e3ed 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc @@ -74,8 +74,8 @@ void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filenam void OutputOpenExrSingleLayerMultiViewOperation::deinit_execution() { - unsigned int width = this->get_width(); - unsigned int height = this->get_height(); + uint width = this->get_width(); + uint height = this->get_height(); if (width != 0 && height != 0) { void *exrhandle; @@ -132,8 +132,8 @@ OutputOpenExrMultiLayerMultiViewOperation::OutputOpenExrMultiLayerMultiViewOpera void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename) { - unsigned int width = this->get_width(); - unsigned int height = this->get_height(); + uint width = this->get_width(); + uint height = this->get_height(); if (width != 0 && height != 0) { @@ -158,7 +158,7 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename IMB_exr_add_view(exrhandle, srv->name); - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { add_exr_channels(exrhandle, layers_[i].name, layers_[i].datatype, @@ -189,8 +189,8 @@ void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution() { - unsigned int width = this->get_width(); - unsigned int height = this->get_height(); + uint width = this->get_width(); + uint height = this->get_height(); if (width != 0 && height != 0) { void *exrhandle; @@ -207,7 +207,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution() exrhandle = this->get_handle(filename); - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { add_exr_channels(exrhandle, layers_[i].name, layers_[i].datatype, @@ -217,7 +217,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution() layers_[i].output_buffer); } - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { /* memory can only be freed after we write all views to the file */ layers_[i].output_buffer = nullptr; layers_[i].image_input = nullptr; @@ -228,7 +228,7 @@ void OutputOpenExrMultiLayerMultiViewOperation::deinit_execution() IMB_exr_write_channels(exrhandle); /* free buffer memory for all the views */ - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { free_exr_channels(exrhandle, rd_, layers_[i].name, layers_[i].datatype); } @@ -284,8 +284,8 @@ void *OutputStereoOperation::get_handle(const char *filename) void OutputStereoOperation::deinit_execution() { - unsigned int width = this->get_width(); - unsigned int height = this->get_height(); + uint width = this->get_width(); + uint height = this->get_height(); if (width != 0 && height != 0) { void *exrhandle; diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h index e36999e5cf1..70773c1a559 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h @@ -31,7 +31,7 @@ class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOpera void deinit_execution() override; }; -/* Writes inputs into OpenEXR multilayer channels. */ +/** Writes inputs into OpenEXR multi-layer channels. */ class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation { private: public: diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cc b/source/blender/compositor/operations/COM_OutputFileOperation.cc index 1d22f3e8cd2..711ea787c41 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cc +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cc @@ -150,7 +150,7 @@ int get_datatype_size(DataType datatype) } } -static float *init_buffer(unsigned int width, unsigned int height, DataType datatype) +static float *init_buffer(uint width, uint height, DataType datatype) { /* When initializing the tree during initial load the width and height can be zero. */ if (width != 0 && height != 0) { @@ -165,7 +165,7 @@ static void write_buffer_rect(rcti *rect, const bNodeTree *tree, SocketReader *reader, float *buffer, - unsigned int width, + uint width, DataType datatype) { float color[4]; @@ -242,7 +242,7 @@ void OutputSingleLayerOperation::init_execution() output_buffer_ = init_buffer(this->get_width(), this->get_height(), datatype_); } -void OutputSingleLayerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/) +void OutputSingleLayerOperation::execute_region(rcti *rect, uint /*tile_number*/) { write_buffer_rect(rect, tree_, image_input_, output_buffer_, this->get_width(), datatype_); } @@ -287,7 +287,7 @@ void OutputSingleLayerOperation::deinit_execution() image_input_ = nullptr; } -void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output), +void OutputSingleLayerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, const rcti &area, Span<MemoryBuffer *> inputs) { @@ -369,7 +369,7 @@ StampData *OutputOpenExrMultiLayerOperation::create_stamp_data() const void OutputOpenExrMultiLayerOperation::init_execution() { - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { if (layers_[i].use_layer) { SocketReader *reader = get_input_socket_reader(i); layers_[i].image_input = reader; @@ -379,9 +379,9 @@ void OutputOpenExrMultiLayerOperation::init_execution() } } -void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/) +void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, uint /*tile_number*/) { - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { OutputOpenExrLayer &layer = layers_[i]; if (layer.image_input) { write_buffer_rect( @@ -392,8 +392,8 @@ void OutputOpenExrMultiLayerOperation::execute_region(rcti *rect, unsigned int / void OutputOpenExrMultiLayerOperation::deinit_execution() { - unsigned int width = this->get_width(); - unsigned int height = this->get_height(); + uint width = this->get_width(); + uint height = this->get_height(); if (width != 0 && height != 0) { char filename[FILE_MAX]; const char *suffix; @@ -410,7 +410,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution() suffix); BLI_make_existing_file(filename); - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { OutputOpenExrLayer &layer = layers_[i]; if (!layer.image_input) { continue; /* skip unconnected sockets */ @@ -437,7 +437,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution() } IMB_exr_close(exrhandle); - for (unsigned int i = 0; i < layers_.size(); i++) { + for (uint i = 0; i < layers_.size(); i++) { if (layers_[i].output_buffer) { MEM_freeN(layers_[i].output_buffer); layers_[i].output_buffer = nullptr; @@ -449,7 +449,7 @@ void OutputOpenExrMultiLayerOperation::deinit_execution() } } -void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output), +void OutputOpenExrMultiLayerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, const rcti &area, Span<MemoryBuffer *> inputs) { diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index df1d68838d9..716bede8035 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -71,7 +71,7 @@ struct OutputOpenExrLayer { SocketReader *image_input; }; -/* Writes inputs into OpenEXR multilayer channels. */ +/* Writes inputs into OpenEXR multi-layer channels. */ class OutputOpenExrMultiLayerOperation : public MultiThreadedOperation { protected: const Scene *scene_; diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc index 006f1f919ba..fcd37f2a179 100644 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc +++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cc @@ -195,8 +195,8 @@ void PlaneCornerPinMaskOperation::determine_canvas(const rcti &preferred_area, r r_area = preferred_area; } -void PlaneCornerPinMaskOperation::get_area_of_interest(const int UNUSED(input_idx), - const rcti &UNUSED(output_area), +void PlaneCornerPinMaskOperation::get_area_of_interest(const int /*input_idx*/, + const rcti & /*output_area*/, rcti &r_input_area) { /* All corner inputs are used as constants. */ diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc index 9c19f55e04f..59e924311e3 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cc @@ -82,7 +82,7 @@ void PlaneDistortWarpImageOperation::calculate_corners(const float corners[4][2] } float frame_corners[4][2] = { - {0.0f, 0.0f}, {(float)width, 0.0f}, {(float)width, (float)height}, {0.0f, (float)height}}; + {0.0f, 0.0f}, {float(width), 0.0f}, {float(width), float(height)}, {0.0f, float(height)}}; BKE_tracking_homography_between_two_quads( sample_data->frame_space_corners, frame_corners, sample_data->perspective_matrix); } @@ -116,7 +116,7 @@ void PlaneDistortWarpImageOperation::execute_pixel_sampled(float output[4], pixel_reader_->read_filtered(color, uv[0], uv[1], deriv[0], deriv[1]); add_v4_v4(output, color); } - mul_v4_fl(output, 1.0f / (float)motion_blur_samples_); + mul_v4_fl(output, 1.0f / float(motion_blur_samples_)); } } @@ -143,7 +143,7 @@ void PlaneDistortWarpImageOperation::update_memory_buffer_partial(MemoryBuffer * 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)motion_blur_samples_); + mul_v4_fl(it.out, 1.0f / float(motion_blur_samples_)); } } } @@ -258,7 +258,7 @@ void PlaneDistortMaskOperation::execute_pixel_sampled(float output[4], inside_counter++; } } - output[0] = (float)inside_counter / osa_; + output[0] = float(inside_counter) / osa_; } else { for (int motion_sample = 0; motion_sample < motion_blur_samples_; motion_sample++) { @@ -278,13 +278,13 @@ void PlaneDistortMaskOperation::execute_pixel_sampled(float output[4], } } } - output[0] = (float)inside_counter / (osa_ * motion_blur_samples_); + output[0] = float(inside_counter) / (osa_ * motion_blur_samples_); } } void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { int inside_count = 0; @@ -292,7 +292,7 @@ void PlaneDistortMaskOperation::update_memory_buffer_partial(MemoryBuffer *outpu MotionSample &sample = samples_[motion_sample]; inside_count += get_jitter_samples_inside_count(it.x, it.y, sample); } - *it.out = (float)inside_count / (osa_ * motion_blur_samples_); + *it.out = float(inside_count) / (osa_ * motion_blur_samples_); } } diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc index 7d515284737..f5922d54fc9 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cc +++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cc @@ -28,7 +28,7 @@ void PlaneTrackCommon::read_and_calculate_corners(PlaneDistortBaseOperation *dis distort_op->calculate_corners(corners, true, 0); } else { - const float frame = (float)framenumber_ - distort_op->motion_blur_shutter_; + const float frame = float(framenumber_) - distort_op->motion_blur_shutter_; const float frame_step = (distort_op->motion_blur_shutter_ * 2.0f) / distort_op->motion_blur_samples_; float frame_iter = frame; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cc b/source/blender/compositor/operations/COM_PreviewOperation.cc index dbc544896e3..2b9fc7ddc8c 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cc +++ b/source/blender/compositor/operations/COM_PreviewOperation.cc @@ -10,8 +10,8 @@ namespace blender::compositor { PreviewOperation::PreviewOperation(const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, - const unsigned int default_width, - const unsigned int default_height) + const uint default_width, + const uint default_height) { this->add_input_socket(DataType::Color, ResizeMode::Align); @@ -39,14 +39,13 @@ void PreviewOperation::init_execution() { input_ = get_input_socket_reader(0); - if (this->get_width() == (unsigned int)preview_->xsize && - this->get_height() == (unsigned int)preview_->ysize) { + if (this->get_width() == uint(preview_->xsize) && this->get_height() == uint(preview_->ysize)) { output_buffer_ = preview_->rect; } if (output_buffer_ == nullptr) { - output_buffer_ = (unsigned char *)MEM_callocN( - sizeof(unsigned char) * 4 * get_width() * get_height(), "PreviewOperation"); + output_buffer_ = (uchar *)MEM_callocN(sizeof(uchar) * 4 * get_width() * get_height(), + "PreviewOperation"); if (preview_->rect) { MEM_freeN(preview_->rect); } @@ -62,7 +61,7 @@ void PreviewOperation::deinit_execution() input_ = nullptr; } -void PreviewOperation::execute_region(rcti *rect, unsigned int /*tile_number*/) +void PreviewOperation::execute_region(rcti *rect, uint /*tile_number*/) { int offset; float color[4]; @@ -102,7 +101,7 @@ bool PreviewOperation::determine_depending_area_of_interest(rcti *input, return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void PreviewOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area) +void PreviewOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) { /* Use default preview resolution as preferred ensuring it has size so that * generated inputs (which don't have resolution on their own) are displayed */ @@ -125,10 +124,10 @@ void PreviewOperation::determine_canvas(const rcti &UNUSED(preferred_area), rcti divider_ = 0.0f; if (width > 0 && height > 0) { if (width > height) { - divider_ = (float)COM_PREVIEW_SIZE / (width); + divider_ = float(COM_PREVIEW_SIZE) / (width); } else { - divider_ = (float)COM_PREVIEW_SIZE / (height); + divider_ = float(COM_PREVIEW_SIZE) / (height); } } width = width * divider_; @@ -155,7 +154,7 @@ void PreviewOperation::get_area_of_interest(const int input_idx, r_input_area.ymax = output_area.ymax / divider_; } -void PreviewOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output), +void PreviewOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, const rcti &area, Span<MemoryBuffer *> inputs) { diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cc b/source/blender/compositor/operations/COM_ReadBufferOperation.cc index 81f046af1b9..224d2ea0f41 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cc +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cc @@ -31,8 +31,7 @@ void ReadBufferOperation::determine_canvas(const rcti &preferred_area, rcti &r_a /** \todo may not occur! But does with blur node. */ if (memory_proxy_->get_executor()) { - uint resolution[2] = {static_cast<uint>(BLI_rcti_size_x(&r_area)), - static_cast<uint>(BLI_rcti_size_y(&r_area))}; + uint resolution[2] = {uint(BLI_rcti_size_x(&r_area)), uint(BLI_rcti_size_y(&r_area))}; memory_proxy_->get_executor()->set_resolution(resolution); } diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cc b/source/blender/compositor/operations/COM_RenderLayersProg.cc index 40f2187b27b..d95ee2a5e1a 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cc +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cc @@ -52,7 +52,7 @@ void RenderLayersProg::init_execution() void RenderLayersProg::do_interpolation(float output[4], float x, float y, PixelSampler sampler) { - unsigned int offset; + uint offset; int width = this->get_width(), height = this->get_height(); int ix = x, iy = y; @@ -169,7 +169,7 @@ void RenderLayersProg::deinit_execution() } } -void RenderLayersProg::determine_canvas(const rcti &UNUSED(preferred_area), rcti &r_area) +void RenderLayersProg::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area) { Scene *sce = this->get_scene(); Render *re = (sce) ? RE_GetSceneRender(sce) : nullptr; @@ -235,7 +235,7 @@ std::unique_ptr<MetaData> RenderLayersProg::get_meta_data() void RenderLayersProg::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { BLI_assert(output->get_num_channels() >= elementsize_); if (layer_buffer_) { @@ -266,7 +266,7 @@ void RenderLayersAOOperation::execute_pixel_sampled(float output[4], void RenderLayersAOOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { BLI_assert(output->get_num_channels() == COM_DATA_TYPE_COLOR_CHANNELS); BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS); @@ -300,7 +300,7 @@ void RenderLayersAlphaProg::execute_pixel_sampled(float output[4], void RenderLayersAlphaProg::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS); BLI_assert(elementsize_ == COM_DATA_TYPE_COLOR_CHANNELS); @@ -323,19 +323,19 @@ void RenderLayersDepthProg::execute_pixel_sampled(float output[4], int iy = y; float *input_buffer = this->get_input_buffer(); - if (input_buffer == nullptr || ix < 0 || iy < 0 || ix >= (int)this->get_width() || - iy >= (int)this->get_height()) { + if (input_buffer == nullptr || ix < 0 || iy < 0 || ix >= int(this->get_width()) || + iy >= int(this->get_height())) { output[0] = 10e10f; } else { - unsigned int offset = (iy * this->get_width() + ix); + uint offset = (iy * this->get_width() + ix); output[0] = input_buffer[offset]; } } void RenderLayersDepthProg::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, - Span<MemoryBuffer *> UNUSED(inputs)) + Span<MemoryBuffer *> /*inputs*/) { BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS); BLI_assert(elementsize_ == COM_DATA_TYPE_VALUE_CHANNELS); diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc index 79f8cf5fc51..b0854cace52 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cc +++ b/source/blender/compositor/operations/COM_RotateOperation.cc @@ -143,7 +143,7 @@ inline void RotateOperation::ensure_degree() double rad; if (do_degree2_rad_conversion_) { - rad = DEG2RAD((double)degree[0]); + rad = DEG2RAD(double(degree[0])); } else { rad = degree[0]; diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc index 261426b31e2..8f4ed844b9f 100644 --- a/source/blender/compositor/operations/COM_SMAAOperation.cc +++ b/source/blender/compositor/operations/COM_SMAAOperation.cc @@ -65,7 +65,7 @@ static void sample_bilinear_vertical(T *reader, int x, int y, float yoffset, flo { float iy = floorf(yoffset); float fy = yoffset - iy; - y += (int)iy; + y += int(iy); float color00[4], color01[4]; @@ -83,7 +83,7 @@ static void sample_bilinear_horizontal(T *reader, int x, int y, float xoffset, f { float ix = floorf(xoffset); float fx = xoffset - ix; - x += (int)ix; + x += int(ix); float color00[4], color10[4]; @@ -113,12 +113,12 @@ static inline const float *areatex_sample_internal(const float *areatex, int x, static void area(int d1, int d2, int e1, int e2, float weights[2]) { /* The areas texture is compressed quadratically: */ - float x = (float)(SMAA_AREATEX_MAX_DISTANCE * e1) + sqrtf((float)d1); - float y = (float)(SMAA_AREATEX_MAX_DISTANCE * e2) + sqrtf((float)d2); + float x = float(SMAA_AREATEX_MAX_DISTANCE * e1) + sqrtf(float(d1)); + float y = float(SMAA_AREATEX_MAX_DISTANCE * e2) + sqrtf(float(d2)); float ix = floorf(x), iy = floorf(y); float fx = x - ix, fy = y - iy; - int X = (int)ix, Y = (int)iy; + int X = int(ix), Y = int(iy); const float *weights00 = areatex_sample_internal(areatex, X + 0, Y + 0); const float *weights10 = areatex_sample_internal(areatex, X + 1, Y + 0); @@ -196,7 +196,7 @@ bool SMAAEdgeDetectionOperation::determine_depending_area_of_interest( return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void SMAAEdgeDetectionOperation::get_area_of_interest(const int UNUSED(input_idx), +void SMAAEdgeDetectionOperation::get_area_of_interest(const int /*input_idx*/, const rcti &output_area, rcti &r_input_area) { @@ -404,7 +404,7 @@ void SMAABlendingWeightCalculationOperation::init_execution() void SMAABlendingWeightCalculationOperation::set_corner_rounding(float rounding) { /* UI values are between 0 and 1 for simplicity but algorithm expects values between 0 and 100 */ - corner_rounding_ = static_cast<int>(scalenorm(0, 100, rounding)); + corner_rounding_ = int(scalenorm(0, 100, rounding)); } void SMAABlendingWeightCalculationOperation::execute_pixel(float output[4], @@ -505,14 +505,14 @@ void SMAABlendingWeightCalculationOperation::execute_pixel(float output[4], } void SMAABlendingWeightCalculationOperation::update_memory_buffer_started( - MemoryBuffer *UNUSED(output), const rcti &UNUSED(out_area), Span<MemoryBuffer *> inputs) + MemoryBuffer * /*output*/, const rcti & /*out_area*/, Span<MemoryBuffer *> inputs) { const MemoryBuffer *image = inputs[0]; sample_image_fn_ = [=](int x, int y, float *out) { image->read_elem_checked(x, y, out); }; } void SMAABlendingWeightCalculationOperation::update_memory_buffer_partial( - MemoryBuffer *output, const rcti &out_area, Span<MemoryBuffer *> UNUSED(inputs)) + MemoryBuffer *output, const rcti &out_area, Span<MemoryBuffer *> /*inputs*/) { for (BuffersIterator<float> it = output->iterate_with({}, out_area); !it.is_end(); ++it) { const int x = it.x; @@ -631,7 +631,7 @@ bool SMAABlendingWeightCalculationOperation::determine_depending_area_of_interes return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void SMAABlendingWeightCalculationOperation::get_area_of_interest(const int UNUSED(input_idx), +void SMAABlendingWeightCalculationOperation::get_area_of_interest(const int /*input_idx*/, const rcti &output_area, rcti &r_input_area) { @@ -1123,7 +1123,7 @@ bool SMAANeighborhoodBlendingOperation::determine_depending_area_of_interest( return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output); } -void SMAANeighborhoodBlendingOperation::get_area_of_interest(const int UNUSED(input_idx), +void SMAANeighborhoodBlendingOperation::get_area_of_interest(const int /*input_idx*/, const rcti &output_area, rcti &r_input_area) { diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc index 2a2aff31893..cc914239caf 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cc +++ b/source/blender/compositor/operations/COM_ScaleOperation.cc @@ -16,7 +16,7 @@ namespace blender::compositor { BaseScaleOperation::BaseScaleOperation() { #ifdef USE_FORCE_BILINEAR - sampler_ = (int)PixelSampler::Bilinear; + sampler_ = int(PixelSampler::Bilinear); #else sampler_ = -1; #endif @@ -372,8 +372,8 @@ void ScaleFixedSizeOperation::init_data(const rcti &input_canvas) { const int input_width = BLI_rcti_size_x(&input_canvas); const int input_height = BLI_rcti_size_y(&input_canvas); - rel_x_ = input_width / (float)new_width_; - rel_y_ = input_height / (float)new_height_; + rel_x_ = input_width / float(new_width_); + rel_y_ = input_height / float(new_height_); /* *** all the options below are for a fairly special case - camera framing *** */ if (offset_x_ != 0.0f || offset_y_ != 0.0f) { diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h index 4cd50f3ead3..ba291342e96 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.h +++ b/source/blender/compositor/operations/COM_ScaleOperation.h @@ -112,12 +112,12 @@ class ScaleRelativeOperation : public ScaleOperation { rcti *output) override; void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override; - float get_relative_scale_x_factor(float UNUSED(width)) override + float get_relative_scale_x_factor(float /*width*/) override { return 1.0f; } - float get_relative_scale_y_factor(float UNUSED(height)) override + float get_relative_scale_y_factor(float /*height*/) override { return 1.0f; } diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc index 0fc5589a3df..a62977c3280 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc @@ -40,8 +40,8 @@ void ScreenLensDistortionOperation::set_dispersion(float dispersion) void ScreenLensDistortionOperation::init_data() { - cx_ = 0.5f * (float)get_width(); - cy_ = 0.5f * (float)get_height(); + cx_ = 0.5f * float(get_width()); + cy_ = 0.5f * float(get_height()); switch (execution_model_) { case eExecutionModel::FullFrame: { @@ -72,8 +72,8 @@ void ScreenLensDistortionOperation::init_execution() input_program_ = this->get_input_socket_reader(0); this->init_mutex(); - uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX); - rng_seed ^= (uint)POINTER_AS_INT(input_program_); + uint rng_seed = uint(PIL_check_seconds_timer_i() & UINT_MAX); + rng_seed ^= uint(POINTER_AS_INT(input_program_)); rng_ = BLI_rng_new(rng_seed); } @@ -147,8 +147,8 @@ void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer, float color[4]; float dsf = len_v2v2(delta[a], delta[b]) + 1.0f; - int ds = jitter_ ? (dsf < 4.0f ? 2 : (int)sqrtf(dsf)) : (int)dsf; - float sd = 1.0f / (float)ds; + int ds = jitter_ ? (dsf < 4.0f ? 2 : int(sqrtf(dsf))) : int(dsf); + float sd = 1.0f / float(ds); float k4 = k4_[a]; float dk4 = dk4_[a]; @@ -178,7 +178,7 @@ void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer, void ScreenLensDistortionOperation::execute_pixel(float output[4], int x, int y, void *data) { MemoryBuffer *buffer = (MemoryBuffer *)data; - float xy[2] = {(float)x, (float)y}; + float xy[2] = {float(x), float(y)}; float uv[2]; get_uv(xy, uv); float uv_dot = len_squared_v2(uv); @@ -196,13 +196,13 @@ void ScreenLensDistortionOperation::execute_pixel(float output[4], int x, int y, accumulate(buffer, 1, 2, uv_dot, uv, delta, sum, count); if (count[0]) { - output[0] = 2.0f * sum[0] / (float)count[0]; + output[0] = 2.0f * sum[0] / float(count[0]); } if (count[1]) { - output[1] = 2.0f * sum[1] / (float)count[1]; + output[1] = 2.0f * sum[1] / float(count[1]); } if (count[2]) { - output[2] = 2.0f * sum[2] / (float)count[2]; + output[2] = 2.0f * sum[2] / float(count[2]); } /* set alpha */ @@ -384,7 +384,7 @@ void ScreenLensDistortionOperation::determine_canvas(const rcti &preferred_area, } void ScreenLensDistortionOperation::get_area_of_interest(const int input_idx, - const rcti &UNUSED(output_area), + const rcti & /*output_area*/, rcti &r_input_area) { if (input_idx != 0) { @@ -485,7 +485,7 @@ void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *o { const MemoryBuffer *input_image = inputs[0]; for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) { - float xy[2] = {(float)it.x, (float)it.y}; + float xy[2] = {float(it.x), float(it.y)}; float uv[2]; get_uv(xy, uv); const float uv_dot = len_squared_v2(uv); @@ -505,13 +505,13 @@ void ScreenLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *o accumulate(input_image, 1, 2, uv_dot, uv, delta, sum, count); if (count[0]) { - it.out[0] = 2.0f * sum[0] / (float)count[0]; + it.out[0] = 2.0f * sum[0] / float(count[0]); } if (count[1]) { - it.out[1] = 2.0f * sum[1] / (float)count[1]; + it.out[1] = 2.0f * sum[1] / float(count[1]); } if (count[2]) { - it.out[2] = 2.0f * sum[2] / (float)count[2]; + it.out[2] = 2.0f * sum[2] / float(count[2]); } /* Set alpha. */ diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cc b/source/blender/compositor/operations/COM_SunBeamsOperation.cc index 1628c0fa1f8..94674c8fd6c 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cc +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cc @@ -52,18 +52,18 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v) { - int x0 = (int)source[0]; - int y0 = (int)source[1]; - x -= (float)x0; - y -= (float)y0; + int x0 = int(source[0]); + int y0 = int(source[1]); + x -= float(x0); + y -= float(y0); u = x * fxu + y * fyu; v = x * fxv + y * fyv; } static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y) { - int x0 = (int)source[0]; - int y0 = (int)source[1]; + int x0 = int(source[0]); + int y0 = int(source[1]); x = x0 + u * fxu + v * fxv; y = y0 + u * fyu + v * fyv; } @@ -95,7 +95,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { buffer_to_sector(source, co[0], co[1], pu, pv); /* line angle */ - double tan_phi = pv / (double)pu; + double tan_phi = pv / double(pu); double dr = sqrt(tan_phi * tan_phi + 1.0); double cos_phi = 1.0 / dr; @@ -105,13 +105,13 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { v = umin * tan_phi; dv = tan_phi; - int start = (int)floorf(umax); - int end = (int)ceilf(umin); + int start = int(floorf(umax)); + int end = int(ceilf(umin)); num = end - start; - sector_to_buffer(source, end, (int)ceilf(v), x, y); + sector_to_buffer(source, end, int(ceilf(v)), x, y); - falloff_factor = dist_max > dist_min ? dr / (double)(dist_max - dist_min) : 0.0f; + falloff_factor = dist_max > dist_min ? dr / double(dist_max - dist_min) : 0.0f; float *iter = input->get_buffer() + input->get_coords_offset(x, y); return iter; @@ -139,7 +139,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { zero_v4(output); - if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) { + if (int(co[0] - source[0]) == 0 && int(co[1] - source[1]) == 0) { copy_v4_v4(output, input->get_elem(source[0], source[1])); return; } @@ -154,7 +154,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { float v_local = v - floorf(v); for (int i = 0; i < num; i++) { - float weight = 1.0f - (float)i * falloff_factor; + float weight = 1.0f - float(i) * falloff_factor; weight *= weight; /* range check, use last valid color when running beyond the image border */ @@ -195,7 +195,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator { /* normalize */ if (num > 0) { - mul_v4_fl(output, 1.0f / (float)num); + mul_v4_fl(output, 1.0f / float(num)); } } }; @@ -288,14 +288,14 @@ void *SunBeamsOperation::initialize_tile_data(rcti * /*rect*/) void SunBeamsOperation::execute_pixel(float output[4], int x, int y, void *data) { - const float co[2] = {(float)x, (float)y}; + const float co[2] = {float(x), float(y)}; accumulate_line((MemoryBuffer *)data, output, co, source_px_, 0.0f, ray_length_px_); } static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length) { - float co[2] = {(float)x, (float)y}; + float co[2] = {float(x), float(y)}; float dir[2], dist; /* move (x,y) vector toward the source by ray_length distance */ @@ -304,7 +304,7 @@ static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], mul_v2_fl(dir, min_ff(dist, ray_length)); sub_v2_v2(co, dir); - int ico[2] = {(int)co[0], (int)co[1]}; + int ico[2] = {int(co[0]), int(co[1])}; BLI_rcti_do_minmax_v(rect, ico); } diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cc b/source/blender/compositor/operations/COM_TonemapOperation.cc index 714625e483d..6f560eafc67 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cc +++ b/source/blender/compositor/operations/COM_TonemapOperation.cc @@ -120,11 +120,11 @@ void *TonemapOperation::initialize_tile_data(rcti *rect) } data->lav = Lav * sc; mul_v3_v3fl(data->cav, cav, sc); - maxl = log((double)maxl + 1e-5); - minl = log((double)minl + 1e-5); + maxl = log(double(maxl) + 1e-5); + minl = log(double(minl) + 1e-5); avl = lsum * sc; data->auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.0f; - float al = exp((double)avl); + float al = exp(double(avl)); data->al = (al == 0.0f) ? 0.0f : (data_->key / al); data->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma); cached_instance_ = data; @@ -139,7 +139,7 @@ void TonemapOperation::deinitialize_tile_data(rcti * /*rect*/, void * /*data*/) } void TonemapOperation::get_area_of_interest(const int input_idx, - const rcti &UNUSED(output_area), + const rcti & /*output_area*/, rcti &r_input_area) { BLI_assert(input_idx == 0); @@ -170,8 +170,8 @@ static Luminance calc_area_luminance(const MemoryBuffer *input, const rcti &area return lum; } -void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output), - const rcti &UNUSED(area), +void TonemapOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, + const rcti & /*area*/, Span<MemoryBuffer *> inputs) { if (cached_instance_ == nullptr) { @@ -193,11 +193,11 @@ void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output) AvgLogLum *avg = new AvgLogLum(); avg->lav = lum.sum / lum.num_pixels; mul_v3_v3fl(avg->cav, lum.color_sum, 1.0f / lum.num_pixels); - const float max_log = log((double)lum.max + 1e-5); - const float min_log = log((double)lum.min + 1e-5); + const float max_log = log(double(lum.max) + 1e-5); + const float min_log = log(double(lum.min) + 1e-5); const float avg_log = lum.log_sum / lum.num_pixels; avg->auto_key = (max_log > min_log) ? ((max_log - avg_log) / (max_log - min_log)) : 1.0f; - const float al = exp((double)avg_log); + const float al = exp(double(avg_log)); avg->al = (al == 0.0f) ? 0.0f : (data_->key / al); avg->igm = (data_->gamma == 0.0f) ? 1 : (1.0f / data_->gamma); cached_instance_ = avg; diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h index 8071470b3f4..4e68d432985 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.h +++ b/source/blender/compositor/operations/COM_TonemapOperation.h @@ -21,7 +21,7 @@ typedef struct AvgLogLum { } AvgLogLum; /** - * \brief base class of tonemap, implementing the simple tonemap + * \brief base class of tone-map, implementing the simple tone-map * \ingroup operation */ class TonemapOperation : public MultiThreadedOperation { @@ -32,7 +32,7 @@ class TonemapOperation : public MultiThreadedOperation { SocketReader *image_reader_; /** - * \brief settings of the Tonemap + * \brief settings of the Tone-map */ const NodeTonemap *data_; diff --git a/source/blender/compositor/operations/COM_TransformOperation.cc b/source/blender/compositor/operations/COM_TransformOperation.cc index 36a4899ef53..0db018a3dc0 100644 --- a/source/blender/compositor/operations/COM_TransformOperation.cc +++ b/source/blender/compositor/operations/COM_TransformOperation.cc @@ -38,7 +38,7 @@ void TransformOperation::init_data() translate_factor_y_; const float degree = get_input_operation(DEGREE_INPUT_INDEX)->get_constant_value_default(0.0f); - const double rad = convert_degree_to_rad_ ? DEG2RAD((double)degree) : degree; + const double rad = convert_degree_to_rad_ ? DEG2RAD(double(degree)) : degree; rotate_cosine_ = cos(rad); rotate_sine_ = sin(rad); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc index d4365af4860..bf6ee64c73f 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc @@ -61,7 +61,7 @@ void *VariableSizeBokehBlurOperation::initialize_tile_data(rcti *rect) const float max_dim = MAX2(this->get_width(), this->get_height()); const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; - data->max_blur_scalar = (int)(data->size->get_max_value(rect2) * scalar); + data->max_blur_scalar = int(data->size->get_max_value(rect2) * scalar); CLAMP(data->max_blur_scalar, 1.0f, max_blur_); return data; } @@ -106,8 +106,8 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y #else int minx = MAX2(x - max_blur_scalar, 0); int miny = MAX2(y - max_blur_scalar, 0); - int maxx = MIN2(x + max_blur_scalar, (int)get_width()); - int maxy = MIN2(y + max_blur_scalar, (int)get_height()); + int maxx = MIN2(x + max_blur_scalar, int(get_width())); + int maxy = MIN2(y + max_blur_scalar, int(get_height())); #endif { input_size_buffer->read_no_check(temp_size, x, y); @@ -134,10 +134,10 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y float dx = nx - x; if (size > fabsf(dx) && size > fabsf(dy)) { float uv[2] = { - (float)(COM_BLUR_BOKEH_PIXELS / 2) + - (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1), - (float)(COM_BLUR_BOKEH_PIXELS / 2) + - (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1), + float(COM_BLUR_BOKEH_PIXELS / 2) + + (dx / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1), + float(COM_BLUR_BOKEH_PIXELS / 2) + + (dy / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1), }; input_bokeh_buffer->read(bokeh, uv[0], uv[1]); madd_v4_v4v4(color_accum, bokeh, &input_program_float_buffer[offset_color_nx_ny]); @@ -185,7 +185,7 @@ void VariableSizeBokehBlurOperation::execute_opencl( const float max_dim = MAX2(get_width(), get_height()); cl_float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; - max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, (float)max_blur_); + max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, float(max_blur_)); device->COM_cl_attach_memory_buffer_to_kernel_parameter( defocus_kernel, 0, -1, cl_mem_to_clean_up, input_memory_buffers, input_program_); @@ -358,10 +358,10 @@ static void blur_pixel(int x, int y, PixelData &p) /* XXX: There is no way to ensure bokeh input is an actual bokeh with #COM_BLUR_BOKEH_PIXELS * size, anything may be connected. Use the real input size and remove asserts? */ - const float u = (float)(COM_BLUR_BOKEH_PIXELS / 2) + - (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1); - const float v = (float)(COM_BLUR_BOKEH_PIXELS / 2) + - (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1); + const float u = float(COM_BLUR_BOKEH_PIXELS / 2) + + (dx / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1); + const float v = float(COM_BLUR_BOKEH_PIXELS / 2) + + (dy / size) * float((COM_BLUR_BOKEH_PIXELS / 2) - 1); float bokeh[4]; p.bokeh_input->read_elem_checked(u, v, bokeh); madd_v4_v4v4(p.color_accum, bokeh, color); @@ -390,7 +390,7 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer * const float max_dim = MAX2(this->get_width(), this->get_height()); p.scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; - p.max_blur_scalar = static_cast<int>(max_size * p.scalar); + p.max_blur_scalar = int(max_size * p.scalar); CLAMP(p.max_blur_scalar, 1, max_blur_); for (BuffersIterator<float> it = output->iterate_with({p.image_input, p.size_input}, area); @@ -510,8 +510,8 @@ void InverseSearchRadiusOperation::deinit_execution() input_radius_ = nullptr; } -void InverseSearchRadiusOperation::determine_resolution(unsigned int resolution[2], - unsigned int preferred_resolution[2]) +void InverseSearchRadiusOperation::determine_resolution(uint resolution[2], + uint preferred_resolution[2]) { NodeOperation::determine_resolution(resolution, preferred_resolution); resolution[0] = resolution[0] / DIVIDER; diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cc b/source/blender/compositor/operations/COM_VectorBlurOperation.cc index 71c61a6e588..1330557c06f 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cc +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cc @@ -103,8 +103,8 @@ bool VectorBlurOperation::determine_depending_area_of_interest(rcti * /*input*/, return false; } -void VectorBlurOperation::get_area_of_interest(const int UNUSED(input_idx), - const rcti &UNUSED(output_area), +void VectorBlurOperation::get_area_of_interest(const int /*input_idx*/, + const rcti & /*output_area*/, rcti &r_input_area) { r_input_area = this->get_canvas(); @@ -190,7 +190,10 @@ struct ZSpan { float clipcrop; }; -/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */ +/** + * Each Z-buffer has coordinates transformed to local rectangle coordinates, + * so we can simply clip. + */ void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop) { memset(zspan, 0, sizeof(ZSpan)); @@ -385,9 +388,9 @@ static void zbuf_fill_in_rgba( xx1 = (x0 * v1[0] + y0 * v1[1]) / z0 + v1[2]; - zxd = -(double)x0 / (double)z0; - zyd = -(double)y0 / (double)z0; - zy0 = ((double)my2) * zyd + (double)xx1; + zxd = -double(x0) / double(z0); + zyd = -double(y0) / double(z0); + zy0 = double(my2) * zyd + double(xx1); /* start-offset in rect */ rectx = zspan->rectx; @@ -419,13 +422,13 @@ static void zbuf_fill_in_rgba( } if (sn2 >= sn1) { - zverg = (double)sn1 * zxd + zy0; + zverg = double(sn1) * zxd + zy0; rz = rectzofs + sn1; rp = rectpofs + sn1; x = sn2 - sn1; while (x >= 0) { - if (zverg < (double)*rz) { + if (zverg < double(*rz)) { *rz = zverg; *rp = *col; } @@ -528,7 +531,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove) } } - /* last: pixels with 0 we fill in zbuffer, with 1 we skip for mask */ + /* last: pixels with 0 we fill in Z-buffer, with 1 we skip for mask */ for (y = 2; y < ysize; y++) { /* setup rows */ row1 = rectmove + (y - 2) * xsize; @@ -590,15 +593,15 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, const float *dimg, *dz, *ro; float *rectvz, *dvz, *dvec1, *dvec2, *dz1, *dz2, *rectz; float *minvecbufrect = nullptr, *rectweight, *rw, *rectmax, *rm; - float maxspeedsq = (float)nbd->maxspeed * nbd->maxspeed; + float maxspeedsq = float(nbd->maxspeed) * nbd->maxspeed; int y, x, step, maxspeed = nbd->maxspeed, samples = nbd->samples; int tsktsk = 0; static int firsttime = 1; char *rectmove, *dm; zbuf_alloc_span(&zspan, xsize, ysize, 1.0f); - zspan.zmulx = ((float)xsize) / 2.0f; - zspan.zmuly = ((float)ysize) / 2.0f; + zspan.zmulx = float(xsize) / 2.0f; + zspan.zmuly = float(ysize) / 2.0f; zspan.zofsx = 0.0f; zspan.zofsy = 0.0f; @@ -627,7 +630,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, /* Min speed? then copy speed-buffer to recalculate speed vectors. */ if (nbd->minspeed) { - float minspeed = (float)nbd->minspeed; + float minspeed = float(nbd->minspeed); float minspeedsq = minspeed * minspeed; minvecbufrect = (float *)MEM_callocN(sizeof(float[4]) * xsize * ysize, "minspeed buf"); @@ -726,7 +729,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, if (maxspeed) { float speedsq = dvz[0] * dvz[0] + dvz[1] * dvz[1]; if (speedsq > maxspeedsq) { - speedsq = (float)maxspeed / sqrtf(speedsq); + speedsq = float(maxspeed) / sqrtf(speedsq); dvz[0] *= speedsq; dvz[1] *= speedsq; } @@ -757,7 +760,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, dm = rectmove; dvec1 = vecbufrect; for (x = xsize * ysize; x > 0; x--, dm++, dvec1 += 4) { - if ((dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f)) { + if (dvec1[0] != 0.0f || dvec1[1] != 0.0f || dvec1[2] != 0.0f || dvec1[3] != 0.0f) { *dm = 255; } } @@ -776,7 +779,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, /* accumulate */ samples /= 2; for (step = 1; step <= samples; step++) { - float speedfac = 0.5f * nbd->fac * (float)step / (float)(samples + 1); + float speedfac = 0.5f * nbd->fac * float(step) / float(samples + 1); int side; for (side = 0; side < 2; side++) { @@ -864,7 +867,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, col.alpha = 0.0f; } else { - col.alpha = ((float)*dm) / 255.0f; + col.alpha = float(*dm) / 255.0f; } col.colpoin = dimg; @@ -882,7 +885,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, * we don't know what is behind it so we don't do that. this hack * overestimates the contribution of foreground pixels but looks a * bit better without a sudden cutoff. */ - blendfac = ((samples - step) / (float)samples); + blendfac = ((samples - step) / float(samples)); /* Smooth-step to make it look a bit nicer as well. */ blendfac = 3.0f * pow(blendfac, 2.0f) - 2.0f * pow(blendfac, 3.0f); diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cc b/source/blender/compositor/operations/COM_ViewerOperation.cc index 3bd5fa4ad14..b4ff6878784 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cc +++ b/source/blender/compositor/operations/COM_ViewerOperation.cc @@ -60,7 +60,7 @@ void ViewerOperation::deinit_execution() output_buffer_ = nullptr; } -void ViewerOperation::execute_region(rcti *rect, unsigned int /*tile_number*/) +void ViewerOperation::execute_region(rcti *rect, uint /*tile_number*/) { float *buffer = output_buffer_; float *depthbuffer = depth_buffer_; @@ -216,7 +216,7 @@ eCompositorPriority ViewerOperation::get_render_priority() const return eCompositorPriority::Low; } -void ViewerOperation::update_memory_buffer_partial(MemoryBuffer *UNUSED(output), +void ViewerOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, const rcti &area, Span<MemoryBuffer *> inputs) { @@ -264,7 +264,7 @@ void ViewerOperation::clear_display_buffer() return; } - size_t buf_bytes = (size_t)ibuf_->y * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float); + size_t buf_bytes = size_t(ibuf_->y) * ibuf_->x * COM_DATA_TYPE_COLOR_CHANNELS * sizeof(float); if (buf_bytes > 0) { memset(output_buffer_, 0, buf_bytes); rcti display_area; diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cc b/source/blender/compositor/operations/COM_WriteBufferOperation.cc index 9073c92b154..56261bfc660 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cc +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cc @@ -42,7 +42,7 @@ void WriteBufferOperation::deinit_execution() memory_proxy_->free(); } -void WriteBufferOperation::execute_region(rcti *rect, unsigned int /*tile_number*/) +void WriteBufferOperation::execute_region(rcti *rect, uint /*tile_number*/) { MemoryBuffer *memory_buffer = memory_proxy_->get_buffer(); float *buffer = memory_buffer->get_buffer(); @@ -95,7 +95,7 @@ void WriteBufferOperation::execute_region(rcti *rect, unsigned int /*tile_number void WriteBufferOperation::execute_opencl_region(OpenCLDevice *device, rcti * /*rect*/, - unsigned int /*chunk_number*/, + uint /*chunk_number*/, MemoryBuffer **input_memory_buffers, MemoryBuffer *output_buffer) { @@ -110,8 +110,8 @@ void WriteBufferOperation::execute_opencl_region(OpenCLDevice *device, * NOTE: list of cl_mem will be filled by 2, and needs to be cleaned up by 4 */ /* STEP 1 */ - const unsigned int output_buffer_width = output_buffer->get_width(); - const unsigned int output_buffer_height = output_buffer->get_height(); + const uint output_buffer_width = output_buffer->get_width(); + const uint output_buffer_height = output_buffer->get_height(); const cl_image_format *image_format = OpenCLDevice::determine_image_format(output_buffer); diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt index 1f1333332f5..b4352248b5b 100644 --- a/source/blender/compositor/realtime_compositor/CMakeLists.txt +++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt @@ -2,6 +2,8 @@ set(INC . + algorithms + cached_resources ../../blenkernel ../../blenlib ../../gpu @@ -9,6 +11,7 @@ set(INC ../../makesdna ../../makesrna ../../nodes + ../../render ../../gpu/intern ../../../../intern/guardedalloc ) @@ -30,6 +33,7 @@ set(SRC intern/shader_node.cc intern/shader_operation.cc intern/simple_operation.cc + intern/static_cache_manager.cc intern/static_shader_manager.cc intern/texture_pool.cc intern/utilities.cc @@ -50,17 +54,157 @@ set(SRC COM_shader_node.hh COM_shader_operation.hh COM_simple_operation.hh + COM_static_cache_manager.hh COM_static_shader_manager.hh COM_texture_pool.hh COM_utilities.hh + + algorithms/intern/algorithm_parallel_reduction.cc + + algorithms/COM_algorithm_parallel_reduction.hh + + cached_resources/intern/morphological_distance_feather_weights.cc + cached_resources/intern/symmetric_blur_weights.cc + cached_resources/intern/symmetric_separable_blur_weights.cc + + cached_resources/COM_cached_resource.hh + cached_resources/COM_morphological_distance_feather_weights.hh + cached_resources/COM_symmetric_blur_weights.hh + cached_resources/COM_symmetric_separable_blur_weights.hh ) set(LIB bf_gpu bf_nodes bf_imbuf + bf_render bf_blenlib bf_blenkernel ) +set(GLSL_SRC + shaders/compositor_alpha_crop.glsl + shaders/compositor_bilateral_blur.glsl + shaders/compositor_blur.glsl + shaders/compositor_blur_variable_size.glsl + shaders/compositor_bokeh_image.glsl + shaders/compositor_box_mask.glsl + shaders/compositor_convert.glsl + shaders/compositor_despeckle.glsl + shaders/compositor_directional_blur.glsl + shaders/compositor_edge_filter.glsl + shaders/compositor_ellipse_mask.glsl + shaders/compositor_filter.glsl + shaders/compositor_flip.glsl + shaders/compositor_image_crop.glsl + shaders/compositor_morphological_distance.glsl + shaders/compositor_morphological_distance_feather.glsl + shaders/compositor_morphological_distance_threshold.glsl + shaders/compositor_morphological_step.glsl + shaders/compositor_normalize.glsl + shaders/compositor_parallel_reduction.glsl + shaders/compositor_projector_lens_distortion.glsl + shaders/compositor_realize_on_domain.glsl + shaders/compositor_screen_lens_distortion.glsl + shaders/compositor_set_alpha.glsl + shaders/compositor_split_viewer.glsl + shaders/compositor_symmetric_blur.glsl + shaders/compositor_symmetric_separable_blur.glsl + shaders/compositor_tone_map_photoreceptor.glsl + shaders/compositor_tone_map_simple.glsl + + shaders/library/gpu_shader_compositor_alpha_over.glsl + shaders/library/gpu_shader_compositor_blur_common.glsl + shaders/library/gpu_shader_compositor_bright_contrast.glsl + shaders/library/gpu_shader_compositor_channel_matte.glsl + shaders/library/gpu_shader_compositor_chroma_matte.glsl + shaders/library/gpu_shader_compositor_color_balance.glsl + shaders/library/gpu_shader_compositor_color_correction.glsl + shaders/library/gpu_shader_compositor_color_matte.glsl + shaders/library/gpu_shader_compositor_color_spill.glsl + shaders/library/gpu_shader_compositor_color_to_luminance.glsl + shaders/library/gpu_shader_compositor_difference_matte.glsl + shaders/library/gpu_shader_compositor_distance_matte.glsl + shaders/library/gpu_shader_compositor_exposure.glsl + shaders/library/gpu_shader_compositor_gamma.glsl + shaders/library/gpu_shader_compositor_hue_correct.glsl + shaders/library/gpu_shader_compositor_hue_saturation_value.glsl + shaders/library/gpu_shader_compositor_invert.glsl + shaders/library/gpu_shader_compositor_luminance_matte.glsl + shaders/library/gpu_shader_compositor_main.glsl + shaders/library/gpu_shader_compositor_map_value.glsl + shaders/library/gpu_shader_compositor_normal.glsl + shaders/library/gpu_shader_compositor_posterize.glsl + shaders/library/gpu_shader_compositor_separate_combine.glsl + shaders/library/gpu_shader_compositor_set_alpha.glsl + shaders/library/gpu_shader_compositor_store_output.glsl + shaders/library/gpu_shader_compositor_texture_utilities.glsl + shaders/library/gpu_shader_compositor_type_conversion.glsl +) + +set(GLSL_C) +foreach(GLSL_FILE ${GLSL_SRC}) + data_to_c_simple(${GLSL_FILE} GLSL_C) +endforeach() + +blender_add_lib(bf_compositor_shaders "${GLSL_C}" "" "" "") + +list(APPEND LIB + bf_compositor_shaders +) + +set(GLSL_SOURCE_CONTENT "") +foreach(GLSL_FILE ${GLSL_SRC}) + get_filename_component(GLSL_FILE_NAME ${GLSL_FILE} NAME) + string(REPLACE "." "_" GLSL_FILE_NAME_UNDERSCORES ${GLSL_FILE_NAME}) + string(APPEND GLSL_SOURCE_CONTENT "SHADER_SOURCE\(datatoc_${GLSL_FILE_NAME_UNDERSCORES}, \"${GLSL_FILE_NAME}\", \"${GLSL_FILE}\"\)\n") +endforeach() + +set(glsl_source_list_file "${CMAKE_CURRENT_BINARY_DIR}/glsl_compositor_source_list.h") +file(GENERATE OUTPUT ${glsl_source_list_file} CONTENT "${GLSL_SOURCE_CONTENT}") +list(APPEND SRC ${glsl_source_list_file}) +list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR}) + +target_include_directories(bf_compositor_shaders PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + +set(SRC_SHADER_CREATE_INFOS + shaders/infos/compositor_alpha_crop_info.hh + shaders/infos/compositor_bilateral_blur_info.hh + shaders/infos/compositor_blur_info.hh + shaders/infos/compositor_blur_variable_size_info.hh + shaders/infos/compositor_bokeh_image_info.hh + shaders/infos/compositor_box_mask_info.hh + shaders/infos/compositor_convert_info.hh + shaders/infos/compositor_despeckle_info.hh + shaders/infos/compositor_directional_blur_info.hh + shaders/infos/compositor_edge_filter_info.hh + shaders/infos/compositor_ellipse_mask_info.hh + shaders/infos/compositor_filter_info.hh + shaders/infos/compositor_flip_info.hh + shaders/infos/compositor_image_crop_info.hh + shaders/infos/compositor_morphological_distance_feather_info.hh + shaders/infos/compositor_morphological_distance_info.hh + shaders/infos/compositor_morphological_distance_threshold_info.hh + shaders/infos/compositor_morphological_step_info.hh + shaders/infos/compositor_normalize_info.hh + shaders/infos/compositor_parallel_reduction_info.hh + shaders/infos/compositor_projector_lens_distortion_info.hh + shaders/infos/compositor_realize_on_domain_info.hh + shaders/infos/compositor_screen_lens_distortion_info.hh + shaders/infos/compositor_set_alpha_info.hh + shaders/infos/compositor_split_viewer_info.hh + shaders/infos/compositor_symmetric_blur_info.hh + shaders/infos/compositor_symmetric_separable_blur_info.hh + shaders/infos/compositor_tone_map_photoreceptor_info.hh + shaders/infos/compositor_tone_map_simple_info.hh +) + +set(SHADER_CREATE_INFOS_CONTENT "") +foreach(DESCRIPTOR_FILE ${SRC_SHADER_CREATE_INFOS}) + string(APPEND SHADER_CREATE_INFOS_CONTENT "#include \"${DESCRIPTOR_FILE}\"\n") +endforeach() + +set(shader_create_info_list_file "${CMAKE_CURRENT_BINARY_DIR}/compositor_shader_create_info_list.hh") +file(GENERATE OUTPUT ${shader_create_info_list_file} CONTENT "${SHADER_CREATE_INFOS_CONTENT}") + blender_add_lib(bf_realtime_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/compositor/realtime_compositor/COM_context.hh b/source/blender/compositor/realtime_compositor/COM_context.hh index b5c8cea641f..80fb4f70ca4 100644 --- a/source/blender/compositor/realtime_compositor/COM_context.hh +++ b/source/blender/compositor/realtime_compositor/COM_context.hh @@ -9,6 +9,7 @@ #include "GPU_texture.h" +#include "COM_static_cache_manager.hh" #include "COM_static_shader_manager.hh" #include "COM_texture_pool.hh" @@ -22,14 +23,17 @@ namespace blender::realtime_compositor { * providing input data like render passes and the active scene, as well as references to the data * where the output of the evaluator will be written. The class also provides a reference to the * texture pool which should be implemented by the caller and provided during construction. - * Finally, the class have an instance of a static shader manager for convenient shader - * acquisition. */ + * Finally, the class have an instance of a static shader manager and a static resource manager + * for acquiring cached shaders and resources efficiently. */ class Context { private: /* A texture pool that can be used to allocate textures for the compositor efficiently. */ TexturePool &texture_pool_; /* A static shader manager that can be used to acquire shaders for the compositor efficiently. */ StaticShaderManager shader_manager_; + /* A static cache manager that can be used to acquire cached resources for the compositor + * efficiently. */ + StaticCacheManager cache_manager_; public: Context(TexturePool &texture_pool); @@ -67,6 +71,9 @@ class Context { /* Get a reference to the static shader manager of this context. */ StaticShaderManager &shader_manager(); + + /* Get a reference to the static cache manager of this context. */ + StaticCacheManager &cache_manager(); }; } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh b/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh index 15e1d0722ea..310333aea5a 100644 --- a/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh +++ b/source/blender/compositor/realtime_compositor/COM_conversion_operation.hh @@ -11,11 +11,13 @@ namespace blender::realtime_compositor { -/* ------------------------------------------------------------------------------------------------- - * Conversion Operation +/* -------------------------------------------------------------------- */ +/** \name Conversion Operation * * A simple operation that converts a result from a certain type to another. See the derived - * classes for more details. */ + * classes for more details. + * \{ */ + class ConversionOperation : public SimpleOperation { public: using SimpleOperation::SimpleOperation; @@ -37,13 +39,18 @@ class ConversionOperation : public SimpleOperation { /* Get the shader the will be used for conversion. */ virtual GPUShader *get_conversion_shader() const = 0; -}; -/* ------------------------------------------------------------------------------------------------- - * Convert Float To Vector Operation + /** \} */ + +}; // namespace blender::realtime_compositorclassConversionOperation:publicSimpleOperation + +/* -------------------------------------------------------------------- */ +/** \name Convert Float to Vector Operation * * Takes a float result and outputs a vector result. All three components of the output are filled - * with the input float. */ + * with the input float. + * \{ */ + class ConvertFloatToVectorOperation : public ConversionOperation { public: ConvertFloatToVectorOperation(Context &context); @@ -53,11 +60,15 @@ class ConvertFloatToVectorOperation : public ConversionOperation { GPUShader *get_conversion_shader() const override; }; -/* ------------------------------------------------------------------------------------------------- - * Convert Float To Color Operation +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Float to Color Operation * * Takes a float result and outputs a color result. All three color channels of the output are - * filled with the input float and the alpha channel is set to 1. */ + * filled with the input float and the alpha channel is set to 1. + * \{ */ + class ConvertFloatToColorOperation : public ConversionOperation { public: ConvertFloatToColorOperation(Context &context); @@ -67,11 +78,15 @@ class ConvertFloatToColorOperation : public ConversionOperation { GPUShader *get_conversion_shader() const override; }; -/* ------------------------------------------------------------------------------------------------- - * Convert Color To Float Operation +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Color to Float Operation * * Takes a color result and outputs a float result. The output is the average of the three color - * channels, the alpha channel is ignored. */ + * channels, the alpha channel is ignored. + * \{ */ + class ConvertColorToFloatOperation : public ConversionOperation { public: ConvertColorToFloatOperation(Context &context); @@ -81,11 +96,15 @@ class ConvertColorToFloatOperation : public ConversionOperation { GPUShader *get_conversion_shader() const override; }; -/* ------------------------------------------------------------------------------------------------- - * Convert Color To Vector Operation +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Color to Vector Operation * * Takes a color result and outputs a vector result. The output is a copy of the three color - * channels to the three vector components. */ + * channels to the three vector components. + * \{ */ + class ConvertColorToVectorOperation : public ConversionOperation { public: ConvertColorToVectorOperation(Context &context); @@ -95,11 +114,18 @@ class ConvertColorToVectorOperation : public ConversionOperation { GPUShader *get_conversion_shader() const override; }; -/* ------------------------------------------------------------------------------------------------- - * Convert Vector To Float Operation +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Vector to Float Operation * * Takes a vector result and outputs a float result. The output is the average of the three - * components. */ + * components. + * \{ */ + +/* + * + * */ class ConvertVectorToFloatOperation : public ConversionOperation { public: ConvertVectorToFloatOperation(Context &context); @@ -109,11 +135,15 @@ class ConvertVectorToFloatOperation : public ConversionOperation { GPUShader *get_conversion_shader() const override; }; -/* ------------------------------------------------------------------------------------------------- - * Convert Vector To Color Operation +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Vector to Color Operation * * Takes a vector result and outputs a color result. The output is a copy of the three vector - * components to the three color channels with the alpha channel set to 1. */ + * components to the three color channels with the alpha channel set to 1. + * \{ */ + class ConvertVectorToColorOperation : public ConversionOperation { public: ConvertVectorToColorOperation(Context &context); @@ -123,4 +153,6 @@ class ConvertVectorToColorOperation : public ConversionOperation { GPUShader *get_conversion_shader() const override; }; +/** \} */ + } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/COM_domain.hh b/source/blender/compositor/realtime_compositor/COM_domain.hh index 54d712f7578..99b40ae61cf 100644 --- a/source/blender/compositor/realtime_compositor/COM_domain.hh +++ b/source/blender/compositor/realtime_compositor/COM_domain.hh @@ -28,7 +28,7 @@ struct RealizationOptions { * result involves projecting it on a different domain, which in turn, involves sampling the * result at arbitrary locations, the interpolation identifies the method used for computing the * value at those arbitrary locations. */ - Interpolation interpolation = Interpolation::Nearest; + Interpolation interpolation = Interpolation::Bilinear; /* If true, the result will be repeated infinitely along the horizontal axis when realizing the * result. If false, regions outside of bounds of the result along the horizontal axis will be * filled with zeros. */ diff --git a/source/blender/compositor/realtime_compositor/COM_result.hh b/source/blender/compositor/realtime_compositor/COM_result.hh index a16d68bb92d..f5ecc4c2112 100644 --- a/source/blender/compositor/realtime_compositor/COM_result.hh +++ b/source/blender/compositor/realtime_compositor/COM_result.hh @@ -14,7 +14,9 @@ namespace blender::realtime_compositor { /* Possible data types that operations can operate on. They either represent the base type of the - * result texture or a single value result. */ + * result texture or a single value result. The color type represents an RGBA color. And the vector + * type represents a generic 4-component vector, which can encode two 2D vectors, one 3D vector + * with the last component ignored, or other dimensional data. */ enum class ResultType : uint8_t { Float, Vector, @@ -85,7 +87,7 @@ class Result { * is a texture. */ union { float float_value_; - float3 vector_value_; + float4 vector_value_; float4 color_value_; }; /* The domain of the result. This only matters if the result was a texture. See the discussion in @@ -157,7 +159,7 @@ class Result { /* If the result is a single value result of type vector, return its vector value. Otherwise, an * uninitialized value is returned. */ - float3 get_vector_value() const; + float4 get_vector_value() const; /* If the result is a single value result of type color, return its color value. Otherwise, an * uninitialized value is returned. */ @@ -167,7 +169,7 @@ class Result { float get_float_value_default(float default_value) const; /* Same as get_vector_value but returns a default value if the result is not a single value. */ - float3 get_vector_value_default(const float3 &default_value) const; + float4 get_vector_value_default(const float4 &default_value) const; /* Same as get_color_value but returns a default value if the result is not a single value. */ float4 get_color_value_default(const float4 &default_value) const; @@ -178,7 +180,7 @@ class Result { /* If the result is a single value result of type vector, set its vector value and upload it to * the texture. Otherwise, an undefined behavior is invoked. */ - void set_vector_value(const float3 &value); + void set_vector_value(const float4 &value); /* If the result is a single value result of type color, set its color value and upload it to the * texture. Otherwise, an undefined behavior is invoked. */ diff --git a/source/blender/compositor/realtime_compositor/COM_scheduler.hh b/source/blender/compositor/realtime_compositor/COM_scheduler.hh index 4f778b32145..9f3bc14ae17 100644 --- a/source/blender/compositor/realtime_compositor/COM_scheduler.hh +++ b/source/blender/compositor/realtime_compositor/COM_scheduler.hh @@ -16,6 +16,6 @@ using Schedule = VectorSet<DNode>; /* Computes the execution schedule of the node tree. This is essentially a post-order depth first * traversal of the node tree from the output node to the leaf input nodes, with informed order of * traversal of dependencies based on a heuristic estimation of the number of needed buffers. */ -Schedule compute_schedule(DerivedNodeTree &tree); +Schedule compute_schedule(const DerivedNodeTree &tree); } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh new file mode 100644 index 00000000000..20fbb156879 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include <memory> + +#include "BLI_map.hh" +#include "BLI_math_vec_types.hh" + +#include "COM_morphological_distance_feather_weights.hh" +#include "COM_symmetric_blur_weights.hh" +#include "COM_symmetric_separable_blur_weights.hh" + +namespace blender::realtime_compositor { + +/* ------------------------------------------------------------------------------------------------- + * Static Cache Manager + * + * A static cache manager is a collection of cached resources that can be retrieved when needed and + * created if not already available. In particular, each cached resource type has its own Map in + * the class, where all instances of that cached resource type are stored and tracked. See the + * CachedResource class for more information. + * + * The manager deletes the cached resources that are no longer needed. A cached resource is said to + * be not needed when it was not used in the previous evaluation. This is done through the + * following mechanism: + * + * - Before every evaluation, do the following: + * 1. All resources whose CachedResource::needed flag is false are deleted. + * 2. The CachedResource::needed flag of all remaining resources is set to false. + * - During evaluation, when retrieving any cached resource, set its CachedResource::needed flag to + * true. + * + * In effect, any resource that was used in the previous evaluation but was not used in the current + * evaluation will be deleted before the next evaluation. This mechanism is implemented in the + * reset() method of the class, which should be called before every evaluation. */ +class StaticCacheManager { + private: + /* A map that stores all SymmetricBlurWeights cached resources. */ + Map<SymmetricBlurWeightsKey, std::unique_ptr<SymmetricBlurWeights>> symmetric_blur_weights_; + + /* A map that stores all SymmetricSeparableBlurWeights cached resources. */ + Map<SymmetricSeparableBlurWeightsKey, std::unique_ptr<SymmetricSeparableBlurWeights>> + symmetric_separable_blur_weights_; + + /* A map that stores all MorphologicalDistanceFeatherWeights cached resources. */ + Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>> + morphological_distance_feather_weights_; + + public: + /* Reset the cache manager by deleting the cached resources that are no longer needed because + * they weren't used in the last evaluation and prepare the remaining cached resources to track + * their needed status in the next evaluation. See the class description for more information. + * This should be called before every evaluation. */ + void reset(); + + /* Check if there is an available SymmetricBlurWeights cached resource with the given parameters + * in the manager, if one exists, return it, otherwise, return a newly created one and add it to + * the manager. In both cases, tag the cached resource as needed to keep it cached for the next + * evaluation. */ + SymmetricBlurWeights &get_symmetric_blur_weights(int type, float2 radius); + + /* Check if there is an available SymmetricSeparableBlurWeights cached resource with the given + * parameters in the manager, if one exists, return it, otherwise, return a newly created one and + * add it to the manager. In both cases, tag the cached resource as needed to keep it cached for + * the next evaluation. */ + SymmetricSeparableBlurWeights &get_symmetric_separable_blur_weights(int type, float radius); + + /* Check if there is an available MorphologicalDistanceFeatherWeights cached resource with the + * given parameters in the manager, if one exists, return it, otherwise, return a newly created + * one and add it to the manager. In both cases, tag the cached resource as needed to keep it + * cached for the next evaluation. */ + MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type, + int radius); +}; + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh index cc6641d288f..c68219b0279 100644 --- a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh +++ b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh @@ -60,8 +60,8 @@ class TexturePool { /* Shorthand for acquire with GPU_RGBA16F format. */ GPUTexture *acquire_color(int2 size); - /* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors - * are stored in RGBA textures, due to the limited support for RGB textures. */ + /* Shorthand for acquire with GPU_RGBA16F format. Identical to acquire_color because vectors are + * 4D, and are thus stored in RGBA textures. */ GPUTexture *acquire_vector(int2 size); /* Shorthand for acquire with GPU_R16F format. */ diff --git a/source/blender/compositor/realtime_compositor/COM_utilities.hh b/source/blender/compositor/realtime_compositor/COM_utilities.hh index 25f9fd0c1b6..efd1bc2b6b0 100644 --- a/source/blender/compositor/realtime_compositor/COM_utilities.hh +++ b/source/blender/compositor/realtime_compositor/COM_utilities.hh @@ -17,7 +17,7 @@ namespace blender::realtime_compositor { using namespace nodes::derived_node_tree_types; /** - Get the origin socket of the given node input. If the input is not linked, the socket itself is + * Get the origin socket of the given node input. If the input is not linked, the socket itself is * returned. If the input is linked, the socket that is linked to it is returned, which could * either be an input or an output. An input socket is returned when the given input is connected * to an unlinked input of a group input node. diff --git a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh new file mode 100644 index 00000000000..f6d479f9bbe --- /dev/null +++ b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_math_vec_types.hh" + +#include "GPU_texture.h" + +#include "COM_context.hh" + +namespace blender::realtime_compositor { + +/* -------------------------------------------------------------------- + * Sum Reductions. + */ + +/* Computes the sum of the red channel of all pixels in the given texture. */ +float sum_red(Context &context, GPUTexture *texture); + +/* Computes the sum of the green channel of all pixels in the given texture. */ +float sum_green(Context &context, GPUTexture *texture); + +/* Computes the sum of the blue channel of all pixels in the given texture. */ +float sum_blue(Context &context, GPUTexture *texture); + +/* Computes the sum of the luminance of all pixels in the given texture, using the given luminance + * coefficients to compute the luminance. */ +float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients); + +/* Computes the sum of the logarithm of the luminance of all pixels in the given texture, using the + * given luminance coefficients to compute the luminance. */ +float sum_log_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients); + +/* Computes the sum of the colors of all pixels in the given texture. */ +float4 sum_color(Context &context, GPUTexture *texture); + +/* -------------------------------------------------------------------- + * Sum Of Squared Difference Reductions. + */ + +/* Computes the sum of the squared difference between the red channel of all pixels in the given + * texture and the given subtrahend. This can be used to compute the standard deviation if the + * given subtrahend is the mean. */ +float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend); + +/* Computes the sum of the squared difference between the green channel of all pixels in the given + * texture and the given subtrahend. This can be used to compute the standard deviation if the + * given subtrahend is the mean. */ +float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend); + +/* Computes the sum of the squared difference between the blue channel of all pixels in the given + * texture and the given subtrahend. This can be used to compute the standard deviation if the + * given subtrahend is the mean. */ +float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend); + +/* Computes the sum of the squared difference between the luminance of all pixels in the given + * texture and the given subtrahend, using the given luminance coefficients to compute the + * luminance. This can be used to compute the standard deviation if the given subtrahend is the + * mean. */ +float sum_luminance_squared_difference(Context &context, + GPUTexture *texture, + float3 luminance_coefficients, + float subtrahend); + +/* -------------------------------------------------------------------- + * Maximum Reductions. + */ + +/* Computes the maximum luminance of all pixels in the given texture, using the given luminance + * coefficients to compute the luminance. */ +float maximum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients); + +/* Computes the maximum float of all pixels in the given float texture, limited to the given range. + * Values outside of the given range are ignored. If non of the pixel values are in the range, the + * lower bound of the range is returned. For instance, if the given range is [-10, 10] and the + * image contains the values {2, 5, 11}, the maximum will be 5, since 11 is outside of the range. + * This is particularly useful for Z Depth normalization, since Z Depth can contain near infinite + * values, so enforcing an upper bound is beneficial. */ +float maximum_float_in_range(Context &context, + GPUTexture *texture, + float lower_bound, + float upper_bound); + +/* -------------------------------------------------------------------- + * Minimum Reductions. + */ + +/* Computes the minimum luminance of all pixels in the given texture, using the given luminance + * coefficients to compute the luminance. */ +float minimum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients); + +/* Computes the minimum float of all pixels in the given float texture, limited to the given range. + * Values outside of the given range are ignored. If non of the pixel values are in the range, the + * upper bound of the range is returned. For instance, if the given range is [-10, 10] and the + * image contains the values {-11, 2, 5}, the minimum will be 2, since -11 is outside of the range. + * This is particularly useful for Z Depth normalization, since Z Depth can contain near infinite + * values, so enforcing a lower bound is beneficial. */ +float minimum_float_in_range(Context &context, + GPUTexture *texture, + float lower_bound, + float upper_bound); + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc new file mode 100644 index 00000000000..9672431992d --- /dev/null +++ b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_math_vec_types.hh" +#include "BLI_math_vector.hh" + +#include "MEM_guardedalloc.h" + +#include "GPU_compute.h" +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_context.hh" +#include "COM_utilities.hh" + +#include "COM_algorithm_parallel_reduction.hh" + +namespace blender::realtime_compositor { + +/* Reduces the given texture into a single value and returns it. The return value should be freed + * by a call to MEM_freeN. The return value is either a pointer to a float, or a pointer to an + * array of floats that represents a vector. This depends on the given format, which should be + * compatible with the reduction shader. + * + * The given reduction shader should be bound when calling the function and the shader is expected + * to be derived from the compositor_parallel_reduction.glsl shader, see that file for more + * information. Also see the compositor_parallel_reduction_info.hh file for example shader + * definitions. */ +static float *parallel_reduction_dispatch(Context &context, + GPUTexture *texture, + GPUShader *shader, + eGPUTextureFormat format) +{ + GPU_shader_uniform_1b(shader, "is_initial_reduction", true); + + GPUTexture *texture_to_reduce = texture; + int2 size_to_reduce = int2(GPU_texture_width(texture), GPU_texture_height(texture)); + + /* Dispatch the reduction shader until the texture reduces to a single pixel. */ + while (size_to_reduce != int2(1)) { + const int2 reduced_size = math::divide_ceil(size_to_reduce, int2(16)); + GPUTexture *reduced_texture = context.texture_pool().acquire(reduced_size, format); + + GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH); + const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + GPU_texture_bind(texture_to_reduce, texture_image_unit); + + const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + GPU_texture_image_bind(reduced_texture, image_unit); + + GPU_compute_dispatch(shader, reduced_size.x, reduced_size.y, 1); + + GPU_texture_image_unbind(reduced_texture); + GPU_texture_unbind(texture_to_reduce); + + /* Release the input texture only if it is not the source texture, since the source texture is + * not acquired or owned by the function. */ + if (texture_to_reduce != texture) { + context.texture_pool().release(texture_to_reduce); + } + + texture_to_reduce = reduced_texture; + size_to_reduce = reduced_size; + + GPU_shader_uniform_1b(shader, "is_initial_reduction", false); + } + + GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + float *pixel = static_cast<float *>(GPU_texture_read(texture_to_reduce, GPU_DATA_FLOAT, 0)); + + /* Release the final texture only if it is not the source texture, since the source texture is + * not acquired or owned by the function. */ + if (texture_to_reduce != texture) { + context.texture_pool().release(texture_to_reduce); + } + + return pixel; +} + +/* -------------------------------------------------------------------- + * Sum Reductions. + */ + +float sum_red(Context &context, GPUTexture *texture) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_red"); + GPU_shader_bind(shader); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_green(Context &context, GPUTexture *texture) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_green"); + GPU_shader_bind(shader); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_blue(Context &context, GPUTexture *texture) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_blue"); + GPU_shader_bind(shader); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_luminance"); + GPU_shader_bind(shader); + + GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_log_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_log_luminance"); + GPU_shader_bind(shader); + + GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float4 sum_color(Context &context, GPUTexture *texture) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_color"); + GPU_shader_bind(shader); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_RGBA32F); + const float4 sum = float4(reduced_value); + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +/* -------------------------------------------------------------------- + * Sum Of Squared Difference Reductions. + */ + +float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_red_squared_difference"); + GPU_shader_bind(shader); + + GPU_shader_uniform_1f(shader, "subtrahend", subtrahend); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_green_squared_difference"); + GPU_shader_bind(shader); + + GPU_shader_uniform_1f(shader, "subtrahend", subtrahend); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_blue_squared_difference"); + GPU_shader_bind(shader); + + GPU_shader_uniform_1f(shader, "subtrahend", subtrahend); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +float sum_luminance_squared_difference(Context &context, + GPUTexture *texture, + float3 luminance_coefficients, + float subtrahend) +{ + GPUShader *shader = context.shader_manager().get("compositor_sum_luminance_squared_difference"); + GPU_shader_bind(shader); + + GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients); + GPU_shader_uniform_1f(shader, "subtrahend", subtrahend); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float sum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return sum; +} + +/* -------------------------------------------------------------------- + * Maximum Reductions. + */ + +float maximum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients) +{ + GPUShader *shader = context.shader_manager().get("compositor_maximum_luminance"); + GPU_shader_bind(shader); + + GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float maximum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return maximum; +} + +float maximum_float_in_range(Context &context, + GPUTexture *texture, + float lower_bound, + float upper_bound) +{ + GPUShader *shader = context.shader_manager().get("compositor_maximum_float_in_range"); + GPU_shader_bind(shader); + + GPU_shader_uniform_1f(shader, "lower_bound", lower_bound); + GPU_shader_uniform_1f(shader, "upper_bound", upper_bound); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float maximum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return maximum; +} + +/* -------------------------------------------------------------------- + * Minimum Reductions. + */ + +float minimum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients) +{ + GPUShader *shader = context.shader_manager().get("compositor_minimum_luminance"); + GPU_shader_bind(shader); + + GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float minimum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return minimum; +} + +float minimum_float_in_range(Context &context, + GPUTexture *texture, + float lower_bound, + float upper_bound) +{ + GPUShader *shader = context.shader_manager().get("compositor_minimum_float_in_range"); + GPU_shader_bind(shader); + + GPU_shader_uniform_1f(shader, "lower_bound", lower_bound); + GPU_shader_uniform_1f(shader, "upper_bound", upper_bound); + + float *reduced_value = parallel_reduction_dispatch(context, texture, shader, GPU_R32F); + const float minimum = *reduced_value; + MEM_freeN(reduced_value); + GPU_shader_unbind(); + + return minimum; +} + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh new file mode 100644 index 00000000000..fe3158ef52d --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_cached_resource.hh @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +namespace blender::realtime_compositor { + +/* ------------------------------------------------------------------------------------------------- + * Cached Resource. + * + * A cached resource is any resource that can be cached across compositor evaluations and across + * multiple operations. Cached resources are managed by an instance of a StaticCacheManager and are + * freed when they are no longer needed, a state which is represented by the `needed` member in the + * class. For more information on the caching mechanism, see the StaticCacheManager class. + * + * To add a new cached resource: + * + * - Create a derived class from CachedResource to represent the resource. + * - Create a key class that can be used in a Map to identify the resource. + * - Add a new Map to StaticCacheManager mapping the key to the resource. + * - Reset the contents of the added map in StaticCacheManager::reset. + * - Add an appropriate getter method in StaticCacheManager. + * + * See the existing cached resources for reference. */ +class CachedResource { + public: + /* A flag that represents the needed status of the cached resource. See the StaticCacheManager + * class for more information on how this member is utilized in the caching mechanism. */ + bool needed = true; +}; + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh new file mode 100644 index 00000000000..cd6827bdd6b --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_morphological_distance_feather_weights.hh @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include <cstdint> + +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_cached_resource.hh" + +namespace blender::realtime_compositor { + +/* ------------------------------------------------------------------------------------------------ + * Morphological Distance Feather Key. + */ +class MorphologicalDistanceFeatherWeightsKey { + public: + int type; + float radius; + + MorphologicalDistanceFeatherWeightsKey(int type, float radius); + + uint64_t hash() const; +}; + +bool operator==(const MorphologicalDistanceFeatherWeightsKey &a, + const MorphologicalDistanceFeatherWeightsKey &b); + +/* ------------------------------------------------------------------------------------------------- + * Morphological Distance Feather Weights. + * + * A cached resource that computes and caches 1D GPU textures containing the weights of the + * separable Gaussian filter of the given radius as well as an inverse distance falloff of the + * given type and radius. The weights and falloffs are symmetric, because the Gaussian and falloff + * functions are all even functions. Consequently, only the positive half of the filter is computed + * and the shader takes that into consideration. */ +class MorphologicalDistanceFeatherWeights : public CachedResource { + private: + GPUTexture *weights_texture_ = nullptr; + GPUTexture *distance_falloffs_texture_ = nullptr; + + public: + MorphologicalDistanceFeatherWeights(int type, int radius); + + ~MorphologicalDistanceFeatherWeights(); + + void compute_weights(int radius); + + void compute_distance_falloffs(int type, int radius); + + void bind_weights_as_texture(GPUShader *shader, const char *texture_name) const; + + void unbind_weights_as_texture() const; + + void bind_distance_falloffs_as_texture(GPUShader *shader, const char *texture_name) const; + + void unbind_distance_falloffs_as_texture() const; +}; + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh new file mode 100644 index 00000000000..05d3c7c6f3e --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include <cstdint> + +#include "BLI_math_vec_types.hh" + +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_cached_resource.hh" + +namespace blender::realtime_compositor { + +/* ------------------------------------------------------------------------------------------------ + * Symmetric Blur Weights Key. + */ +class SymmetricBlurWeightsKey { + public: + int type; + float2 radius; + + SymmetricBlurWeightsKey(int type, float2 radius); + + uint64_t hash() const; +}; + +bool operator==(const SymmetricBlurWeightsKey &a, const SymmetricBlurWeightsKey &b); + +/* ------------------------------------------------------------------------------------------------- + * Symmetric Blur Weights. + * + * A cached resource that computes and caches a 2D GPU texture containing the weights of the filter + * of the given type and radius. The filter is assumed to be symmetric, because the filter + * functions are evaluated on the normalized distance to the center. Consequently, only the upper + * right quadrant are computed and the shader takes that into consideration. */ +class SymmetricBlurWeights : public CachedResource { + private: + GPUTexture *texture_ = nullptr; + + public: + SymmetricBlurWeights(int type, float2 radius); + + ~SymmetricBlurWeights(); + + void bind_as_texture(GPUShader *shader, const char *texture_name) const; + + void unbind_as_texture() const; +}; + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh new file mode 100644 index 00000000000..85e75e4535d --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include <cstdint> + +#include "BLI_math_vec_types.hh" + +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_cached_resource.hh" + +namespace blender::realtime_compositor { + +/* ------------------------------------------------------------------------------------------------ + * Symmetric Separable Blur Weights Key. + */ +class SymmetricSeparableBlurWeightsKey { + public: + int type; + float radius; + + SymmetricSeparableBlurWeightsKey(int type, float radius); + + uint64_t hash() const; +}; + +bool operator==(const SymmetricSeparableBlurWeightsKey &a, + const SymmetricSeparableBlurWeightsKey &b); + +/* ------------------------------------------------------------------------------------------------- + * Symmetric Separable Blur Weights. + * + * A cached resource that computes and caches a 1D GPU texture containing the weights of the + * separable filter of the given type and radius. The filter is assumed to be symmetric, because + * the filter functions are all even functions. Consequently, only the positive half of the filter + * is computed and the shader takes that into consideration. */ +class SymmetricSeparableBlurWeights : public CachedResource { + private: + GPUTexture *texture_ = nullptr; + + public: + SymmetricSeparableBlurWeights(int type, float radius); + + ~SymmetricSeparableBlurWeights(); + + void bind_as_texture(GPUShader *shader, const char *texture_name) const; + + void unbind_as_texture() const; +}; + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc new file mode 100644 index 00000000000..eac88b907b8 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/morphological_distance_feather_weights.cc @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <cmath> +#include <cstdint> + +#include "BLI_array.hh" +#include "BLI_hash.hh" +#include "BLI_index_range.hh" + +#include "RE_pipeline.h" + +#include "DNA_scene_types.h" + +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_morphological_distance_feather_weights.hh" + +namespace blender::realtime_compositor { + +/* -------------------------------------------------------------------- + * Morphological Distance Feather Weights Key. + */ + +MorphologicalDistanceFeatherWeightsKey::MorphologicalDistanceFeatherWeightsKey(int type, + float radius) + : type(type), radius(radius) +{ +} + +uint64_t MorphologicalDistanceFeatherWeightsKey::hash() const +{ + return get_default_hash_2(type, radius); +} + +bool operator==(const MorphologicalDistanceFeatherWeightsKey &a, + const MorphologicalDistanceFeatherWeightsKey &b) +{ + return a.type == b.type && a.radius == b.radius; +} + +/* -------------------------------------------------------------------- + * Morphological Distance Feather Weights. + */ + +MorphologicalDistanceFeatherWeights::MorphologicalDistanceFeatherWeights(int type, int radius) +{ + compute_weights(radius); + compute_distance_falloffs(type, radius); +} + +MorphologicalDistanceFeatherWeights::~MorphologicalDistanceFeatherWeights() +{ + GPU_texture_free(weights_texture_); + GPU_texture_free(distance_falloffs_texture_); +} + +void MorphologicalDistanceFeatherWeights::compute_weights(int radius) +{ + /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only + * compute half of it and no doubling happens. We add 1 to make sure the filter size is always + * odd and there is a center weight. */ + const int size = radius + 1; + Array<float> weights(size); + + float sum = 0.0f; + + /* First, compute the center weight. */ + const float center_weight = RE_filter_value(R_FILTER_GAUSS, 0.0f); + weights[0] = center_weight; + sum += center_weight; + + /* Second, compute the other weights in the positive direction, making sure to add double the + * weight to the sum of weights because the filter is symmetric and we only loop over half of + * it. Skip the center weight already computed by dropping the front index. */ + const float scale = radius > 0.0f ? 1.0f / radius : 0.0f; + for (const int i : weights.index_range().drop_front(1)) { + const float weight = RE_filter_value(R_FILTER_GAUSS, i * scale); + weights[i] = weight; + sum += weight * 2.0f; + } + + /* Finally, normalize the weights. */ + for (const int i : weights.index_range()) { + weights[i] /= sum; + } + + weights_texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data()); +} + +/* Computes a falloff that is equal to 1 at an input of zero and decrease to zero at an input of 1, + * with the rate of decrease depending on the falloff type. */ +static float compute_distance_falloff(int type, float x) +{ + x = 1.0f - x; + + switch (type) { + case PROP_SMOOTH: + return 3.0f * x * x - 2.0f * x * x * x; + case PROP_SPHERE: + return std::sqrt(2.0f * x - x * x); + case PROP_ROOT: + return std::sqrt(x); + case PROP_SHARP: + return x * x; + case PROP_INVSQUARE: + return x * (2.0f - x); + case PROP_LIN: + return x; + default: + BLI_assert_unreachable(); + return x; + } +} + +void MorphologicalDistanceFeatherWeights::compute_distance_falloffs(int type, int radius) +{ + /* The size of the distance falloffs is double the radius plus 1, but since the falloffs are + * symmetric, we only compute half of them and no doubling happens. We add 1 to make sure the + * falloffs size is always odd and there is a center falloff. */ + const int size = radius + 1; + Array<float> falloffs(size); + + /* Compute the distance falloffs in the positive direction only, because the falloffs are + * symmetric. */ + const float scale = radius > 0.0f ? 1.0f / radius : 0.0f; + for (const int i : falloffs.index_range()) { + falloffs[i] = compute_distance_falloff(type, i * scale); + } + + distance_falloffs_texture_ = GPU_texture_create_1d( + "Distance Factors", size, 1, GPU_R16F, falloffs.data()); +} + +void MorphologicalDistanceFeatherWeights::bind_weights_as_texture(GPUShader *shader, + const char *texture_name) const +{ + const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + GPU_texture_bind(weights_texture_, texture_image_unit); +} + +void MorphologicalDistanceFeatherWeights::unbind_weights_as_texture() const +{ + GPU_texture_unbind(weights_texture_); +} + +void MorphologicalDistanceFeatherWeights::bind_distance_falloffs_as_texture( + GPUShader *shader, const char *texture_name) const +{ + const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + GPU_texture_bind(distance_falloffs_texture_, texture_image_unit); +} + +void MorphologicalDistanceFeatherWeights::unbind_distance_falloffs_as_texture() const +{ + GPU_texture_unbind(distance_falloffs_texture_); +} + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc new file mode 100644 index 00000000000..a22d32a8e18 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <cstdint> + +#include "BLI_array.hh" +#include "BLI_hash.hh" +#include "BLI_index_range.hh" +#include "BLI_math_vec_types.hh" +#include "BLI_math_vector.hh" + +#include "RE_pipeline.h" + +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_symmetric_blur_weights.hh" + +namespace blender::realtime_compositor { + +/* -------------------------------------------------------------------- + * Symmetric Blur Weights Key. + */ + +SymmetricBlurWeightsKey::SymmetricBlurWeightsKey(int type, float2 radius) + : type(type), radius(radius) +{ +} + +uint64_t SymmetricBlurWeightsKey::hash() const +{ + return get_default_hash_3(type, radius.x, radius.y); +} + +bool operator==(const SymmetricBlurWeightsKey &a, const SymmetricBlurWeightsKey &b) +{ + return a.type == b.type && a.radius == b.radius; +} + +/* -------------------------------------------------------------------- + * Symmetric Blur Weights. + */ + +SymmetricBlurWeights::SymmetricBlurWeights(int type, float2 radius) +{ + /* The full size of filter is double the radius plus 1, but since the filter is symmetric, we + * only compute a single quadrant of it and so no doubling happens. We add 1 to make sure the + * filter size is always odd and there is a center weight. */ + const float2 scale = math::safe_divide(float2(1.0f), radius); + const int2 size = int2(math::ceil(radius)) + int2(1); + Array<float> weights(size.x * size.y); + + float sum = 0.0f; + + /* First, compute the center weight. */ + const float center_weight = RE_filter_value(type, 0.0f); + weights[0] = center_weight; + sum += center_weight; + + /* Then, compute the weights along the positive x axis, making sure to add double the weight to + * the sum of weights because the filter is symmetric and we only loop over the positive half + * of the x axis. Skip the center weight already computed by dropping the front index. */ + for (const int x : IndexRange(size.x).drop_front(1)) { + const float weight = RE_filter_value(type, x * scale.x); + weights[x] = weight; + sum += weight * 2.0f; + } + + /* Then, compute the weights along the positive y axis, making sure to add double the weight to + * the sum of weights because the filter is symmetric and we only loop over the positive half + * of the y axis. Skip the center weight already computed by dropping the front index. */ + for (const int y : IndexRange(size.y).drop_front(1)) { + const float weight = RE_filter_value(type, y * scale.y); + weights[size.x * y] = weight; + sum += weight * 2.0f; + } + + /* Then, compute the other weights in the upper right quadrant, making sure to add quadruple + * the weight to the sum of weights because the filter is symmetric and we only loop over one + * quadrant of it. Skip the weights along the y and x axis already computed by dropping the + * front index. */ + for (const int y : IndexRange(size.y).drop_front(1)) { + for (const int x : IndexRange(size.x).drop_front(1)) { + const float weight = RE_filter_value(type, math::length(float2(x, y) * scale)); + weights[size.x * y + x] = weight; + sum += weight * 4.0f; + } + } + + /* Finally, normalize the weights. */ + for (const int y : IndexRange(size.y)) { + for (const int x : IndexRange(size.x)) { + weights[size.x * y + x] /= sum; + } + } + + texture_ = GPU_texture_create_2d("Weights", size.x, size.y, 1, GPU_R16F, weights.data()); +} + +SymmetricBlurWeights::~SymmetricBlurWeights() +{ + GPU_texture_free(texture_); +} + +void SymmetricBlurWeights::bind_as_texture(GPUShader *shader, const char *texture_name) const +{ + const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + GPU_texture_bind(texture_, texture_image_unit); +} + +void SymmetricBlurWeights::unbind_as_texture() const +{ + GPU_texture_unbind(texture_); +} + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc new file mode 100644 index 00000000000..b8c47d5a5d0 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_separable_blur_weights.cc @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <cstdint> + +#include "BLI_array.hh" +#include "BLI_hash.hh" +#include "BLI_index_range.hh" +#include "BLI_math_base.hh" + +#include "RE_pipeline.h" + +#include "GPU_shader.h" +#include "GPU_texture.h" + +#include "COM_symmetric_separable_blur_weights.hh" + +namespace blender::realtime_compositor { + +/* -------------------------------------------------------------------- + * Symmetric Separable Blur Weights Key. + */ + +SymmetricSeparableBlurWeightsKey::SymmetricSeparableBlurWeightsKey(int type, float radius) + : type(type), radius(radius) +{ +} + +uint64_t SymmetricSeparableBlurWeightsKey::hash() const +{ + return get_default_hash_2(type, radius); +} + +bool operator==(const SymmetricSeparableBlurWeightsKey &a, + const SymmetricSeparableBlurWeightsKey &b) +{ + return a.type == b.type && a.radius == b.radius; +} + +/* -------------------------------------------------------------------- + * Symmetric Separable Blur Weights. + */ + +SymmetricSeparableBlurWeights::SymmetricSeparableBlurWeights(int type, float radius) +{ + /* The size of filter is double the radius plus 1, but since the filter is symmetric, we only + * compute half of it and no doubling happens. We add 1 to make sure the filter size is always + * odd and there is a center weight. */ + const int size = math::ceil(radius) + 1; + Array<float> weights(size); + + float sum = 0.0f; + + /* First, compute the center weight. */ + const float center_weight = RE_filter_value(type, 0.0f); + weights[0] = center_weight; + sum += center_weight; + + /* Second, compute the other weights in the positive direction, making sure to add double the + * weight to the sum of weights because the filter is symmetric and we only loop over half of + * it. Skip the center weight already computed by dropping the front index. */ + const float scale = radius > 0.0f ? 1.0f / radius : 0.0f; + for (const int i : weights.index_range().drop_front(1)) { + const float weight = RE_filter_value(type, i * scale); + weights[i] = weight; + sum += weight * 2.0f; + } + + /* Finally, normalize the weights. */ + for (const int i : weights.index_range()) { + weights[i] /= sum; + } + + texture_ = GPU_texture_create_1d("Weights", size, 1, GPU_R16F, weights.data()); +} + +SymmetricSeparableBlurWeights::~SymmetricSeparableBlurWeights() +{ + GPU_texture_free(texture_); +} + +void SymmetricSeparableBlurWeights::bind_as_texture(GPUShader *shader, + const char *texture_name) const +{ + const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name); + GPU_texture_bind(texture_, texture_image_unit); +} + +void SymmetricSeparableBlurWeights::unbind_as_texture() const +{ + GPU_texture_unbind(texture_); +} + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/intern/context.cc b/source/blender/compositor/realtime_compositor/intern/context.cc index 64ac29af3d1..0b123a2c271 100644 --- a/source/blender/compositor/realtime_compositor/intern/context.cc +++ b/source/blender/compositor/realtime_compositor/intern/context.cc @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "COM_context.hh" +#include "COM_static_cache_manager.hh" #include "COM_static_shader_manager.hh" #include "COM_texture_pool.hh" @@ -17,9 +18,8 @@ int Context::get_frame_number() const float Context::get_time() const { - const float frame_number = static_cast<float>(get_frame_number()); - const float frame_rate = static_cast<float>(get_scene()->r.frs_sec) / - static_cast<float>(get_scene()->r.frs_sec_base); + const float frame_number = float(get_frame_number()); + const float frame_rate = float(get_scene()->r.frs_sec) / float(get_scene()->r.frs_sec_base); return frame_number / frame_rate; } @@ -33,4 +33,9 @@ StaticShaderManager &Context::shader_manager() return shader_manager_; } +StaticCacheManager &Context::cache_manager() +{ + return cache_manager_; +} + } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc index d6bf74ffbee..dd585aedec6 100644 --- a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc @@ -12,9 +12,9 @@ namespace blender::realtime_compositor { -/* ------------------------------------------------------------------------------------------------- - * Conversion Operation. - */ +/* -------------------------------------------------------------------- */ +/** \name Conversion Operation + * \{ */ void ConversionOperation::execute() { @@ -79,9 +79,11 @@ SimpleOperation *ConversionOperation::construct_if_needed(Context &context, return nullptr; } -/* ------------------------------------------------------------------------------------------------- - * Convert Float To Vector Operation. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Float to Vector Operation + * \{ */ ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context) : ConversionOperation(context) @@ -94,7 +96,7 @@ ConvertFloatToVectorOperation::ConvertFloatToVectorOperation(Context &context) void ConvertFloatToVectorOperation::execute_single(const Result &input, Result &output) { - output.set_vector_value(float3(input.get_float_value())); + output.set_vector_value(float4(float3(input.get_float_value()), 0.0f)); } GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const @@ -102,9 +104,11 @@ GPUShader *ConvertFloatToVectorOperation::get_conversion_shader() const return shader_manager().get("compositor_convert_float_to_vector"); } -/* ------------------------------------------------------------------------------------------------- - * Convert Float To Color Operation. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Float to Color Operation + * \{ */ ConvertFloatToColorOperation::ConvertFloatToColorOperation(Context &context) : ConversionOperation(context) @@ -127,9 +131,11 @@ GPUShader *ConvertFloatToColorOperation::get_conversion_shader() const return shader_manager().get("compositor_convert_float_to_color"); } -/* ------------------------------------------------------------------------------------------------- - * Convert Color To Float Operation. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Color to Float Operation + * \{ */ ConvertColorToFloatOperation::ConvertColorToFloatOperation(Context &context) : ConversionOperation(context) @@ -151,9 +157,11 @@ GPUShader *ConvertColorToFloatOperation::get_conversion_shader() const return shader_manager().get("compositor_convert_color_to_float"); } -/* ------------------------------------------------------------------------------------------------- - * Convert Color To Vector Operation. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Color to Vector Operation + * \{ */ ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context) : ConversionOperation(context) @@ -167,7 +175,7 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation(Context &context) void ConvertColorToVectorOperation::execute_single(const Result &input, Result &output) { float4 color = input.get_color_value(); - output.set_vector_value(float3(color)); + output.set_vector_value(float4(float3(color), 0.0f)); } GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const @@ -175,9 +183,11 @@ GPUShader *ConvertColorToVectorOperation::get_conversion_shader() const return shader_manager().get("compositor_convert_color_to_vector"); } -/* ------------------------------------------------------------------------------------------------- - * Convert Vector To Float Operation. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Vector to Float Operation + * \{ */ ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context) : ConversionOperation(context) @@ -190,7 +200,7 @@ ConvertVectorToFloatOperation::ConvertVectorToFloatOperation(Context &context) void ConvertVectorToFloatOperation::execute_single(const Result &input, Result &output) { - float3 vector = input.get_vector_value(); + float4 vector = input.get_vector_value(); output.set_float_value((vector[0] + vector[1] + vector[2]) / 3.0f); } @@ -199,9 +209,11 @@ GPUShader *ConvertVectorToFloatOperation::get_conversion_shader() const return shader_manager().get("compositor_convert_vector_to_float"); } -/* ------------------------------------------------------------------------------------------------- - * Convert Vector To Color Operation. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Convert Vector to Color Operation + * \{ */ ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context) : ConversionOperation(context) @@ -214,7 +226,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation(Context &context) void ConvertVectorToColorOperation::execute_single(const Result &input, Result &output) { - output.set_color_value(float4(input.get_vector_value(), 1.0f)); + output.set_color_value(float4(float3(input.get_vector_value()), 1.0f)); } GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const @@ -222,4 +234,6 @@ GPUShader *ConvertVectorToColorOperation::get_conversion_shader() const return shader_manager().get("compositor_convert_vector_to_color"); } +/** \} */ + } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/intern/evaluator.cc b/source/blender/compositor/realtime_compositor/intern/evaluator.cc index 48457bec199..1cd7d4f8951 100644 --- a/source/blender/compositor/realtime_compositor/intern/evaluator.cc +++ b/source/blender/compositor/realtime_compositor/intern/evaluator.cc @@ -28,6 +28,7 @@ Evaluator::Evaluator(Context &context, bNodeTree &node_tree) void Evaluator::evaluate() { + context_.cache_manager().reset(); context_.texture_pool().reset(); if (!is_compiled_) { diff --git a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc index b3cc86b5f79..99f7cd90557 100644 --- a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc @@ -38,7 +38,7 @@ void InputSingleValueOperation::execute() break; case ResultType::Vector: result.set_vector_value( - float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value)); + float4(float3(bsocket->default_value_typed<bNodeSocketValueVector>()->value), 0.0f)); break; case ResultType::Color: result.set_color_value(float4(bsocket->default_value_typed<bNodeSocketValueRGBA>()->value)); diff --git a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc index 817293c0fa6..e5c448d0e33 100644 --- a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc @@ -38,8 +38,8 @@ void RealizeOnDomainOperation::execute() GPU_shader_bind(shader); /* Transform the input space into the domain space. */ - const float3x3 local_transformation = input.domain().transformation * - domain_.transformation.inverted(); + const float3x3 local_transformation = domain_.transformation.inverted() * + input.domain().transformation; /* Set the origin of the transformation to be the center of the domain. */ const float3x3 transformation = float3x3::from_origin_transformation( diff --git a/source/blender/compositor/realtime_compositor/intern/result.cc b/source/blender/compositor/realtime_compositor/intern/result.cc index 8059367d211..d89f1c86167 100644 --- a/source/blender/compositor/realtime_compositor/intern/result.cc +++ b/source/blender/compositor/realtime_compositor/intern/result.cc @@ -62,7 +62,7 @@ void Result::allocate_invalid() set_float_value(0.0f); break; case ResultType::Vector: - set_vector_value(float3(0.0f)); + set_vector_value(float4(0.0f)); break; case ResultType::Color: set_color_value(float4(0.0f)); @@ -125,7 +125,7 @@ float Result::get_float_value() const return float_value_; } -float3 Result::get_vector_value() const +float4 Result::get_vector_value() const { return vector_value_; } @@ -143,7 +143,7 @@ float Result::get_float_value_default(float default_value) const return default_value; } -float3 Result::get_vector_value_default(const float3 &default_value) const +float4 Result::get_vector_value_default(const float4 &default_value) const { if (is_single_value()) { return get_vector_value(); @@ -165,7 +165,7 @@ void Result::set_float_value(float value) GPU_texture_update(texture_, GPU_DATA_FLOAT, &float_value_); } -void Result::set_vector_value(const float3 &value) +void Result::set_vector_value(const float4 &value) { vector_value_ = value; GPU_texture_update(texture_, GPU_DATA_FLOAT, vector_value_); diff --git a/source/blender/compositor/realtime_compositor/intern/scheduler.cc b/source/blender/compositor/realtime_compositor/intern/scheduler.cc index ac5cc55a73f..0d3cce7af39 100644 --- a/source/blender/compositor/realtime_compositor/intern/scheduler.cc +++ b/source/blender/compositor/realtime_compositor/intern/scheduler.cc @@ -8,6 +8,7 @@ #include "NOD_derived_node_tree.hh" +#include "BKE_node.h" #include "BKE_node_runtime.hh" #include "COM_scheduler.hh" @@ -17,36 +18,103 @@ namespace blender::realtime_compositor { using namespace nodes::derived_node_tree_types; -/* Compute the output node whose result should be computed. The output node is the node marked as - * NODE_DO_OUTPUT. If multiple types of output nodes are marked, then the preference will be - * CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. If no output node exists, a null - * node will be returned. */ -static DNode compute_output_node(DerivedNodeTree &tree) +/* Find the active context from the given context and its descendants contexts. The active context + * is the one whose node instance key matches the active_viewer_key stored in the root node tree. + * The instance key of each context is computed by calling BKE_node_instance_key given the key of + * the parent as well as the group node making the context. */ +static const DTreeContext *find_active_context_recursive(const DTreeContext *context, + bNodeInstanceKey key) { - const bNodeTree &root_tree = tree.root_context().btree(); + /* The instance key of the given context matches the active viewer instance key, so this is the + * active context, return it. */ + if (key.value == context->derived_tree().root_context().btree().active_viewer_key.value) { + return context; + } + + /* For each of the group nodes, compute their instance key and contexts and call this function + * recursively. */ + for (const bNode *group_node : context->btree().group_nodes()) { + const bNodeInstanceKey child_key = BKE_node_instance_key(key, &context->btree(), group_node); + const DTreeContext *child_context = context->child_context(*group_node); + const DTreeContext *found_context = find_active_context_recursive(child_context, child_key); + + /* If the found context is null, that means neither the child context nor one of its descendant + * contexts is active. */ + if (!found_context) { + continue; + } + + /* Otherwise, we have found our active context, return it. */ + return found_context; + } + + /* Neither the given context nor one of its descendant contexts is active, so return null. */ + return nullptr; +} + +/* Find the active context for the given node tree. The active context represents the node tree + * currently being edited. In most cases, that would be the top level node tree itself, but in the + * case where the user is editing the node tree of a node group, the active context would be a + * representation of the node tree of that node group. Note that the context also stores the group + * node that the user selected to edit the node tree, so the context fully represents a particular + * instance of the node group. */ +static const DTreeContext *find_active_context(const DerivedNodeTree &tree) +{ + /* The root context has an instance key of NODE_INSTANCE_KEY_BASE by definition. */ + return find_active_context_recursive(&tree.root_context(), NODE_INSTANCE_KEY_BASE); +} + +/* Return the output node which is marked as NODE_DO_OUTPUT. If multiple types of output nodes are + * marked, then the preference will be CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. + * If no output node exists, a null node will be returned. */ +static DNode find_output_in_context(const DTreeContext *context) +{ + const bNodeTree &tree = context->btree(); - for (const bNode *node : root_tree.nodes_by_type("CompositorNodeComposite")) { + for (const bNode *node : tree.nodes_by_type("CompositorNodeComposite")) { if (node->flag & NODE_DO_OUTPUT) { - return DNode(&tree.root_context(), node); + return DNode(context, node); } } - for (const bNode *node : root_tree.nodes_by_type("CompositorNodeViewer")) { + for (const bNode *node : tree.nodes_by_type("CompositorNodeViewer")) { if (node->flag & NODE_DO_OUTPUT) { - return DNode(&tree.root_context(), node); + return DNode(context, node); } } - for (const bNode *node : root_tree.nodes_by_type("CompositorNodeSplitViewer")) { + for (const bNode *node : tree.nodes_by_type("CompositorNodeSplitViewer")) { if (node->flag & NODE_DO_OUTPUT) { - return DNode(&tree.root_context(), node); + return DNode(context, node); } } - /* No output node found, return a null node. */ return DNode(); } +/* Compute the output node whose result should be computed. This node is the output node that + * satisfies the requirements in the find_output_in_context function. First, the active context is + * searched for an output node, if non was found, the root context is search. For more information + * on what contexts mean here, see the find_active_context function. */ +static DNode compute_output_node(const DerivedNodeTree &tree) +{ + const DTreeContext *active_context = find_active_context(tree); + + const DNode node = find_output_in_context(active_context); + if (node) { + return node; + } + + /* If the active context is the root one and no output node was found, we consider this node tree + * to have no output node, even if one of the non-active descendants have an output node. */ + if (active_context->is_root()) { + return DNode(); + } + + /* The active context doesn't have an output node, search in the root context as a fallback. */ + return find_output_in_context(&tree.root_context()); +} + /* A type representing a mapping that associates each node with a heuristic estimation of the * number of intermediate buffers needed to compute it and all of its dependencies. See the * compute_number_of_needed_buffers function for more information. */ @@ -225,7 +293,7 @@ static NeededBuffers compute_number_of_needed_buffers(DNode output_node) * doesn't always guarantee an optimal evaluation order, as the optimal evaluation order is very * difficult to compute, however, this method works well in most cases. Moreover it assumes that * all buffers will have roughly the same size, which may not always be the case. */ -Schedule compute_schedule(DerivedNodeTree &tree) +Schedule compute_schedule(const DerivedNodeTree &tree) { Schedule schedule; diff --git a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc index 8e52baf63ec..88efdae1872 100644 --- a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc @@ -273,7 +273,7 @@ static const char *get_store_function_name(ResultType type) void ShaderOperation::populate_operation_result(DOutputSocket output_socket, GPUMaterial *material) { - const unsigned int output_id = output_sockets_to_output_identifiers_map_.size(); + const uint output_id = output_sockets_to_output_identifiers_map_.size(); std::string output_identifier = "output" + std::to_string(output_id); const ResultType result_type = get_node_socket_result_type(output_socket.bsocket()); diff --git a/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc new file mode 100644 index 00000000000..da78412a815 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <memory> + +#include "BLI_math_vec_types.hh" + +#include "COM_morphological_distance_feather_weights.hh" +#include "COM_symmetric_blur_weights.hh" +#include "COM_symmetric_separable_blur_weights.hh" + +#include "COM_static_cache_manager.hh" + +namespace blender::realtime_compositor { + +/* -------------------------------------------------------------------- + * Static Cache Manager. + */ + +void StaticCacheManager::reset() +{ + /* First, delete all resources that are no longer needed. */ + symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; }); + symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; }); + morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; }); + + /* Second, reset the needed status of the remaining resources to false to ready them to track + * their needed status for the next evaluation. */ + for (auto &value : symmetric_blur_weights_.values()) { + value->needed = false; + } + for (auto &value : symmetric_separable_blur_weights_.values()) { + value->needed = false; + } + for (auto &value : morphological_distance_feather_weights_.values()) { + value->needed = false; + } +} + +SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius) +{ + const SymmetricBlurWeightsKey key(type, radius); + + auto &weights = *symmetric_blur_weights_.lookup_or_add_cb( + key, [&]() { return std::make_unique<SymmetricBlurWeights>(type, radius); }); + + weights.needed = true; + return weights; +} + +SymmetricSeparableBlurWeights &StaticCacheManager::get_symmetric_separable_blur_weights( + int type, float radius) +{ + const SymmetricSeparableBlurWeightsKey key(type, radius); + + auto &weights = *symmetric_separable_blur_weights_.lookup_or_add_cb( + key, [&]() { return std::make_unique<SymmetricSeparableBlurWeights>(type, radius); }); + + weights.needed = true; + return weights; +} + +MorphologicalDistanceFeatherWeights &StaticCacheManager:: + get_morphological_distance_feather_weights(int type, int radius) +{ + const MorphologicalDistanceFeatherWeightsKey key(type, radius); + + auto &weights = *morphological_distance_feather_weights_.lookup_or_add_cb( + key, [&]() { return std::make_unique<MorphologicalDistanceFeatherWeights>(type, radius); }); + + weights.needed = true; + return weights; +} + +} // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc index 1568970a030..4b476574d72 100644 --- a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc +++ b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc @@ -13,9 +13,9 @@ namespace blender::realtime_compositor { -/* -------------------------------------------------------------------- - * Texture Pool Key. - */ +/* -------------------------------------------------------------------- */ +/** \name Texture Pool Key + * \{ */ TexturePoolKey::TexturePoolKey(int2 size, eGPUTextureFormat format) : size(size), format(format) { @@ -37,9 +37,11 @@ bool operator==(const TexturePoolKey &a, const TexturePoolKey &b) return a.size == b.size && a.format == b.format; } -/* -------------------------------------------------------------------- - * Texture Pool. - */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Texture Pool + * \{ */ GPUTexture *TexturePool::acquire(int2 size, eGPUTextureFormat format) { @@ -62,7 +64,7 @@ GPUTexture *TexturePool::acquire_color(int2 size) GPUTexture *TexturePool::acquire_vector(int2 size) { - /* Vectors are stored in RGBA textures because RGB textures have limited support. */ + /* Vectors are 4D, and are thus stored in RGBA textures. */ return acquire(size, GPU_RGBA16F); } @@ -81,4 +83,6 @@ void TexturePool::reset() textures_.clear(); } +/** \} */ + } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/intern/utilities.cc b/source/blender/compositor/realtime_compositor/intern/utilities.cc index 1a5823b8441..25472d6ed50 100644 --- a/source/blender/compositor/realtime_compositor/intern/utilities.cc +++ b/source/blender/compositor/realtime_compositor/intern/utilities.cc @@ -71,7 +71,7 @@ bool is_output_linked_to_node_conditioned(DOutputSocket output, FunctionRef<bool { bool condition_satisfied = false; output.foreach_target_socket( - [&](DInputSocket target, const TargetSocketPathInfo &UNUSED(path_info)) { + [&](DInputSocket target, const TargetSocketPathInfo & /*path_info*/) { if (condition(target.node())) { condition_satisfied = true; return; @@ -85,7 +85,7 @@ int number_of_inputs_linked_to_output_conditioned(DOutputSocket output, { int count = 0; output.foreach_target_socket( - [&](DInputSocket target, const TargetSocketPathInfo &UNUSED(path_info)) { + [&](DInputSocket target, const TargetSocketPathInfo & /*path_info*/) { if (condition(target)) { count++; } diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl new file mode 100644 index 00000000000..d55c8efd4c6 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_alpha_crop.glsl @@ -0,0 +1,11 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + /* The lower bound is inclusive and upper bound is exclusive. */ + bool is_inside = all(greaterThanEqual(texel, lower_bound)) && all(lessThan(texel, upper_bound)); + /* Write the pixel color if it is inside the cropping region, otherwise, write zero. */ + vec4 color = is_inside ? texture_load(input_tx, texel) : vec4(0.0); + imageStore(output_img, texel, color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl new file mode 100644 index 00000000000..c7c5ada7a9f --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_bilateral_blur.glsl @@ -0,0 +1,31 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec4 center_determinator = texture_load(determinator_tx, texel); + + /* Go over the pixels in the blur window of the specified radius around the center pixel, and for + * pixels whose determinator is close enough to the determinator of the center pixel, accumulate + * their color as well as their weights. */ + float accumulated_weight = 0.0; + vec4 accumulated_color = vec4(0.0); + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + vec4 determinator = texture_load(determinator_tx, texel + ivec2(x, y)); + float difference = dot(abs(center_determinator - determinator).rgb, vec3(1.0)); + + if (difference < threshold) { + accumulated_weight += 1.0; + accumulated_color += texture_load(input_tx, texel + ivec2(x, y)); + } + } + } + + /* Write the accumulated color divided by the accumulated weight if any pixel in the window was + * accumulated, otherwise, write a fallback black color. */ + vec4 fallback = vec4(vec3(0.0), 1.0); + vec4 color = (accumulated_weight != 0.0) ? (accumulated_color / accumulated_weight) : fallback; + imageStore(output_img, texel, color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl new file mode 100644 index 00000000000..c7ac620f99b --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl @@ -0,0 +1,66 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +vec4 load_input(ivec2 texel) +{ + vec4 color; + if (extend_bounds) { + /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So + * we load the input with an offset by the radius amount and fallback to a transparent color if + * it is out of bounds. */ + color = texture_load(input_tx, texel - radius, vec4(0.0)); + } + else { + color = texture_load(input_tx, texel); + } + + return color; +} + +/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from + * the weights texture, where the given texel (0, 0) corresponds the center of weights texture. + * Note that we load the weights texture inverted along both directions to maintain the shape of + * the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D + * weights texture whose right half is all ones and whose left half is all zeros. Further, consider + * that we are blurring a single white pixel on a black background. When computing the value of a + * pixel that is to the right of the white pixel, the white pixel will be in the left region of the + * search window, and consequently, without inversion, a zero will be sampled from the left side of + * the weights texture and result will be zero. However, what we expect is that pixels to the right + * of the white pixel will be white, that is, they should sample a weight of 1 from the right side + * of the weights texture, hence the need for inversion. */ +vec4 load_weight(ivec2 texel) +{ + /* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5 + * to sample at the center of the pixels, then divide by the upper bound plus one to transform + * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally, + * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as + * mentioned in the function description. */ + return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1))); +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* The mask input is treated as a boolean. If it is zero, then no blurring happens for this + * pixel. Otherwise, the pixel is blurred normally and the mask value is irrelevant. */ + float mask = texture_load(mask_tx, texel).x; + if (mask == 0.0) { + imageStore(output_img, texel, texture_load(input_tx, texel)); + return; + } + + /* Go over the window of the given radius and accumulate the colors multiplied by their + * respective weights as well as the weights themselves. */ + vec4 accumulated_color = vec4(0.0); + vec4 accumulated_weight = vec4(0.0); + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + vec4 weight = load_weight(ivec2(x, y)); + accumulated_color += load_input(texel + ivec2(x, y)) * weight; + accumulated_weight += weight; + } + } + + imageStore(output_img, texel, safe_divide(accumulated_color, accumulated_weight)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl new file mode 100644 index 00000000000..9383bbf9825 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl @@ -0,0 +1,71 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from + * the weights texture, where the given texel (0, 0) corresponds the center of weights texture. + * Note that we load the weights texture inverted along both directions to maintain the shape of + * the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D + * weights texture whose right half is all ones and whose left half is all zeros. Further, consider + * that we are blurring a single white pixel on a black background. When computing the value of a + * pixel that is to the right of the white pixel, the white pixel will be in the left region of the + * search window, and consequently, without inversion, a zero will be sampled from the left side of + * the weights texture and result will be zero. However, what we expect is that pixels to the right + * of the white pixel will be white, that is, they should sample a weight of 1 from the right side + * of the weights texture, hence the need for inversion. */ +vec4 load_weight(ivec2 texel, float radius) +{ + /* The center zero texel is always assigned a unit weight regardless of the corresponding weight + * in the weights texture. That's to guarantee that at last the center pixel will be accumulated + * even if the weights texture is zero at its center. */ + if (texel == ivec2(0)) { + return vec4(1.0); + } + + /* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5 + * to sample at the center of the pixels, then divide by the upper bound plus one to transform + * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally, + * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as + * mentioned in the function description. */ + return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1))); +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* The mask input is treated as a boolean. If it is zero, then no blurring happens for this + * pixel. Otherwise, the pixel is blurred normally and the mask value is irrelevant. */ + float mask = texture_load(mask_tx, texel).x; + if (mask == 0.0) { + imageStore(output_img, texel, texture_load(input_tx, texel)); + return; + } + + float center_size = texture_load(size_tx, texel).x * base_size; + + /* Go over the window of the given search radius and accumulate the colors multiplied by their + * respective weights as well as the weights themselves, but only if both the size of the center + * pixel and the size of the candidate pixel are less than both the x and y distances of the + * candidate pixel. */ + vec4 accumulated_color = vec4(0.0); + vec4 accumulated_weight = vec4(0.0); + for (int y = -search_radius; y <= search_radius; y++) { + for (int x = -search_radius; x <= search_radius; x++) { + float candidate_size = texture_load(size_tx, texel + ivec2(x, y)).x * base_size; + + /* Skip accumulation if either the x or y distances of the candidate pixel are larger than + * either the center or candidate pixel size. Note that the max and min functions here denote + * "either" in the aforementioned description. */ + float size = min(center_size, candidate_size); + if (max(abs(x), abs(y)) > size) { + continue; + } + + vec4 weight = load_weight(ivec2(x, y), size); + accumulated_color += texture_load(input_tx, texel + ivec2(x, y)) * weight; + accumulated_weight += weight; + } + } + + imageStore(output_img, texel, safe_divide(accumulated_color, accumulated_weight)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl new file mode 100644 index 00000000000..6e98aa9fe17 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_bokeh_image.glsl @@ -0,0 +1,118 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* Get the 2D vertex position of the vertex with the given index in the regular polygon + * representing this bokeh. The polygon is rotated by the rotation amount and have a unit + * circumradius. The regular polygon is one whose vertices' exterior angles are given by + * exterior_angle. See the bokeh function for more information. */ +vec2 get_regular_polygon_vertex_position(int vertex_index) +{ + float angle = exterior_angle * vertex_index - rotation; + return vec2(cos(angle), sin(angle)); +} + +/* Find the closest point to the given point on the given line. This assumes the length of the + * given line is not zero. */ +vec2 closest_point_on_line(vec2 point, vec2 line_start, vec2 line_end) +{ + vec2 line_vector = line_end - line_start; + vec2 point_vector = point - line_start; + float line_length_squared = dot(line_vector, line_vector); + float parameter = dot(point_vector, line_vector) / line_length_squared; + return line_start + line_vector * parameter; +} + +/* Compute the value of the bokeh at the given point. The computed bokeh is essentially a regular + * polygon centered in space having the given circumradius. The regular polygon is one whose + * vertices' exterior angles are given by "exterior_angle", which relates to the number of vertices + * n through the equation "exterior angle = 2 pi / n". The regular polygon may additionally morph + * into a shape with the given properties: + * + * - The regular polygon may have a circular hole in its center whose radius is controlled by the + * "catadioptric" value. + * - The regular polygon is rotated by the "rotation" value. + * - The regular polygon can morph into a circle controlled by the "roundness" value, such that it + * becomes a full circle at unit roundness. + * + * The function returns 0 when the point lies inside the regular polygon and 1 otherwise. However, + * at the edges, it returns a narrow band gradient as a form of anti-aliasing. */ +float bokeh(vec2 point, float circumradius) +{ + /* Get the index of the vertex of the regular polygon whose polar angle is maximum but less than + * the polar angle of the given point, taking rotation into account. This essentially finds the + * vertex closest to the given point in the clock-wise direction. */ + float angle = mod(atan(point.y, point.x) + rotation, M_2PI); + int vertex_index = int(angle / exterior_angle); + + /* Compute the shortest distance between the origin and the polygon edge composed from the + * previously selected vertex and the one following it. */ + vec2 first_vertex = get_regular_polygon_vertex_position(vertex_index) * circumradius; + vec2 second_vertex = get_regular_polygon_vertex_position(vertex_index + 1) * circumradius; + vec2 closest_point = closest_point_on_line(point, first_vertex, second_vertex); + float distance_to_edge = length(closest_point); + + /* Mix the distance to the edge with the circumradius, making it tend to the distance to a + * circle when roundness tends to 1. */ + float distance_to_edge_round = mix(distance_to_edge, circumradius, roundness); + + /* The point is outside of the bokeh, so we return 0. */ + float distance = length(point); + if (distance > distance_to_edge_round) { + return 0.0; + } + + /* The point is inside the catadioptric hole and is not part of the bokeh, so we return 0. */ + float catadioptric_distance = distance_to_edge_round * catadioptric; + if (distance < catadioptric_distance) { + return 0.0; + } + + /* The point is very close to the edge of the bokeh, so we return the difference between the + * distance to the edge and the distance as a form of anti-aliasing. */ + if (distance_to_edge_round - distance < 1.0) { + return distance_to_edge_round - distance; + } + + /* The point is very close to the edge of the catadioptric hole, so we return the difference + * between the distance to the hole and the distance as a form of anti-aliasing. */ + if (catadioptric != 0.0 && distance - catadioptric_distance < 1.0) { + return distance - catadioptric_distance; + } + + /* Otherwise, the point is part of the bokeh and we return 1. */ + return 1.0; +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Since we need the regular polygon to occupy the entirety of the output image, the circumradius + * of the regular polygon is half the width of the output image. */ + float circumradius = float(imageSize(output_img).x) / 2.0; + + /* Move the texel coordinates such that the regular polygon is centered. */ + vec2 point = vec2(texel) - circumradius; + + /* Each of the color channels of the output image contains a bokeh with a different circumradius. + * The largest one occupies the whole image as stated above, while the other two have circumradii + * that are shifted by an amount that is proportional to the "lens_shift" value. The alpha + * channel of the output is the average of all three values. */ + float min_shift = abs(lens_shift * circumradius); + float min = mix(bokeh(point, circumradius - min_shift), 0.0, min_shift == circumradius); + + float median_shift = min_shift / 2.0; + float median = bokeh(point, circumradius - median_shift); + + float max = bokeh(point, circumradius); + vec4 bokeh = vec4(min, median, max, (max + median + min) / 3.0); + + /* If the lens shift is negative, swap the min and max bokeh values, which are stored in the red + * and blue channels respectively. Note that we take the absolute value of the lens shift above, + * so the sign of the lens shift only controls this swap. */ + if (lens_shift < 0) { + bokeh = bokeh.zyxw; + } + + imageStore(output_img, texel, bokeh); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl new file mode 100644 index 00000000000..fad23f28fde --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_box_mask.glsl @@ -0,0 +1,27 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec2 uv = vec2(texel) / vec2(domain_size - ivec2(1)); + uv -= location; + uv.y *= float(domain_size.y) / float(domain_size.x); + uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv; + bool is_inside = all(lessThan(abs(uv), size)); + + float base_mask_value = texture_load(base_mask_tx, texel).x; + float value = texture_load(mask_value_tx, texel).x; + +#if defined(CMP_NODE_MASKTYPE_ADD) + float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value; +#elif defined(CMP_NODE_MASKTYPE_SUBTRACT) + float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value; +#elif defined(CMP_NODE_MASKTYPE_MULTIPLY) + float output_mask_value = is_inside ? base_mask_value * value : 0.0; +#elif defined(CMP_NODE_MASKTYPE_NOT) + float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value; +#endif + + imageStore(output_mask_img, texel, vec4(output_mask_value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl new file mode 100644 index 00000000000..044fb057ca5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_convert.glsl @@ -0,0 +1,8 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec4 value = texture_load(input_tx, texel); + imageStore(output_img, texel, CONVERT_EXPRESSION(value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl new file mode 100644 index 00000000000..e4743d69d17 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_despeckle.glsl @@ -0,0 +1,70 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* Returns true if the given color is close enough to the given reference color within the + * threshold supplied by the user, and returns false otherwise. */ +bool is_close(vec4 reference_color, vec4 color) +{ + return all(lessThan(abs(reference_color - color).rgb, vec3(threshold))); +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* A 3x3 weights kernel whose weights are the inverse of the distance to the center of the + * kernel. So the center weight is zero, the corners weights are (1 / sqrt(2)), and the rest + * of the weights are 1. The total sum of weights is 4 plus quadruple the corner weight. */ + float corner_weight = 1.0 / sqrt(2.0); + float sum_of_weights = 4.0 + corner_weight * 4.0; + mat3 weights = mat3(vec3(corner_weight, 1.0, corner_weight), + vec3(1.0, 0.0, 1.0), + vec3(corner_weight, 1.0, corner_weight)); + + vec4 center_color = texture_load(input_tx, texel); + + /* Go over the pixels in the 3x3 window around the center pixel and compute the total sum of + * their colors multiplied by their weights. Additionally, for pixels whose colors are not close + * enough to the color of the center pixel, accumulate their color as well as their weights. */ + vec4 sum_of_colors = vec4(0); + float accumulated_weight = 0.0; + vec4 accumulated_color = vec4(0); + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + float weight = weights[j][i]; + vec4 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * weight; + sum_of_colors += color; + if (!is_close(center_color, color)) { + accumulated_color += color; + accumulated_weight += weight; + } + } + } + + /* If the accumulated weight is zero, that means all pixels in the 3x3 window are similar and no + * need to despeckle anything, so write the original center color and return. */ + if (accumulated_weight == 0.0) { + imageStore(output_img, texel, center_color); + return; + } + + /* If the ratio between the accumulated weights and the total sum of weights is not larger than + * the user specified neighbor threshold, then the number of pixels in the neighborhood that are + * not close enough to the center pixel is low, and no need to despeckle anything, so write the + * original center color and return. */ + if (accumulated_weight / sum_of_weights < neighbor_threshold) { + imageStore(output_img, texel, center_color); + return; + } + + /* If the weighted average color of the neighborhood is close enough to the center pixel, then no + * need to despeckle anything, so write the original center color and return. */ + if (is_close(center_color, sum_of_colors / sum_of_weights)) { + imageStore(output_img, texel, center_color); + return; + } + + /* We need to despeckle, so write the mean accumulated color. */ + float factor = texture_load(factor_tx, texel).x; + vec4 mean_color = accumulated_color / accumulated_weight; + imageStore(output_img, texel, mix(center_color, mean_color, factor)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl new file mode 100644 index 00000000000..1805cb5a7f5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl @@ -0,0 +1,21 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + ivec2 input_size = texture_size(input_tx); + + /* Add 0.5 to evaluate the input sampler at the center of the pixel. */ + vec2 coordinates = vec2(texel) + vec2(0.5); + + /* For each iteration, accumulate the input at the normalize coordinates, hence the divide by + * input size, then transform the coordinates for the next iteration. */ + vec4 accumulated_color = vec4(0.0); + for (int i = 0; i < iterations; i++) { + accumulated_color += texture(input_tx, coordinates / input_size); + coordinates = (mat3(inverse_transformation) * vec3(coordinates, 1.0)).xy; + } + + /* Write the accumulated color divided by the number of iterations. */ + imageStore(output_img, texel, accumulated_color / iterations); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl new file mode 100644 index 00000000000..67e27c22602 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl @@ -0,0 +1,31 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Compute the dot product between the 3x3 window around the pixel and the edge detection kernel + * in the X direction and Y direction. The Y direction kernel is computed by transposing the + * given X direction kernel. */ + vec3 color_x = vec3(0); + vec3 color_y = vec3(0); + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + vec3 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)).rgb; + color_x += color * kernel[j][i]; + color_y += color * kernel[i][j]; + } + } + + /* Compute the channel-wise magnitude of the 2D vector composed from the X and Y edge detection + * filter results. */ + vec3 magnitude = sqrt(color_x * color_x + color_y * color_y); + + /* Mix the channel-wise magnitude with the original color at the center of the kernel using the + * input factor. */ + vec4 color = texture_load(input_tx, texel); + magnitude = mix(color.rgb, magnitude, texture_load(factor_tx, texel).x); + + /* Store the channel-wise magnitude with the original alpha of the input. */ + imageStore(output_img, texel, vec4(magnitude, color.a)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl new file mode 100644 index 00000000000..28f725067e0 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_ellipse_mask.glsl @@ -0,0 +1,27 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec2 uv = vec2(texel) / vec2(domain_size - ivec2(1)); + uv -= location; + uv.y *= float(domain_size.y) / float(domain_size.x); + uv = mat2(cos_angle, -sin_angle, sin_angle, cos_angle) * uv; + bool is_inside = length(uv / radius) < 1.0; + + float base_mask_value = texture_load(base_mask_tx, texel).x; + float value = texture_load(mask_value_tx, texel).x; + +#if defined(CMP_NODE_MASKTYPE_ADD) + float output_mask_value = is_inside ? max(base_mask_value, value) : base_mask_value; +#elif defined(CMP_NODE_MASKTYPE_SUBTRACT) + float output_mask_value = is_inside ? clamp(base_mask_value - value, 0.0, 1.0) : base_mask_value; +#elif defined(CMP_NODE_MASKTYPE_MULTIPLY) + float output_mask_value = is_inside ? base_mask_value * value : 0.0; +#elif defined(CMP_NODE_MASKTYPE_NOT) + float output_mask_value = is_inside ? (base_mask_value > 0.0 ? 0.0 : value) : base_mask_value; +#endif + + imageStore(output_mask_img, texel, vec4(output_mask_value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl new file mode 100644 index 00000000000..e501c563dda --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl @@ -0,0 +1,20 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Compute the dot product between the 3x3 window around the pixel and the filter kernel. */ + vec4 color = vec4(0); + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + color += texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * kernel[j][i]; + } + } + + /* Mix with the original color at the center of the kernel using the input factor. */ + color = mix(texture_load(input_tx, texel), color, texture_load(factor_tx, texel).x); + + /* Store the color making sure it is not negative. */ + imageStore(output_img, texel, max(color, 0.0)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl new file mode 100644 index 00000000000..919c454ee63 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_flip.glsl @@ -0,0 +1,15 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + ivec2 size = texture_size(input_tx); + ivec2 flipped_texel = texel; + if (flip_x) { + flipped_texel.x = size.x - texel.x - 1; + } + if (flip_y) { + flipped_texel.y = size.y - texel.y - 1; + } + imageStore(output_img, texel, texture_load(input_tx, flipped_texel)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl new file mode 100644 index 00000000000..f20e033dee4 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_image_crop.glsl @@ -0,0 +1,7 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + imageStore(output_img, texel, texture_load(input_tx, texel + lower_bound)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl new file mode 100644 index 00000000000..09f896b7a9d --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance.glsl @@ -0,0 +1,24 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Find the minimum/maximum value in the circular window of the given radius around the pixel. By + * circular window, we mean that pixels in the window whose distance to the center of window is + * larger than the given radius are skipped and not considered. Consequently, the dilation or + * erosion that take place produces round results as opposed to squarish ones. This is + * essentially a morphological operator with a circular structuring element. The LIMIT value + * should be FLT_MAX if OPERATOR is min and FLT_MIN if OPERATOR is max. */ + float value = LIMIT; + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + if (x * x + y * y <= radius * radius) { + value = OPERATOR(value, texture_load(input_tx, texel + ivec2(x, y), vec4(LIMIT)).x); + } + } + } + + imageStore(output_img, texel, vec4(value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl new file mode 100644 index 00000000000..acdd8a40342 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_feather.glsl @@ -0,0 +1,101 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* The Morphological Distance Feather operation is a linear combination between the result of two + * operations. The first operation is a Gaussian blur with a radius equivalent to the dilate/erode + * distance, which is straightforward and implemented as a separable filter similar to the blur + * operation. + * + * The second operation is an approximation of a morphological inverse distance operation evaluated + * at a distance falloff function. The result of a morphological inverse distance operation is a + * narrow band distance field that starts at its maximum value at boundaries where a difference in + * values took place and linearly deceases until it reaches zero in the span of a number of pixels + * equivalent to the erode/dilate distance. Additionally, instead of linearly decreasing, the user + * may choose a different falloff which is evaluated at the computed distance. For dilation, the + * distance field decreases outwards, and for erosion, the distance field decreased inwards. + * + * The reason why the result of a Gaussian blur is mixed in with the distance field is because the + * distance field is merely approximated and not accurately computed, the defects of which is more + * apparent away from boundaries and especially at corners where the distance field should take a + * circular shape. That's why the Gaussian blur is mostly mixed only further from boundaries. + * + * The morphological inverse distance operation is approximated using a separable implementation + * and intertwined with the Gaussian blur implementation as follows. A search window of a radius + * equivalent to the dilate/erode distance is applied on the image to find either the minimum or + * maximum pixel value multiplied by its corresponding falloff value in the window. For dilation, + * we try to find the maximum, and for erosion, we try to find the minimum. Additionally, we also + * save the falloff value where the minimum or maximum was found. The found value will be that of + * the narrow band distance field and the saved falloff value will be used as the mixing factor + * with the Gaussian blur. + * + * To make sense of the aforementioned algorithm, assume we are dilating a binary image by 5 pixels + * whose half has a value of 1 and the other half has a value of zero. Consider the following: + * + * - A pixel of value 1 already has the maximum possible value, so its value will remain unchanged + * regardless of its position. + * - A pixel of value 0 that is right at the boundary of the 1's region will have a maximum value + * of around 0.8 depending on the falloff. That's because the search window intersects the 1's + * region, which when multiplied by the falloff gives the first value of the falloff, which is + * larger than the initially zero value computed at the center of the search window. + * - A pixel of value 0 that is 3 pixels away from the boundary will have a maximum value of around + * 0.4 depending on the falloff. That's because the search window intersects the 1's region, + * which when multiplied by the falloff gives the third value of the falloff, which is larger + * than the initially zero value computed at the center of the search window. + * - Finally, a pixel of value 0 that is 6 pixels away from the boundary will have a maximum value + * of 0, because the search window doesn't intersects the 1's region and only spans zero values. + * + * The previous example demonstrates how the distance field naturally arises, and the same goes for + * the erode case, except the minimum value is computed instead. + */ +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* A value for accumulating the blur result. */ + float accumulated_value = 0.0; + + /* Compute the contribution of the center pixel to the blur result. */ + float center_value = texture_load(input_tx, texel).x; + accumulated_value += center_value * texture_load(weights_tx, 0).x; + + /* Start with the center value as the maximum/minimum distance and reassign to the true maximum + * or minimum in the search loop below. Additionally, the center falloff is always 1.0, so start + * with that. */ + float limit_distance = center_value; + float limit_distance_falloff = 1.0; + + /* Compute the contributions of the pixels to the right and left, noting that the weights and + * falloffs textures only store the weights and falloffs for the positive half, but since the + * they are both symmetric, the same weights and falloffs are used for the negative half and we + * compute both of their contributions. */ + for (int i = 1; i < texture_size(weights_tx); i++) { + float weight = texture_load(weights_tx, i).x; + float falloff = texture_load(falloffs_tx, i).x; + + /* Loop for two iterations, where s takes the value of -1 and 1, which is used as the sign + * needed to evaluated the positive and negative sides as explain above. */ + for (int s = -1; s < 2; s += 2) { + /* Compute the contribution of the pixel to the blur result. */ + float value = texture_load(input_tx, texel + ivec2(s * i, 0)).x; + accumulated_value += value * weight; + + /* The distance is computed such that its highest value is the pixel value itself, so + * multiply the distance falloff by the pixel value. */ + float falloff_distance = value * falloff; + + /* Find either the maximum or the minimum for the dilate and erode cases respectively. */ + if (COMPARE(falloff_distance, limit_distance)) { + limit_distance = falloff_distance; + limit_distance_falloff = falloff; + } + } + } + + /* Mix between the limit distance and the blurred accumulated value such that the limit distance + * is used for pixels closer to the boundary and the blurred value is used for pixels away from + * the boundary. */ + float value = mix(accumulated_value, limit_distance, limit_distance_falloff); + + /* Write the value using the transposed texel. See the execute_distance_feather_horizontal_pass + * method for more information on the rational behind this. */ + imageStore(output_img, texel.yx, vec4(value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl new file mode 100644 index 00000000000..e6625e7419f --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl @@ -0,0 +1,88 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* The Morphological Distance Threshold operation is effectively three consecutive operations + * implemented as a single operation. The three operations are as follows: + * + * .-----------. .--------------. .----------------. + * | Threshold |-->| Dilate/Erode |-->| Distance Inset | + * '-----------' '--------------' '----------------' + * + * The threshold operation just converts the input into a binary image, where the pixel is 1 if it + * is larger than 0.5 and 0 otherwise. Pixels that are 1 in the output of the threshold operation + * are said to be masked. The dilate/erode operation is a dilate or erode morphological operation + * with a circular structuring element depending on the sign of the distance, where it is a dilate + * operation if the distance is positive and an erode operation otherwise. This is equivalent to + * the Morphological Distance operation, see its implementation for more information. Finally, the + * distance inset is an operation that converts the binary image into a narrow band distance field. + * That is, pixels that are unmasked will remain 0, while pixels that are masked will start from + * zero at the boundary of the masked region and linearly increase until reaching 1 in the span of + * a number pixels given by the inset value. + * + * As a performance optimization, the dilate/erode operation is omitted and its effective result is + * achieved by slightly adjusting the distance inset operation. The base distance inset operation + * works by computing the signed distance from the current center pixel to the nearest pixel with a + * different value. Since our image is a binary image, that means that if the pixel is masked, we + * compute the signed distance to the nearest unmasked pixel, and if the pixel unmasked, we compute + * the signed distance to the nearest masked pixel. The distance is positive if the pixel is masked + * and negative otherwise. The distance is then normalized by dividing by the given inset value and + * clamped to the [0, 1] range. Since distances larger than the inset value are eventually clamped, + * the distance search window is limited to a radius equivalent to the inset value. + * + * To archive the effective result of the omitted dilate/erode operation, we adjust the distance + * inset operation as follows. First, we increase the radius of the distance search window by the + * radius of the dilate/erode operation. Then we adjust the resulting narrow band signed distance + * field as follows. + * + * For the erode case, we merely subtract the erode distance, which makes the outermost erode + * distance number of pixels zero due to clamping, consequently achieving the result of the erode, + * while retaining the needed inset because we increased the distance search window by the same + * amount we subtracted. + * + * Similarly, for the dilate case, we add the dilate distance, which makes the dilate distance + * number of pixels just outside of the masked region positive and part of the narrow band distance + * field, consequently achieving the result of the dilate, while at the same time, the innermost + * dilate distance number of pixels become 1 due to clamping, retaining the needed inset because we + * increased the distance search window by the same amount we added. + * + * Since the erode/dilate distance is already signed appropriately as described before, we just add + * it in both cases. */ +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Apply a threshold operation on the center pixel, where the threshold is currently hard-coded + * at 0.5. The pixels with values larger than the threshold are said to be masked. */ + bool is_center_masked = texture_load(input_tx, texel).x > 0.5; + + /* Since the distance search window will access pixels outside of the bounds of the image, we use + * a texture loader with a fallback value. And since we don't want those values to affect the + * result, the fallback value is chosen such that the inner condition fails, which is when the + * sampled pixel and the center pixel are the same, so choose a fallback that will be considered + * masked if the center pixel is masked and unmasked otherwise. */ + vec4 fallback = vec4(is_center_masked ? 1.0 : 0.0); + + /* Since the distance search window is limited to the given radius, the maximum possible squared + * distance to the center is double the squared radius. */ + int minimum_squared_distance = radius * radius * 2; + + /* Find the squared distance to the nearest different pixel in the search window of the given + * radius. */ + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + bool is_sample_masked = texture_load(input_tx, texel + ivec2(x, y), fallback).x > 0.5; + if (is_center_masked != is_sample_masked) { + minimum_squared_distance = min(minimum_squared_distance, x * x + y * y); + } + } + } + + /* Compute the actual distance from the squared distance and assign it an appropriate sign + * depending on whether it lies in a masked region or not. */ + float signed_minimum_distance = sqrt(minimum_squared_distance) * (is_center_masked ? 1.0 : -1.0); + + /* Add the erode/dilate distance and divide by the inset amount as described in the discussion, + * then clamp to the [0, 1] range. */ + float value = clamp((signed_minimum_distance + distance) / inset, 0.0, 1.0); + + imageStore(output_img, texel, vec4(value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl new file mode 100644 index 00000000000..6992bc2afa5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_step.glsl @@ -0,0 +1,19 @@ +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Find the minimum/maximum value in the window of the given radius around the pixel. This is + * essentially a morphological operator with a square structuring element. The LIMIT value should + * be FLT_MAX if OPERATOR is min and FLT_MIN if OPERATOR is max. */ + float value = LIMIT; + for (int i = -radius; i <= radius; i++) { + value = OPERATOR(value, texture_load(input_tx, texel + ivec2(i, 0), vec4(LIMIT)).x); + } + + /* Write the value using the transposed texel. See the execute_step_horizontal_pass method for + * more information on the rational behind this. */ + imageStore(output_img, texel.yx, vec4(value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl new file mode 100644 index 00000000000..53dfeb01730 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_normalize.glsl @@ -0,0 +1,10 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + float value = texture_load(input_tx, texel).x; + float normalized_value = (value - minimum) * scale; + float clamped_value = clamp(normalized_value, 0.0, 1.0); + imageStore(output_img, texel, vec4(clamped_value)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl new file mode 100644 index 00000000000..f6f84aa24c1 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl @@ -0,0 +1,98 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* This shader reduces the given texture into a smaller texture of a size equal to the number of + * work groups. In particular, each work group reduces its contents into a single value and writes + * that value to a single pixel in the output image. The shader can be dispatched multiple times to + * eventually reduce the image into a single pixel. + * + * The shader works by loading the whole data of each work group into a linear array, then it + * reduces the second half of the array onto the first half of the array, then it reduces the + * second quarter of the array onto the first quarter or the array, and so on until only one + * element remains. The following figure illustrates the process for sum reduction on 8 elements. + * + * .---. .---. .---. .---. .---. .---. .---. .---. + * | 0 | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | Original data. + * '---' '---' '---' '---' '---' '---' '---' '---' + * |.____|_____|_____|_____| | | | + * || |.____|_____|___________| | | + * || || |.____|_________________| | + * || || || |.______________________| <--First reduction. Stride = 4. + * || || || || + * .---. .---. .---. .----. + * | 4 | | 6 | | 8 | | 10 | <--Data after first reduction. + * '---' '---' '---' '----' + * |.____|_____| | + * || |.__________| <--Second reduction. Stride = 2. + * || || + * .----. .----. + * | 12 | | 16 | <--Data after second reduction. + * '----' '----' + * |.____| + * || <--Third reduction. Stride = 1. + * .----. + * | 28 | + * '----' <--Data after third reduction. + * + * + * The shader is generic enough to implement many types of reductions. This is done by using macros + * that the developer should define to implement a certain reduction operation. Those include, + * TYPE, IDENTITY, INITIALIZE, LOAD, and REDUCE. See the implementation below for more information + * as well as the compositor_parallel_reduction_info.hh for example reductions operations. */ + +/* Doing the reduction in shared memory is faster, so create a shared array where the whole data + * of the work group will be loaded and reduced. The 2D structure of the work group is irrelevant + * for reduction, so we just load the data in a 1D array to simplify reduction. The developer is + * expected to define the TYPE macro to be a float or a vec4, depending on the type of data being + * reduced. */ +const uint reduction_size = gl_WorkGroupSize.x * gl_WorkGroupSize.y; +shared TYPE reduction_data[reduction_size]; + +void main() +{ + /* Load the data from the texture, while returning IDENTITY for out of bound coordinates. The + * developer is expected to define the IDENTITY macro to be a vec4 that does not affect the + * output of the reduction. For instance, sum reductions have an identity of vec4(0.0), while + * max value reductions have an identity of vec4(FLT_MIN). */ + vec4 value = texture_load(input_tx, ivec2(gl_GlobalInvocationID.xy), IDENTITY); + + /* Initialize the shared array given the previously loaded value. This step can be different + * depending on whether this is the initial reduction pass or a latter one. Indeed, the input + * texture for the initial reduction is the source texture itself, while the input texture to a + * latter reduction pass is an intermediate texture after one or more reductions have happened. + * This is significant because the data being reduced might be computed from the original data + * and different from it, for instance, when summing the luminance of an image, the original data + * is a vec4 color, while the reduced data is a float luminance value. So for the initial + * reduction pass, the luminance will be computed from the color, reduced, then stored into an + * intermediate float texture. On the other hand, for latter reduction passes, the luminance will + * be loaded directly and reduced without extra processing. So the developer is expected to + * define the INITIALIZE and LOAD macros to be expressions that derive the needed value from the + * loaded value for the initial reduction pass and latter ones respectively. */ + reduction_data[gl_LocalInvocationIndex] = is_initial_reduction ? INITIALIZE(value) : LOAD(value); + + /* Reduce the reduction data by half on every iteration until only one element remains. See the + * above figure for an intuitive understanding of the stride value. */ + for (uint stride = reduction_size / 2; stride > 0; stride /= 2) { + barrier(); + + /* Only the threads up to the current stride should be active as can be seen in the diagram + * above. */ + if (gl_LocalInvocationIndex >= stride) { + continue; + } + + /* Reduce each two elements that are stride apart, writing the result to the element with the + * lower index, as can be seen in the diagram above. The developer is expected to define the + * REDUCE macro to be a commutative and associative binary operator suitable for parallel + * reduction. */ + reduction_data[gl_LocalInvocationIndex] = REDUCE( + reduction_data[gl_LocalInvocationIndex], reduction_data[gl_LocalInvocationIndex + stride]); + } + + /* Finally, the result of the reduction is available as the first element in the reduction data, + * write it to the pixel corresponding to the work group, making sure only the one thread writes + * it. */ + barrier(); + if (gl_LocalInvocationIndex == 0) { + imageStore(output_img, ivec2(gl_WorkGroupID.xy), vec4(reduction_data[0])); + } +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl new file mode 100644 index 00000000000..ab44dac93e6 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_projector_lens_distortion.glsl @@ -0,0 +1,16 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Get the normalized coordinates of the pixel centers. */ + vec2 normalized_texel = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx)); + + /* Sample the red and blue channels shifted by the dispersion amount. */ + const float red = texture(input_tx, normalized_texel + vec2(dispersion, 0.0)).r; + const float green = texture_load(input_tx, texel).g; + const float blue = texture(input_tx, normalized_texel - vec2(dispersion, 0.0)).b; + + imageStore(output_img, texel, vec4(red, green, blue, 1.0)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl new file mode 100644 index 00000000000..b8561e5f059 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl @@ -0,0 +1,29 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Add 0.5 to evaluate the input sampler at the center of the pixel. */ + vec2 coordinates = vec2(texel) + vec2(0.5); + + /* Transform the input image by transforming the domain coordinates with the inverse of input + * image's transformation. The inverse transformation is an affine matrix and thus the + * coordinates should be in homogeneous coordinates. */ + coordinates = (mat3(inverse_transformation) * vec3(coordinates, 1.0)).xy; + + /* Since an input image with an identity transformation is supposed to be centered in the domain, + * we subtract the offset between the lower left corners of the input image and the domain, which + * is half the difference between their sizes, because the difference in size is on both sides of + * the centered image. Additionally, we floor the offset to retain the 0.5 offset added above in + * case the difference in sizes was odd. */ + ivec2 domain_size = imageSize(domain_img); + ivec2 input_size = texture_size(input_tx); + vec2 offset = floor((domain_size - input_size) / 2.0); + + /* Subtract the offset and divide by the input image size to get the relevant coordinates into + * the sampler's expected [0, 1] range. */ + vec2 normalized_coordinates = (coordinates - offset) / input_size; + + imageStore(domain_img, texel, texture(input_tx, normalized_coordinates)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl new file mode 100644 index 00000000000..dc572ea5aaf --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl @@ -0,0 +1,151 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_hash.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* A model that approximates lens distortion parameterized by a distortion parameter and dependent + * on the squared distance to the center of the image. The distorted pixel is then computed as the + * scalar multiplication of the pixel coordinates with the value returned by this model. See the + * compute_distorted_uv function for more details. */ +float compute_distortion_scale(float distortion, float distance_squared) +{ + return 1.0 / (1.0 + sqrt(max(0.0, 1.0 - distortion * distance_squared))); +} + +/* A vectorized version of compute_distortion_scale that is applied on the chromatic distortion + * parameters passed to the shader. */ +vec3 compute_chromatic_distortion_scale(float distance_squared) +{ + return 1.0 / (1.0 + sqrt(max(vec3(0.0), 1.0 - chromatic_distortion * distance_squared))); +} + +/* Compute the image coordinates after distortion by the given distortion scale computed by the + * compute_distortion_scale function. Note that the function expects centered normalized UV + * coordinates but outputs non-centered image coordinates. */ +vec2 compute_distorted_uv(vec2 uv, float scale) +{ + return (uv * scale + 0.5) * texture_size(input_tx) - 0.5; +} + +/* Compute the number of integration steps that should be used to approximate the distorted pixel + * using a heuristic, see the compute_number_of_steps function for more details. The numbers of + * steps is proportional to the number of pixels spanned by the distortion amount. For jitter + * distortion, the square root of the distortion amount plus 1 is used with a minimum of 2 steps. + * For non-jitter distortion, the distortion amount plus 1 is used as the number of steps */ +int compute_number_of_integration_steps_heuristic(float distortion) +{ +#if defined(JITTER) + return distortion < 4.0 ? 2 : int(sqrt(distortion + 1.0)); +#else + return int(distortion + 1.0); +#endif +} + +/* Compute the number of integration steps that should be used to compute each channel of the + * distorted pixel. Each of the channels are distorted by their respective chromatic distortion + * amount, then the amount of distortion between each two consecutive channels is computed, this + * amount is then used to heuristically infer the number of needed integration steps, see the + * integrate_distortion function for more information. */ +ivec3 compute_number_of_integration_steps(vec2 uv, float distance_squared) +{ + /* Distort each channel by its respective chromatic distortion amount. */ + vec3 distortion_scale = compute_chromatic_distortion_scale(distance_squared); + vec2 distorted_uv_red = compute_distorted_uv(uv, distortion_scale.r); + vec2 distorted_uv_green = compute_distorted_uv(uv, distortion_scale.g); + vec2 distorted_uv_blue = compute_distorted_uv(uv, distortion_scale.b); + + /* Infer the number of needed integration steps to compute the distorted red channel starting + * from the green channel. */ + float distortion_red = distance(distorted_uv_red, distorted_uv_green); + int steps_red = compute_number_of_integration_steps_heuristic(distortion_red); + + /* Infer the number of needed integration steps to compute the distorted blue channel starting + * from the green channel. */ + float distortion_blue = distance(distorted_uv_green, distorted_uv_blue); + int steps_blue = compute_number_of_integration_steps_heuristic(distortion_blue); + + /* The number of integration steps used to compute the green channel is the sum of both the red + * and the blue channel steps because it is computed once with each of them. */ + return ivec3(steps_red, steps_red + steps_blue, steps_blue); +} + +/* Returns a random jitter amount, which is essentially a random value in the [0, 1] range. If + * jitter is not enabled, return a constant 0.5 value instead. */ +float get_jitter(int seed) +{ +#if defined(JITTER) + return hash_uint3_to_float(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, seed); +#else + return 0.5; +#endif +} + +/* Each color channel may have a different distortion with the guarantee that the red will have the + * lowest distortion while the blue will have the highest one. If each channel is distorted + * independently, the image will look disintegrated, with each channel seemingly merely shifted. + * Consequently, the distorted pixels needs to be computed by integrating along the path of change + * of distortion starting from one channel to another. For instance, to compute the distorted red + * from the distorted green, we accumulate the color of the distorted pixel starting from the + * distortion of the red, taking small steps until we reach the distortion of the green. The pixel + * color is weighted such that it is maximum at the start distortion and zero at the end distortion + * in an arithmetic progression. The integration steps can be augmented with random values to + * simulate lens jitter. Finally, it should be noted that this function integrates both the start + * and end channels in reverse directions for more efficient computation. */ +vec3 integrate_distortion(int start, int end, float distance_squared, vec2 uv, int steps) +{ + vec3 accumulated_color = vec3(0.0); + float distortion_amount = chromatic_distortion[end] - chromatic_distortion[start]; + for (int i = 0; i < steps; i++) { + /* The increment will be in the [0, 1) range across iterations. */ + float increment = (i + get_jitter(i)) / steps; + float distortion = chromatic_distortion[start] + increment * distortion_amount; + float distortion_scale = compute_distortion_scale(distortion, distance_squared); + + /* Sample the color at the distorted coordinates and accumulate it weighted by the increment + * value for both the start and end channels. */ + vec2 distorted_uv = compute_distorted_uv(uv, distortion_scale); + vec4 color = texture(input_tx, distorted_uv / texture_size(input_tx)); + accumulated_color[start] += (1.0 - increment) * color[start]; + accumulated_color[end] += increment * color[end]; + } + return accumulated_color; +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + /* Compute the UV image coordinates in the range [-1, 1] as well as the squared distance to the + * center of the image, which is at (0, 0) in the UV coordinates. */ + vec2 center = texture_size(input_tx) / 2.0; + vec2 uv = scale * (texel + 0.5 - center) / center; + float distance_squared = dot(uv, uv); + + /* If any of the color channels will get distorted outside of the screen beyond what is possible, + * write a zero transparent color and return. */ + if (any(greaterThan(chromatic_distortion * distance_squared, vec3(1.0)))) { + imageStore(output_img, texel, vec4(0.0)); + return; + } + + /* Compute the number of integration steps that should be used to compute each channel of the + * distorted pixel. */ + ivec3 number_of_steps = compute_number_of_integration_steps(uv, distance_squared); + + /* Integrate the distortion of the red and green, then the green and blue channels. That means + * the green will be integrated twice, but this is accounted for in the number of steps which the + * color will later be divided by. See the compute_number_of_integration_steps function for more + * details. */ + vec3 color = vec3(0.0); + color += integrate_distortion(0, 1, distance_squared, uv, number_of_steps.r); + color += integrate_distortion(1, 2, distance_squared, uv, number_of_steps.b); + + /* The integration above performed weighted accumulation, and thus the color needs to be divided + * by the sum of the weights. Assuming no jitter, the weights are generated as an arithmetic + * progression starting from (0.5 / n) to ((n - 0.5) / n) for n terms. The sum of an arithmetic + * progression can be computed as (n * (start + end) / 2), which when subsisting the start and + * end reduces to (n / 2). So the color should be multiplied by 2 / n. The jitter sequence + * approximately sums to the same value because it is a uniform random value whose mean value is + * 0.5, so the expression doesn't change regardless of jitter. */ + color *= 2.0 / vec3(number_of_steps); + + imageStore(output_img, texel, vec4(color, 1.0)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl new file mode 100644 index 00000000000..7dd40581790 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl @@ -0,0 +1,8 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec4 color = vec4(texture_load(image_tx, texel).rgb, texture_load(alpha_tx, texel).x); + imageStore(output_img, texel, color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl new file mode 100644 index 00000000000..866b9045da2 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl @@ -0,0 +1,14 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); +#if defined(SPLIT_HORIZONTAL) + bool condition = (view_size.x * split_ratio) < texel.x; +#elif defined(SPLIT_VERTICAL) + bool condition = (view_size.y * split_ratio) < texel.y; +#endif + vec4 color = condition ? texture_load(first_image_tx, texel) : + texture_load(second_image_tx, texel); + imageStore(output_img, texel, color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl new file mode 100644 index 00000000000..df08991a35c --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl @@ -0,0 +1,77 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +vec4 load_input(ivec2 texel) +{ + vec4 color; + if (extend_bounds) { + /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So + * we load the input with an offset by the radius amount and fallback to a transparent color if + * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra + * center weight, see the SymmetricBlurWeights for more information. */ + ivec2 blur_size = texture_size(weights_tx) - 1; + color = texture_load(input_tx, texel - blur_size, vec4(0.0)); + } + else { + color = texture_load(input_tx, texel); + } + + if (gamma_correct) { + color = gamma_correct_blur_input(color); + } + + return color; +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec4 accumulated_color = vec4(0.0); + + /* First, compute the contribution of the center pixel. */ + vec4 center_color = load_input(texel); + accumulated_color += center_color * texture_load(weights_tx, ivec2(0)).x; + + ivec2 weights_size = texture_size(weights_tx); + + /* Then, compute the contributions of the pixels along the x axis of the filter, noting that the + * weights texture only stores the weights for the positive half, but since the filter is + * symmetric, the same weight is used for the negative half and we add both of their + * contributions. */ + for (int x = 1; x < weights_size.x; x++) { + float weight = texture_load(weights_tx, ivec2(x, 0)).x; + accumulated_color += load_input(texel + ivec2(x, 0)) * weight; + accumulated_color += load_input(texel + ivec2(-x, 0)) * weight; + } + + /* Then, compute the contributions of the pixels along the y axis of the filter, noting that the + * weights texture only stores the weights for the positive half, but since the filter is + * symmetric, the same weight is used for the negative half and we add both of their + * contributions. */ + for (int y = 1; y < weights_size.y; y++) { + float weight = texture_load(weights_tx, ivec2(0, y)).x; + accumulated_color += load_input(texel + ivec2(0, y)) * weight; + accumulated_color += load_input(texel + ivec2(0, -y)) * weight; + } + + /* Finally, compute the contributions of the pixels in the four quadrants of the filter, noting + * that the weights texture only stores the weights for the upper right quadrant, but since the + * filter is symmetric, the same weight is used for the rest of the quadrants and we add all four + * of their contributions. */ + for (int y = 1; y < weights_size.y; y++) { + for (int x = 1; x < weights_size.x; x++) { + float weight = texture_load(weights_tx, ivec2(x, y)).x; + accumulated_color += load_input(texel + ivec2(x, y)) * weight; + accumulated_color += load_input(texel + ivec2(-x, y)) * weight; + accumulated_color += load_input(texel + ivec2(x, -y)) * weight; + accumulated_color += load_input(texel + ivec2(-x, -y)) * weight; + } + } + + if (gamma_correct) { + accumulated_color = gamma_uncorrect_blur_output(accumulated_color); + } + + imageStore(output_img, texel, accumulated_color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl new file mode 100644 index 00000000000..ab0c7baa787 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_separable_blur.glsl @@ -0,0 +1,53 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +vec4 load_input(ivec2 texel) +{ + vec4 color; + if (extend_bounds) { + /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So + * we load the input with an offset by the radius amount and fallback to a transparent color if + * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra + * center weight, see the SymmetricSeparableBlurWeights for more information. */ + int blur_size = texture_size(weights_tx) - 1; + color = texture_load(input_tx, texel - ivec2(blur_size, 0), vec4(0.0)); + } + else { + color = texture_load(input_tx, texel); + } + + if (gamma_correct_input) { + color = gamma_correct_blur_input(color); + } + + return color; +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec4 accumulated_color = vec4(0.0); + + /* First, compute the contribution of the center pixel. */ + vec4 center_color = load_input(texel); + accumulated_color += center_color * texture_load(weights_tx, 0).x; + + /* Then, compute the contributions of the pixel to the right and left, noting that the + * weights texture only stores the weights for the positive half, but since the filter is + * symmetric, the same weight is used for the negative half and we add both of their + * contributions. */ + for (int i = 1; i < texture_size(weights_tx); i++) { + float weight = texture_load(weights_tx, i).x; + accumulated_color += load_input(texel + ivec2(i, 0)) * weight; + accumulated_color += load_input(texel + ivec2(-i, 0)) * weight; + } + + if (gamma_uncorrect_output) { + accumulated_color = gamma_uncorrect_blur_output(accumulated_color); + } + + /* Write the color using the transposed texel. See the execute_separable_blur_horizontal_pass + * method for more information on the rational behind this. */ + imageStore(output_img, texel.yx, accumulated_color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl new file mode 100644 index 00000000000..167006585ca --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_photoreceptor.glsl @@ -0,0 +1,22 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* Tone mapping based on equation (1) and the trilinear interpolation between equations (6) and (7) + * from Reinhard, Erik, and Kate Devlin. "Dynamic range reduction inspired by photoreceptor + * physiology." IEEE transactions on visualization and computer graphics 11.1 (2005): 13-24. */ +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec4 input_color = texture_load(input_tx, texel); + float input_luminance = dot(input_color.rgb, luminance_coefficients); + + /* Trilinear interpolation between equations (6) and (7) from Reinhard's 2005 paper. */ + vec4 local_adaptation_level = mix(vec4(input_luminance), input_color, chromatic_adaptation); + vec4 adaptation_level = mix(global_adaptation_level, local_adaptation_level, light_adaptation); + + /* Equation (1) from Reinhard's 2005 paper, assuming Vmax is 1. */ + vec4 semi_saturation = pow(intensity * adaptation_level, vec4(contrast)); + vec4 tone_mapped_color = input_color / (input_color + semi_saturation); + + imageStore(output_img, texel, vec4(tone_mapped_color.rgb, input_color.a)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl new file mode 100644 index 00000000000..ce42d021dd1 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_tone_map_simple.glsl @@ -0,0 +1,26 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) + +/* Tone mapping based on equation (3) from Reinhard, Erik, et al. "Photographic tone reproduction + * for digital images." Proceedings of the 29th annual conference on Computer graphics and + * interactive techniques. 2002. */ +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec4 input_color = texture_load(input_tx, texel); + + /* Equation (2) from Reinhard's 2002 paper. */ + vec4 scaled_color = input_color * luminance_scale; + + /* Equation (3) from Reinhard's 2002 paper, but with the 1 replaced with the blend factor for + * more flexibility. See ToneMapOperation::compute_luminance_scale_blend_factor. */ + vec4 denominator = luminance_scale_blend_factor + scaled_color; + vec4 tone_mapped_color = safe_divide(scaled_color, denominator); + + if (inverse_gamma != 0.0) { + tone_mapped_color = pow(max(tone_mapped_color, vec4(0.0)), vec4(inverse_gamma)); + } + + imageStore(output_img, texel, vec4(tone_mapped_color.rgb, input_color.a)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh new file mode 100644 index 00000000000..11f2f329cd8 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_alpha_crop_info.hh @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_alpha_crop) + .local_group_size(16, 16) + .push_constant(Type::IVEC2, "lower_bound") + .push_constant(Type::IVEC2, "upper_bound") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_alpha_crop.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh new file mode 100644 index 00000000000..301cd6acd9e --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bilateral_blur_info.hh @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_bilateral_blur) + .local_group_size(16, 16) + .push_constant(Type::INT, "radius") + .push_constant(Type::FLOAT, "threshold") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "determinator_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_bilateral_blur.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh new file mode 100644 index 00000000000..36b772aa486 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_info.hh @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_blur) + .local_group_size(16, 16) + .push_constant(Type::INT, "radius") + .push_constant(Type::BOOL, "extend_bounds") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "weights_tx") + .sampler(2, ImageType::FLOAT_2D, "mask_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_blur.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh new file mode 100644 index 00000000000..05b6385fd1e --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_blur_variable_size_info.hh @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_blur_variable_size) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "base_size") + .push_constant(Type::INT, "search_radius") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "weights_tx") + .sampler(2, ImageType::FLOAT_2D, "size_tx") + .sampler(3, ImageType::FLOAT_2D, "mask_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_blur_variable_size.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh new file mode 100644 index 00000000000..3541de53070 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_bokeh_image_info.hh @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_bokeh_image) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "exterior_angle") + .push_constant(Type::FLOAT, "rotation") + .push_constant(Type::FLOAT, "roundness") + .push_constant(Type::FLOAT, "catadioptric") + .push_constant(Type::FLOAT, "lens_shift") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_bokeh_image.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh new file mode 100644 index 00000000000..ecb253bbab1 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_box_mask_info.hh @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_box_mask_shared) + .local_group_size(16, 16) + .push_constant(Type::IVEC2, "domain_size") + .push_constant(Type::VEC2, "location") + .push_constant(Type::VEC2, "size") + .push_constant(Type::FLOAT, "cos_angle") + .push_constant(Type::FLOAT, "sin_angle") + .sampler(0, ImageType::FLOAT_2D, "base_mask_tx") + .sampler(1, ImageType::FLOAT_2D, "mask_value_tx") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img") + .compute_source("compositor_box_mask.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_box_mask_add) + .additional_info("compositor_box_mask_shared") + .define("CMP_NODE_MASKTYPE_ADD") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_box_mask_subtract) + .additional_info("compositor_box_mask_shared") + .define("CMP_NODE_MASKTYPE_SUBTRACT") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_box_mask_multiply) + .additional_info("compositor_box_mask_shared") + .define("CMP_NODE_MASKTYPE_MULTIPLY") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_box_mask_not) + .additional_info("compositor_box_mask_shared") + .define("CMP_NODE_MASKTYPE_NOT") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh new file mode 100644 index 00000000000..35e60056736 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_convert_shared) + .local_group_size(16, 16) + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .typedef_source("gpu_shader_compositor_type_conversion.glsl") + .compute_source("compositor_convert.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_convert_float_to_vector) + .additional_info("compositor_convert_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(vec3_from_float(value.x), 0.0)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_float_to_color) + .additional_info("compositor_convert_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4_from_float(value.x)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_color_to_float) + .additional_info("compositor_convert_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(float_from_vec4(value), vec3(0.0))") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_color_to_vector) + .additional_info("compositor_convert_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(vec3_from_vec4(value), 0.0)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_vector_to_float) + .additional_info("compositor_convert_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(float_from_vec3(value.xyz), vec3(0.0))") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_vector_to_color) + .additional_info("compositor_convert_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4_from_vec3(value.xyz)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_extract_alpha_from_color) + .additional_info("compositor_convert_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(value.a, vec3(0.0))") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_color_to_half_color) + .additional_info("compositor_convert_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "value") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_float_to_half_float) + .additional_info("compositor_convert_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(value.r, vec3(0.0))") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_convert_color_to_opaque) + .additional_info("compositor_convert_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("CONVERT_EXPRESSION(value)", "vec4(value.rgb, 1.0)") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh new file mode 100644 index 00000000000..df86c3a8258 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_despeckle_info.hh @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_despeckle) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "threshold") + .push_constant(Type::FLOAT, "neighbor_threshold") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "factor_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_despeckle.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh new file mode 100644 index 00000000000..bb9199dcd26 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_directional_blur_info.hh @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_directional_blur) + .local_group_size(16, 16) + .push_constant(Type::INT, "iterations") + .push_constant(Type::MAT4, "inverse_transformation") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_directional_blur.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh new file mode 100644 index 00000000000..916ec62bdba --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_edge_filter) + .local_group_size(16, 16) + .push_constant(Type::MAT4, "kernel") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "factor_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_edge_filter.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh new file mode 100644 index 00000000000..52db91c94e5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_ellipse_mask_info.hh @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_shared) + .local_group_size(16, 16) + .push_constant(Type::IVEC2, "domain_size") + .push_constant(Type::VEC2, "location") + .push_constant(Type::VEC2, "radius") + .push_constant(Type::FLOAT, "cos_angle") + .push_constant(Type::FLOAT, "sin_angle") + .sampler(0, ImageType::FLOAT_2D, "base_mask_tx") + .sampler(1, ImageType::FLOAT_2D, "mask_value_tx") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img") + .compute_source("compositor_ellipse_mask.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_add) + .additional_info("compositor_ellipse_mask_shared") + .define("CMP_NODE_MASKTYPE_ADD") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_subtract) + .additional_info("compositor_ellipse_mask_shared") + .define("CMP_NODE_MASKTYPE_SUBTRACT") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_multiply) + .additional_info("compositor_ellipse_mask_shared") + .define("CMP_NODE_MASKTYPE_MULTIPLY") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_ellipse_mask_not) + .additional_info("compositor_ellipse_mask_shared") + .define("CMP_NODE_MASKTYPE_NOT") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh new file mode 100644 index 00000000000..9d565cf4b8a --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_filter) + .local_group_size(16, 16) + .push_constant(Type::MAT4, "kernel") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "factor_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_filter.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh new file mode 100644 index 00000000000..db831518cb7 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_flip_info.hh @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_flip) + .local_group_size(16, 16) + .push_constant(Type::BOOL, "flip_x") + .push_constant(Type::BOOL, "flip_y") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_flip.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh new file mode 100644 index 00000000000..e7736744c40 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_image_crop_info.hh @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_image_crop) + .local_group_size(16, 16) + .push_constant(Type::IVEC2, "lower_bound") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_image_crop.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh new file mode 100644 index 00000000000..9f17f60129d --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_feather_info.hh @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_feather_shared) + .local_group_size(16, 16) + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_1D, "weights_tx") + .sampler(2, ImageType::FLOAT_1D, "falloffs_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_morphological_distance_feather.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_feather_dilate) + .additional_info("compositor_morphological_distance_feather_shared") + .define("COMPARE(x, y)", "x > y") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_feather_erode) + .additional_info("compositor_morphological_distance_feather_shared") + .define("COMPARE(x, y)", "x < y") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh new file mode 100644 index 00000000000..fc960e119e5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_info.hh @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_shared) + .local_group_size(16, 16) + .push_constant(Type::INT, "radius") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_morphological_distance.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_dilate) + .additional_info("compositor_morphological_distance_shared") + .define("OPERATOR(a, b)", "max(a, b)") + .define("LIMIT", "FLT_MIN") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_erode) + .additional_info("compositor_morphological_distance_shared") + .define("OPERATOR(a, b)", "min(a, b)") + .define("LIMIT", "FLT_MAX") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh new file mode 100644 index 00000000000..b1d64f61b80 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_distance_threshold_info.hh @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_morphological_distance_threshold) + .local_group_size(16, 16) + .push_constant(Type::INT, "radius") + .push_constant(Type::INT, "distance") + .push_constant(Type::FLOAT, "inset") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_morphological_distance_threshold.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh new file mode 100644 index 00000000000..e97ffd9feea --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_morphological_step_info.hh @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_morphological_step_shared) + .local_group_size(16, 16) + .push_constant(Type::INT, "radius") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_morphological_step.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_morphological_step_dilate) + .additional_info("compositor_morphological_step_shared") + .define("OPERATOR(a, b)", "max(a, b)") + .define("LIMIT", "FLT_MIN") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_morphological_step_erode) + .additional_info("compositor_morphological_step_shared") + .define("OPERATOR(a, b)", "min(a, b)") + .define("LIMIT", "FLT_MAX") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh new file mode 100644 index 00000000000..02fdc424014 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_normalize_info.hh @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_normalize) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "minimum") + .push_constant(Type::FLOAT, "scale") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_normalize.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh new file mode 100644 index 00000000000..e2252b14758 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_parallel_reduction_info.hh @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_parallel_reduction_shared) + .local_group_size(16, 16) + .push_constant(Type::BOOL, "is_initial_reduction") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .compute_source("compositor_parallel_reduction.glsl"); + +/* -------------------------------------------------------------------- + * Sum Reductions. + */ + +GPU_SHADER_CREATE_INFO(compositor_sum_shared) + .additional_info("compositor_parallel_reduction_shared") + .define("IDENTITY", "vec4(0.0)") + .define("REDUCE(lhs, rhs)", "lhs + rhs"); + +GPU_SHADER_CREATE_INFO(compositor_sum_float_shared) + .additional_info("compositor_sum_shared") + .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("TYPE", "float") + .define("LOAD(value)", "value.x"); + +GPU_SHADER_CREATE_INFO(compositor_sum_red) + .additional_info("compositor_sum_float_shared") + .define("INITIALIZE(value)", "value.r") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_green) + .additional_info("compositor_sum_float_shared") + .define("INITIALIZE(value)", "value.g") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_blue) + .additional_info("compositor_sum_float_shared") + .define("INITIALIZE(value)", "value.b") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_luminance) + .additional_info("compositor_sum_float_shared") + .push_constant(Type::VEC3, "luminance_coefficients") + .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_log_luminance) + .additional_info("compositor_sum_float_shared") + .push_constant(Type::VEC3, "luminance_coefficients") + .define("INITIALIZE(value)", "log(max(dot(value.rgb, luminance_coefficients), 1e-5))") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_color) + .additional_info("compositor_sum_shared") + .image(0, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("TYPE", "vec4") + .define("INITIALIZE(value)", "value") + .define("LOAD(value)", "value") + .do_static_compilation(true); + +/* -------------------------------------------------------------------- + * Sum Of Squared Difference Reductions. + */ + +GPU_SHADER_CREATE_INFO(compositor_sum_squared_difference_float_shared) + .additional_info("compositor_parallel_reduction_shared") + .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .push_constant(Type::FLOAT, "subtrahend") + .define("TYPE", "float") + .define("IDENTITY", "vec4(subtrahend)") + .define("LOAD(value)", "value.x") + .define("REDUCE(lhs, rhs)", "lhs + rhs"); + +GPU_SHADER_CREATE_INFO(compositor_sum_red_squared_difference) + .additional_info("compositor_sum_squared_difference_float_shared") + .define("INITIALIZE(value)", "pow(value.r - subtrahend, 2.0)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_green_squared_difference) + .additional_info("compositor_sum_squared_difference_float_shared") + .define("INITIALIZE(value)", "pow(value.g - subtrahend, 2.0)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_blue_squared_difference) + .additional_info("compositor_sum_squared_difference_float_shared") + .define("INITIALIZE(value)", "pow(value.b - subtrahend, 2.0)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_sum_luminance_squared_difference) + .additional_info("compositor_sum_squared_difference_float_shared") + .push_constant(Type::VEC3, "luminance_coefficients") + .define("INITIALIZE(value)", "pow(dot(value.rgb, luminance_coefficients) - subtrahend, 2.0)") + .do_static_compilation(true); + +/* -------------------------------------------------------------------- + * Maximum Reductions. + */ + +GPU_SHADER_CREATE_INFO(compositor_maximum_luminance) + .additional_info("compositor_parallel_reduction_shared") + .typedef_source("common_math_lib.glsl") + .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .push_constant(Type::VEC3, "luminance_coefficients") + .define("TYPE", "float") + .define("IDENTITY", "vec4(FLT_MIN)") + .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)") + .define("LOAD(value)", "value.x") + .define("REDUCE(lhs, rhs)", "max(lhs, rhs)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_maximum_float_in_range) + .additional_info("compositor_parallel_reduction_shared") + .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .push_constant(Type::FLOAT, "lower_bound") + .push_constant(Type::FLOAT, "upper_bound") + .define("TYPE", "float") + .define("IDENTITY", "vec4(lower_bound)") + .define("INITIALIZE(v)", "((v.x <= upper_bound) && (v.x >= lower_bound)) ? v.x : lower_bound") + .define("LOAD(value)", "value.x") + .define("REDUCE(lhs, rhs)", "((rhs > lhs) && (rhs <= upper_bound)) ? rhs : lhs") + .do_static_compilation(true); + +/* -------------------------------------------------------------------- + * Minimum Reductions. + */ + +GPU_SHADER_CREATE_INFO(compositor_minimum_luminance) + .additional_info("compositor_parallel_reduction_shared") + .typedef_source("common_math_lib.glsl") + .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .push_constant(Type::VEC3, "luminance_coefficients") + .define("TYPE", "float") + .define("IDENTITY", "vec4(FLT_MAX)") + .define("INITIALIZE(value)", "dot(value.rgb, luminance_coefficients)") + .define("LOAD(value)", "value.x") + .define("REDUCE(lhs, rhs)", "min(lhs, rhs)") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_minimum_float_in_range) + .additional_info("compositor_parallel_reduction_shared") + .image(0, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .push_constant(Type::FLOAT, "lower_bound") + .push_constant(Type::FLOAT, "upper_bound") + .define("TYPE", "float") + .define("IDENTITY", "vec4(upper_bound)") + .define("INITIALIZE(v)", "((v.x <= upper_bound) && (v.x >= lower_bound)) ? v.x : upper_bound") + .define("LOAD(value)", "value.x") + .define("REDUCE(lhs, rhs)", "((rhs < lhs) && (rhs >= lower_bound)) ? rhs : lhs") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh new file mode 100644 index 00000000000..98fe1731703 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_projector_lens_distortion_info.hh @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_projector_lens_distortion) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "dispersion") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_projector_lens_distortion.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh new file mode 100644 index 00000000000..4528649ae98 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_realize_on_domain_info.hh @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_shared) + .local_group_size(16, 16) + .push_constant(Type::MAT4, "inverse_transformation") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .compute_source("compositor_realize_on_domain.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_color) + .additional_info("compositor_realize_on_domain_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_vector) + .additional_info("compositor_realize_on_domain_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_float) + .additional_info("compositor_realize_on_domain_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh new file mode 100644 index 00000000000..c42f2b328d4 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_screen_lens_distortion_info.hh @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_shared) + .local_group_size(16, 16) + .push_constant(Type::VEC3, "chromatic_distortion") + .push_constant(Type::FLOAT, "scale") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_screen_lens_distortion.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion) + .additional_info("compositor_screen_lens_distortion_shared") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_screen_lens_distortion_jitter) + .additional_info("compositor_screen_lens_distortion_shared") + .define("JITTER") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh new file mode 100644 index 00000000000..ca28194e921 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_set_alpha) + .local_group_size(16, 16) + .sampler(0, ImageType::FLOAT_2D, "image_tx") + .sampler(1, ImageType::FLOAT_2D, "alpha_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_set_alpha.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh new file mode 100644 index 00000000000..d5793b0ce59 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_split_viewer_shared) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "split_ratio") + .push_constant(Type::IVEC2, "view_size") + .sampler(0, ImageType::FLOAT_2D, "first_image_tx") + .sampler(1, ImageType::FLOAT_2D, "second_image_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_split_viewer.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_split_viewer_horizontal) + .additional_info("compositor_split_viewer_shared") + .define("SPLIT_HORIZONTAL") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_split_viewer_vertical) + .additional_info("compositor_split_viewer_shared") + .define("SPLIT_VERTICAL") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh new file mode 100644 index 00000000000..8ba2b4e04ef --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_info.hh @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_symmetric_blur) + .local_group_size(16, 16) + .push_constant(Type::BOOL, "extend_bounds") + .push_constant(Type::BOOL, "gamma_correct") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "weights_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_symmetric_blur.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh new file mode 100644 index 00000000000..57247dba4b8 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_separable_blur_info.hh @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur) + .local_group_size(16, 16) + .push_constant(Type::BOOL, "extend_bounds") + .push_constant(Type::BOOL, "gamma_correct_input") + .push_constant(Type::BOOL, "gamma_uncorrect_output") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_1D, "weights_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_symmetric_separable_blur.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh new file mode 100644 index 00000000000..a460c9d58a6 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_photoreceptor_info.hh @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_tone_map_photoreceptor) + .local_group_size(16, 16) + .push_constant(Type::VEC4, "global_adaptation_level") + .push_constant(Type::FLOAT, "contrast") + .push_constant(Type::FLOAT, "intensity") + .push_constant(Type::FLOAT, "chromatic_adaptation") + .push_constant(Type::FLOAT, "light_adaptation") + .push_constant(Type::VEC3, "luminance_coefficients") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_tone_map_photoreceptor.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh new file mode 100644 index 00000000000..2b220af9460 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_tone_map_simple_info.hh @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_tone_map_simple) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "luminance_scale") + .push_constant(Type::FLOAT, "luminance_scale_blend_factor") + .push_constant(Type::FLOAT, "inverse_gamma") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_tone_map_simple.glsl") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl new file mode 100644 index 00000000000..8e3e033147f --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl @@ -0,0 +1,48 @@ +void node_composite_alpha_over_mixed( + float factor, vec4 color, vec4 over_color, float premultiply_factor, out vec4 result) +{ + if (over_color.a <= 0.0) { + result = color; + } + else if (factor == 1.0 && over_color.a >= 1.0) { + result = over_color; + } + else { + float add_factor = 1.0 - premultiply_factor + over_color.a * premultiply_factor; + float premultiplier = factor * add_factor; + float multiplier = 1.0 - factor * over_color.a; + + result = multiplier * color + vec2(premultiplier, factor).xxxy * over_color; + } +} + +void node_composite_alpha_over_key(float factor, vec4 color, vec4 over_color, out vec4 result) +{ + if (over_color.a <= 0.0) { + result = color; + } + else if (factor == 1.0 && over_color.a >= 1.0) { + result = over_color; + } + else { + result = mix(color, vec4(over_color.rgb, 1.0), factor * over_color.a); + } +} + +void node_composite_alpha_over_premultiply(float factor, + vec4 color, + vec4 over_color, + out vec4 result) +{ + if (over_color.a < 0.0) { + result = color; + } + else if (factor == 1.0 && over_color.a >= 1.0) { + result = over_color; + } + else { + float multiplier = 1.0 - factor * over_color.a; + + result = multiplier * color + factor * over_color; + } +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl new file mode 100644 index 00000000000..e404c03bbb0 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl @@ -0,0 +1,32 @@ +/* Preprocess the input of the blur filter by squaring it in its alpha straight form, assuming the + * given color is alpha premultiplied. */ +vec4 gamma_correct_blur_input(vec4 color) +{ + /* Unpremultiply alpha. */ + color.rgb /= color.a > 0.0 ? color.a : 1.0; + + /* Square color channel if it is positive, otherwise zero it. */ + color.rgb *= mix(color.rgb, vec3(0.0), lessThan(color.rgb, vec3(0.0))); + + /* Premultiply alpha to undo previous alpha unpremultiplication. */ + color.rgb *= color.a > 0.0 ? color.a : 1.0; + + return color; +} + +/* Postprocess the output of the blur filter by taking its square root it in its alpha straight + * form, assuming the given color is alpha premultiplied. This essential undoes the processing done + * by the gamma_correct_blur_input function. */ +vec4 gamma_uncorrect_blur_output(vec4 color) +{ + /* Unpremultiply alpha. */ + color.rgb /= color.a > 0.0 ? color.a : 1.0; + + /* Take the square root of the color channel if it is positive, otherwise zero it. */ + color.rgb = mix(sqrt(color.rgb), vec3(0.0), lessThan(color.rgb, vec3(0.0))); + + /* Premultiply alpha to undo previous alpha unpremultiplication. */ + color.rgb *= color.a > 0.0 ? color.a : 1.0; + + return color; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl new file mode 100644 index 00000000000..ce71b4fd8a4 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl @@ -0,0 +1,38 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +/* The algorithm is by Werner D. Streidt + * (http://visca.com/ffactory/archives/5-99/msg00021.html) + * Extracted of OpenCV demhist.c + */ + +#define FLT_EPSILON 1.192092896e-07F + +void node_composite_bright_contrast( + vec4 color, float brightness, float contrast, const float use_premultiply, out vec4 result) +{ + brightness /= 100.0; + float delta = contrast / 200.0; + + float multiplier, offset; + if (contrast > 0.0) { + multiplier = 1.0 - delta * 2.0; + multiplier = 1.0 / max(multiplier, FLT_EPSILON); + offset = multiplier * (brightness - delta); + } + else { + delta *= -1.0; + multiplier = max(1.0 - delta * 2.0, 0.0); + offset = multiplier * brightness + delta; + } + + if (use_premultiply != 0.0) { + color_alpha_unpremultiply(color, color); + } + + result.rgb = color.rgb * multiplier + offset; + result.a = color.a; + + if (use_premultiply != 0.0) { + color_alpha_premultiply(result, result); + } +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl new file mode 100644 index 00000000000..f2dcc9543f2 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl @@ -0,0 +1,52 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +#define CMP_NODE_CHANNEL_MATTE_CS_RGB 1.0 +#define CMP_NODE_CHANNEL_MATTE_CS_HSV 2.0 +#define CMP_NODE_CHANNEL_MATTE_CS_YUV 3.0 +#define CMP_NODE_CHANNEL_MATTE_CS_YCC 4.0 + +void node_composite_channel_matte(vec4 color, + const float color_space, + const float matte_channel, + const vec2 limit_channels, + float max_limit, + float min_limit, + out vec4 result, + out float matte) +{ + vec4 channels; + if (color_space == CMP_NODE_CHANNEL_MATTE_CS_HSV) { + rgb_to_hsv(color, channels); + } + else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YUV) { + rgba_to_yuva_itu_709(color, channels); + } + else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YCC) { + rgba_to_ycca_itu_709(color, channels); + } + else { + channels = color; + } + + float matte_value = channels[int(matte_channel)]; + float limit_value = max(channels[int(limit_channels.x)], channels[int(limit_channels.y)]); + + float alpha = 1.0 - (matte_value - limit_value); + if (alpha > max_limit) { + alpha = color.a; + } + else if (alpha < min_limit) { + alpha = 0.0; + } + else { + alpha = (alpha - min_limit) / (max_limit - min_limit); + } + + matte = min(alpha, color.a); + result = color * matte; +} + +#undef CMP_NODE_CHANNEL_MATTE_CS_RGB +#undef CMP_NODE_CHANNEL_MATTE_CS_HSV +#undef CMP_NODE_CHANNEL_MATTE_CS_YUV +#undef CMP_NODE_CHANNEL_MATTE_CS_YCC diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl new file mode 100644 index 00000000000..5d6bea0c9db --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl @@ -0,0 +1,43 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +/* Algorithm from the book Video Demystified. Chapter 7. Chroma Keying. */ +void node_composite_chroma_matte(vec4 color, + vec4 key, + float acceptance, + float cutoff, + float falloff, + out vec4 result, + out float matte) +{ + vec4 color_ycca; + rgba_to_ycca_itu_709(color, color_ycca); + vec4 key_ycca; + rgba_to_ycca_itu_709(key, key_ycca); + + /* Normalize the CrCb components into the [-1, 1] range. */ + vec2 color_cc = color_ycca.yz * 2.0 - 1.0; + vec2 key_cc = key_ycca.yz * 2.0 - 1.0; + + /* Rotate the color onto the space of the key such that x axis of the color space passes through + * the key color. */ + color_cc = vector_to_rotation_matrix(key_cc * vec2(1.0, -1.0)) * color_cc; + + /* Compute foreground key. If positive, the value is in the [0, 1] range. */ + float foreground_key = color_cc.x - (abs(color_cc.y) / acceptance); + + /* Negative foreground key values retain the original alpha. Positive values are scaled by the + * falloff, while colors that make an angle less than the cutoff angle get a zero alpha. */ + float alpha = color.a; + if (foreground_key > 0.0) { + alpha = 1.0 - (foreground_key / falloff); + + if (abs(atan(color_cc.y, color_cc.x)) < (cutoff / 2.0)) { + alpha = 0.0; + } + } + + /* Compute output. */ + matte = min(alpha, color.a); + result = color * matte; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl new file mode 100644 index 00000000000..bffb94cdedb --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl @@ -0,0 +1,34 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_color_balance_lgg( + float factor, vec4 color, vec3 lift, vec3 gamma, vec3 gain, out vec4 result) +{ + lift = 2.0 - lift; + vec3 srgb_color = linear_rgb_to_srgb(color.rgb); + vec3 lift_balanced = ((srgb_color - 1.0) * lift) + 1.0; + + vec3 gain_balanced = lift_balanced * gain; + gain_balanced = max(gain_balanced, vec3(0.0)); + + vec3 linear_color = srgb_to_linear_rgb(gain_balanced); + gamma = mix(gamma, vec3(1e-6), equal(gamma, vec3(0.0))); + vec3 gamma_balanced = pow(linear_color, 1.0 / gamma); + + result.rgb = mix(color.rgb, gamma_balanced, min(factor, 1.0)); + result.a = color.a; +} + +void node_composite_color_balance_asc_cdl(float factor, + vec4 color, + vec3 offset, + vec3 power, + vec3 slope, + float offset_basis, + out vec4 result) +{ + offset += offset_basis; + vec3 balanced = color.rgb * slope + offset; + balanced = pow(max(balanced, vec3(0.0)), power); + result.rgb = mix(color.rgb, balanced, min(factor, 1.0)); + result.a = color.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl new file mode 100644 index 00000000000..9b4858f03be --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl @@ -0,0 +1,87 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_color_correction(vec4 color, + float mask, + const vec3 enabled_channels, + float start_midtones, + float end_midtones, + float master_saturation, + float master_contrast, + float master_gamma, + float master_gain, + float master_lift, + float shadows_saturation, + float shadows_contrast, + float shadows_gamma, + float shadows_gain, + float shadows_lift, + float midtones_saturation, + float midtones_contrast, + float midtones_gamma, + float midtones_gain, + float midtones_lift, + float highlights_saturation, + float highlights_contrast, + float highlights_gamma, + float highlights_gain, + float highlights_lift, + const vec3 luminance_coefficients, + out vec4 result) +{ + const float margin = 0.10; + const float margin_divider = 0.5 / margin; + float level = (color.r + color.g + color.b) / 3.0; + float level_shadows = 0.0; + float level_midtones = 0.0; + float level_highlights = 0.0; + if (level < (start_midtones - margin)) { + level_shadows = 1.0; + } + else if (level < (start_midtones + margin)) { + level_midtones = ((level - start_midtones) * margin_divider) + 0.5; + level_shadows = 1.0 - level_midtones; + } + else if (level < (end_midtones - margin)) { + level_midtones = 1.0; + } + else if (level < (end_midtones + margin)) { + level_highlights = ((level - end_midtones) * margin_divider) + 0.5; + level_midtones = 1.0 - level_highlights; + } + else { + level_highlights = 1.0; + } + + float contrast = level_shadows * shadows_contrast; + contrast += level_midtones * midtones_contrast; + contrast += level_highlights * highlights_contrast; + contrast *= master_contrast; + float saturation = level_shadows * shadows_saturation; + saturation += level_midtones * midtones_saturation; + saturation += level_highlights * highlights_saturation; + saturation *= master_saturation; + float gamma = level_shadows * shadows_gamma; + gamma += level_midtones * midtones_gamma; + gamma += level_highlights * highlights_gamma; + gamma *= master_gamma; + float gain = level_shadows * shadows_gain; + gain += level_midtones * midtones_gain; + gain += level_highlights * highlights_gain; + gain *= master_gain; + float lift = level_shadows * shadows_lift; + lift += level_midtones * midtones_lift; + lift += level_highlights * highlights_lift; + lift += master_lift; + + float inverse_gamma = 1.0 / gamma; + float luma = get_luminance(color.rgb, luminance_coefficients); + + vec3 corrected = luma + saturation * (color.rgb - luma); + corrected = 0.5 + (corrected - 0.5) * contrast; + corrected = fallback_pow(corrected * gain + lift, inverse_gamma, corrected); + corrected = mix(color.rgb, corrected, min(mask, 1.0)); + + result.rgb = mix(corrected, color.rgb, equal(enabled_channels, vec3(0.0))); + result.a = color.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl new file mode 100644 index 00000000000..038471bc1bc --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl @@ -0,0 +1,27 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_color_matte(vec4 color, + vec4 key, + float hue_epsilon, + float saturation_epsilon, + float value_epsilon, + out vec4 result, + out float matte) + +{ + vec4 color_hsva; + rgb_to_hsv(color, color_hsva); + vec4 key_hsva; + rgb_to_hsv(key, key_hsva); + + bool is_within_saturation = distance(color_hsva.y, key_hsva.y) < saturation_epsilon; + bool is_within_value = distance(color_hsva.z, key_hsva.z) < value_epsilon; + bool is_within_hue = distance(color_hsva.x, key_hsva.x) < hue_epsilon; + /* Hue wraps around, so check the distance around the boundary. */ + float min_hue = min(color_hsva.x, key_hsva.x); + float max_hue = max(color_hsva.x, key_hsva.x); + is_within_hue = is_within_hue || ((min_hue + (1.0 - max_hue)) < hue_epsilon); + + matte = (is_within_hue && is_within_saturation && is_within_value) ? 0.0 : color.a; + result = color * matte; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl new file mode 100644 index 00000000000..0adad53ad80 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl @@ -0,0 +1,13 @@ +void node_composite_color_spill(vec4 color, + float factor, + const float spill_channel, + vec3 spill_scale, + const vec2 limit_channels, + float limit_scale, + out vec4 result) +{ + float average_limit = (color[int(limit_channels.x)] + color[int(limit_channels.y)]) / 2.0; + float map = factor * color[int(spill_channel)] - limit_scale * average_limit; + result.rgb = map > 0.0 ? color.rgb + spill_scale * map : color.rgb; + result.a = color.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl new file mode 100644 index 00000000000..bcdd625bd4f --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl @@ -0,0 +1,6 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void color_to_luminance(vec4 color, const vec3 luminance_coefficients, out float result) +{ + result = get_luminance(color.rgb, luminance_coefficients); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl new file mode 100644 index 00000000000..d769cadce3c --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl @@ -0,0 +1,10 @@ +void node_composite_difference_matte( + vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte) +{ + vec4 difference = abs(color - key); + float average_difference = (difference.r + difference.g + difference.b) / 3.0; + bool is_opaque = average_difference > tolerance + falloff; + float alpha = is_opaque ? color.a : (max(0.0, average_difference - tolerance) / falloff); + matte = min(alpha, color.a); + result = color * matte; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl new file mode 100644 index 00000000000..9beed66826c --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl @@ -0,0 +1,26 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_distance_matte_rgba( + vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte) +{ + float difference = distance(color.rgb, key.rgb); + bool is_opaque = difference > tolerance + falloff; + float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff; + matte = min(alpha, color.a); + result = color * matte; +} + +void node_composite_distance_matte_ycca( + vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte) +{ + vec4 color_ycca; + rgba_to_ycca_itu_709(color, color_ycca); + vec4 key_ycca; + rgba_to_ycca_itu_709(key, key_ycca); + + float difference = distance(color_ycca.yz, key_ycca.yz); + bool is_opaque = difference > tolerance + falloff; + float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff; + matte = min(alpha, color.a); + result = color * matte; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl new file mode 100644 index 00000000000..f246635a91e --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl @@ -0,0 +1,6 @@ +void node_composite_exposure(vec4 color, float exposure, out vec4 result) +{ + float multiplier = exp2(exposure); + result.rgb = color.rgb * multiplier; + result.a = color.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl new file mode 100644 index 00000000000..53070d4b0e2 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl @@ -0,0 +1,7 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) + +void node_composite_gamma(vec4 color, float gamma, out vec4 result) +{ + result.rgb = fallback_pow(color.rgb, gamma, color.rgb); + result.a = color.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl new file mode 100644 index 00000000000..99eb125cdf2 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl @@ -0,0 +1,39 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +/* Curve maps are stored in sampler objects that are evaluated in the [0, 1] range, so normalize + * parameters accordingly. */ +#define NORMALIZE_PARAMETER(parameter, minimum, range) ((parameter - minimum) * range) + +void node_composite_hue_correct(float factor, + vec4 color, + sampler1DArray curve_map, + const float layer, + vec3 minimums, + vec3 range_dividers, + out vec4 result) +{ + vec4 hsv; + rgb_to_hsv(color, hsv); + + /* First, adjust the hue channel on its own, since corrections in the saturation and value + * channels depends on the new value of the hue, not its original value. A curve map value of 0.5 + * means no change in hue, so adjust the value to get an identity at 0.5. Since the identity of + * addition is 0, we subtract 0.5 (0.5 - 0.5 = 0). */ + const float hue_parameter = NORMALIZE_PARAMETER(hsv.x, minimums.x, range_dividers.x); + hsv.x += texture(curve_map, vec2(hue_parameter, layer)).x - 0.5; + + /* Second, adjust the saturation and value based on the new value of the hue. A curve map value + * of 0.5 means no change in hue, so adjust the value to get an identity at 0.5. Since the + * identity of duplication is 1, we multiply by 2 (0.5 * 2 = 1). */ + vec2 parameters = NORMALIZE_PARAMETER(hsv.x, minimums.yz, range_dividers.yz); + hsv.y *= texture(curve_map, vec2(parameters.x, layer)).y * 2.0; + hsv.z *= texture(curve_map, vec2(parameters.y, layer)).z * 2.0; + + /* Sanitize the new hue and saturation values. */ + hsv.x = fract(hsv.x); + hsv.y = clamp(hsv.y, 0.0, 1.0); + + hsv_to_rgb(hsv, result); + + result = mix(color, result, factor); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl new file mode 100644 index 00000000000..dd5eb33d318 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl @@ -0,0 +1,16 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_hue_saturation_value( + vec4 color, float hue, float saturation, float value, float factor, out vec4 result) +{ + vec4 hsv; + rgb_to_hsv(color, hsv); + + hsv.x = fract(hsv.x + hue + 0.5); + hsv.y = clamp(hsv.y * saturation, 0.0, 1.0); + hsv.z = hsv.z * value; + + hsv_to_rgb(hsv, result); + + result = mix(color, result, factor); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl new file mode 100644 index 00000000000..59be746da7f --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl @@ -0,0 +1,13 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_invert(float fac, vec4 color, float do_rgb, float do_alpha, out vec4 result) +{ + result = color; + if (do_rgb != 0.0) { + result.rgb = 1.0 - result.rgb; + } + if (do_alpha != 0.0) { + result.a = 1.0 - result.a; + } + result = mix(color, result, fac); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl new file mode 100644 index 00000000000..3647ac583fe --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl @@ -0,0 +1,14 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_composite_luminance_matte(vec4 color, + float high, + float low, + const vec3 luminance_coefficients, + out vec4 result, + out float matte) +{ + float luminance = get_luminance(color.rgb, luminance_coefficients); + float alpha = clamp(0.0, 1.0, (luminance - low) / (high - low)); + matte = min(alpha, color.a); + result = color * matte; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl new file mode 100644 index 00000000000..27624223dbc --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl @@ -0,0 +1,7 @@ +/* The compute shader that will be dispatched by the compositor ShaderOperation. It just calls the + * evaluate function that will be dynamically generated and appended to this shader in the + * ShaderOperation::generate_code method. */ +void main() +{ + evaluate(); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl new file mode 100644 index 00000000000..20874b4ef44 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl @@ -0,0 +1,56 @@ +/* An arbitrary value determined by Blender. */ +#define BLENDER_ZMAX 10000.0 + +void node_composite_map_range(float value, + float from_min, + float from_max, + float to_min, + float to_max, + const float should_clamp, + out float result) +{ + if (abs(from_max - from_min) < 1e-6) { + result = 0.0; + } + else { + if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) { + result = (value - from_min) / (from_max - from_min); + result = to_min + result * (to_max - to_min); + } + else if (value > BLENDER_ZMAX) { + result = to_max; + } + else { + result = to_min; + } + + if (should_clamp != 0.0) { + if (to_max > to_min) { + result = clamp(result, to_min, to_max); + } + else { + result = clamp(result, to_max, to_min); + } + } + } +} + +void node_composite_map_value(float value, + float offset, + float size, + const float use_min, + float min, + const float use_max, + float max, + out float result) +{ + result = (value + offset) * size; + + if (use_min != 0.0 && result < min) { + result = min; + } + + if (use_max != 0.0 && result > max) { + result = max; + } +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl new file mode 100644 index 00000000000..a2e3b6c4aaa --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl @@ -0,0 +1,9 @@ +void node_composite_normal(vec3 input_vector, + vec3 input_normal, + out vec3 result_normal, + out float result_dot) +{ + vec3 normal = normalize(input_normal); + result_normal = normal; + result_dot = -dot(input_vector, normal); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl new file mode 100644 index 00000000000..ee8ae234abe --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl @@ -0,0 +1,6 @@ +void node_composite_posterize(vec4 color, float steps, out vec4 result) +{ + steps = clamp(steps, 2.0, 1024.0); + result = floor(color * steps) / steps; + result.a = color.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl new file mode 100644 index 00000000000..d72d2260394 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl @@ -0,0 +1,132 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +/* ** Combine/Separate XYZ ** */ + +void node_composite_combine_xyz(float x, float y, float z, out vec3 vector) +{ + vector = vec3(x, y, z); +} + +void node_composite_separate_xyz(vec3 vector, out float x, out float y, out float z) +{ + x = vector.x; + y = vector.y; + z = vector.z; +} + +/* ** Combine/Separate RGBA ** */ + +void node_composite_combine_rgba(float r, float g, float b, float a, out vec4 color) +{ + color = vec4(r, g, b, a); +} + +void node_composite_separate_rgba(vec4 color, out float r, out float g, out float b, out float a) +{ + r = color.r; + g = color.g; + b = color.b; + a = color.a; +} + +/* ** Combine/Separate HSVA ** */ + +void node_composite_combine_hsva(float h, float s, float v, float a, out vec4 color) +{ + hsv_to_rgb(vec4(h, s, v, a), color); +} + +void node_composite_separate_hsva(vec4 color, out float h, out float s, out float v, out float a) +{ + vec4 hsva; + rgb_to_hsv(color, hsva); + h = hsva.x; + s = hsva.y; + v = hsva.z; + a = hsva.a; +} + +/* ** Combine/Separate HSLA ** */ + +void node_composite_combine_hsla(float h, float s, float l, float a, out vec4 color) +{ + hsl_to_rgb(vec4(h, s, l, a), color); +} + +void node_composite_separate_hsla(vec4 color, out float h, out float s, out float l, out float a) +{ + vec4 hsla; + rgb_to_hsl(color, hsla); + h = hsla.x; + s = hsla.y; + l = hsla.z; + a = hsla.a; +} + +/* ** Combine/Separate YCCA ** */ + +void node_composite_combine_ycca_itu_601(float y, float cb, float cr, float a, out vec4 color) +{ + ycca_to_rgba_itu_601(vec4(y, cb, cr, a), color); +} + +void node_composite_combine_ycca_itu_709(float y, float cb, float cr, float a, out vec4 color) +{ + ycca_to_rgba_itu_709(vec4(y, cb, cr, a), color); +} + +void node_composite_combine_ycca_jpeg(float y, float cb, float cr, float a, out vec4 color) +{ + ycca_to_rgba_jpeg(vec4(y, cb, cr, a), color); +} + +void node_composite_separate_ycca_itu_601( + vec4 color, out float y, out float cb, out float cr, out float a) +{ + vec4 ycca; + rgba_to_ycca_itu_601(color, ycca); + y = ycca.x; + cb = ycca.y; + cr = ycca.z; + a = ycca.a; +} + +void node_composite_separate_ycca_itu_709( + vec4 color, out float y, out float cb, out float cr, out float a) +{ + vec4 ycca; + rgba_to_ycca_itu_709(color, ycca); + y = ycca.x; + cb = ycca.y; + cr = ycca.z; + a = ycca.a; +} + +void node_composite_separate_ycca_jpeg( + vec4 color, out float y, out float cb, out float cr, out float a) +{ + vec4 ycca; + rgba_to_ycca_jpeg(color, ycca); + y = ycca.x; + cb = ycca.y; + cr = ycca.z; + a = ycca.a; +} + +/* ** Combine/Separate YUVA ** */ + +void node_composite_combine_yuva_itu_709(float y, float u, float v, float a, out vec4 color) +{ + yuva_to_rgba_itu_709(vec4(y, u, v, a), color); +} + +void node_composite_separate_yuva_itu_709( + vec4 color, out float y, out float u, out float v, out float a) +{ + vec4 yuva; + rgba_to_yuva_itu_709(color, yuva); + y = yuva.x; + u = yuva.y; + v = yuva.z; + a = yuva.a; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl new file mode 100644 index 00000000000..95380d1ed0f --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl @@ -0,0 +1,9 @@ +void node_composite_set_alpha_apply(vec4 color, float alpha, out vec4 result) +{ + result = color * alpha; +} + +void node_composite_set_alpha_replace(vec4 color, float alpha, out vec4 result) +{ + result = vec4(color.rgb, alpha); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl new file mode 100644 index 00000000000..7fba26907b5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl @@ -0,0 +1,26 @@ +/* The following functions are called to store the given value in the output identified by the + * given ID. The ID is an unsigned integer that is encoded in a float, so floatBitsToUint is called + * to get the actual identifier. The functions have an output value as their last argument that is + * used to establish an output link that is then used to track the nodes that contribute to the + * output of the compositor node tree. + * + * The store_[float|vector|color] functions are dynamically generated in + * ShaderOperation::generate_code_for_outputs. */ + +void node_compositor_store_output_float(const float id, float value, out float out_value) +{ + store_float(floatBitsToUint(id), value); + out_value = value; +} + +void node_compositor_store_output_vector(const float id, vec3 vector, out vec3 out_vector) +{ + store_vector(floatBitsToUint(id), vector); + out_vector = vector; +} + +void node_compositor_store_output_color(const float id, vec4 color, out vec4 out_color) +{ + store_color(floatBitsToUint(id), color); + out_color = color; +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl new file mode 100644 index 00000000000..128fc6aeaf5 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl @@ -0,0 +1,35 @@ +/* A shorthand for 1D textureSize with a zero LOD. */ +int texture_size(sampler1D sampler) +{ + return textureSize(sampler, 0); +} + +/* A shorthand for 1D texelFetch with zero LOD and bounded access clamped to border. */ +vec4 texture_load(sampler1D sampler, int x) +{ + const int texture_bound = texture_size(sampler) - 1; + return texelFetch(sampler, clamp(x, 0, texture_bound), 0); +} + +/* A shorthand for 2D textureSize with a zero LOD. */ +ivec2 texture_size(sampler2D sampler) +{ + return textureSize(sampler, 0); +} + +/* A shorthand for 2D texelFetch with zero LOD and bounded access clamped to border. */ +vec4 texture_load(sampler2D sampler, ivec2 texel) +{ + const ivec2 texture_bounds = texture_size(sampler) - ivec2(1); + return texelFetch(sampler, clamp(texel, ivec2(0), texture_bounds), 0); +} + +/* A shorthand for 2D texelFetch with zero LOD and a fallback value for out-of-bound access. */ +vec4 texture_load(sampler2D sampler, ivec2 texel, vec4 fallback) +{ + const ivec2 texture_bounds = texture_size(sampler) - ivec2(1); + if (any(lessThan(texel, ivec2(0))) || any(greaterThan(texel, texture_bounds))) { + return fallback; + } + return texelFetch(sampler, texel, 0); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl new file mode 100644 index 00000000000..75c76fd7341 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl @@ -0,0 +1,29 @@ +float float_from_vec4(vec4 vector) +{ + return dot(vector.rgb, vec3(1.0)) / 3.0; +} + +float float_from_vec3(vec3 vector) +{ + return dot(vector, vec3(1.0)) / 3.0; +} + +vec3 vec3_from_vec4(vec4 vector) +{ + return vector.rgb; +} + +vec3 vec3_from_float(float value) +{ + return vec3(value); +} + +vec4 vec4_from_vec3(vec3 vector) +{ + return vec4(vector, 1.0); +} + +vec4 vec4_from_float(float value) +{ + return vec4(vec3(value), 1.0); +} diff --git a/source/blender/compositor/tests/COM_BuffersIterator_test.cc b/source/blender/compositor/tests/COM_BuffersIterator_test.cc index 03748760029..89febb38655 100644 --- a/source/blender/compositor/tests/COM_BuffersIterator_test.cc +++ b/source/blender/compositor/tests/COM_BuffersIterator_test.cc @@ -237,7 +237,7 @@ TEST_F(BuffersIteratorTest, OutputIteration) { set_inputs_enabled(false); test_iteration( - [](BuffersIterator<float> &it, const rcti &UNUSED(area)) { + [](BuffersIterator<float> &it, const rcti & /*area*/) { EXPECT_EQ(it.get_num_inputs(), 0); for (; !it.is_end(); ++it) { const int dummy = it.y * BUFFER_WIDTH + it.x; @@ -247,7 +247,7 @@ TEST_F(BuffersIteratorTest, OutputIteration) it.out[3] = dummy + 4.0f; } }, - [](float *out, Span<const float *> UNUSED(ins), const int x, const int y) { + [](float *out, Span<const float *> /*ins*/, const int x, const int y) { const int dummy = y * BUFFER_WIDTH + x; EXPECT_NEAR(out[0], dummy + 1.0f, FLT_EPSILON); EXPECT_NEAR(out[1], dummy + 2.0f, FLT_EPSILON); @@ -260,7 +260,7 @@ TEST_F(BuffersIteratorTest, OutputAndInputsIteration) { set_inputs_enabled(true); test_iteration( - [](BuffersIterator<float> &it, const rcti &UNUSED(area)) { + [](BuffersIterator<float> &it, const rcti & /*area*/) { EXPECT_EQ(it.get_num_inputs(), NUM_INPUTS); for (; !it.is_end(); ++it) { const float *in1 = it.in(0); @@ -271,7 +271,7 @@ TEST_F(BuffersIteratorTest, OutputAndInputsIteration) it.out[3] = in1[3] - in2[1]; } }, - [](float *out, Span<const float *> ins, const int UNUSED(x), const int UNUSED(y)) { + [](float *out, Span<const float *> ins, const int /*x*/, const int /*y*/) { const float *in1 = ins[0]; const float *in2 = ins[1]; EXPECT_NEAR(out[0], in1[0] + in2[0], FLT_EPSILON); |