Compositor: Port GLSL SMAA to CPU compositor #119414

Merged
Omar Emara merged 21 commits from OmarEmaraDev/blender:smaa-cpp into main 2024-03-25 14:21:12 +01:00
13 changed files with 1496 additions and 2150 deletions

View File

@ -104,10 +104,6 @@ if(WITH_MOD_FLUID)
add_subdirectory(mantaflow)
endif()
if(WITH_COMPOSITOR_CPU)
add_subdirectory(smaa_areatex)
endif()
if(WITH_VULKAN_BACKEND)
add_subdirectory(vulkan_memory_allocator)
endif()

View File

@ -1,5 +0,0 @@
# SPDX-FileCopyrightText: 2017 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
add_executable(smaa_areatex smaa_areatex.cpp)

View File

@ -1,5 +0,0 @@
Project: smaa-cpp
URL: https://github.com/iRi-E/smaa-cpp
License: MIT
Upstream version: 0.4.0
Local modifications:

File diff suppressed because it is too large Load Diff

View File

@ -584,20 +584,6 @@ if(WITH_COMPOSITOR_CPU)
${CMAKE_CURRENT_BINARY_DIR}/operations
)
set(GENSRC_DIR ${CMAKE_CURRENT_BINARY_DIR}/operations)
set(GENSRC ${GENSRC_DIR}/COM_SMAAAreaTexture.h)
add_custom_command(
OUTPUT ${GENSRC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${GENSRC_DIR}
COMMAND "$<TARGET_FILE:smaa_areatex>" ${GENSRC}
DEPENDS smaa_areatex
)
list(APPEND SRC
${GENSRC}
)
unset(GENSRC)
unset(GENSRC_DIR)
if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
add_definitions(-DOIDN_STATIC_LIB)

View File

@ -7,37 +7,41 @@
namespace blender::compositor {
/* Blender encodes the threshold in the [0, 1] range, while the SMAA algorithm expects it in
* the [0, 0.5] range. */
static float get_threshold(const NodeAntiAliasingData *data)
{
return data->threshold / 2.0f;
}
/* Blender encodes the local contrast adaptation factor in the [0, 1] range, while the SMAA
* algorithm expects it in the [0, 10] range. */
static float get_local_contrast_adaptation_factor(const NodeAntiAliasingData *data)
{
return data->contrast_limit * 10.0f;
}
/* Blender encodes the corner rounding factor in the float [0, 1] range, while the SMAA algorithm
* expects it in the integer [0, 100] range. */
static int get_corner_rounding(const NodeAntiAliasingData *data)
{
return int(data->corner_rounding * 100.0f);
}
void AntiAliasingNode::convert_to_operations(NodeConverter &converter,
const CompositorContext & /*context*/) const
{
const bNode *node = this->get_bnode();
const NodeAntiAliasingData *data = (const NodeAntiAliasingData *)node->storage;
/* Edge Detection (First Pass) */
SMAAEdgeDetectionOperation *operation1 = nullptr;
SMAAOperation *operation = new SMAAOperation();
operation->set_threshold(get_threshold(data));
operation->set_local_contrast_adaptation_factor(get_local_contrast_adaptation_factor(data));
operation->set_corner_rounding(get_corner_rounding(data));
converter.add_operation(operation);
operation1 = new SMAAEdgeDetectionOperation();
operation1->set_threshold(data->threshold);
operation1->set_local_contrast_adaptation_factor(data->contrast_limit);
converter.add_operation(operation1);
converter.map_input_socket(get_input_socket(0), operation1->get_input_socket(0));
/* Blending Weight Calculation Pixel Shader (Second Pass) */
SMAABlendingWeightCalculationOperation *operation2 =
new SMAABlendingWeightCalculationOperation();
operation2->set_corner_rounding(data->corner_rounding);
converter.add_operation(operation2);
converter.add_link(operation1->get_output_socket(), operation2->get_input_socket(0));
/* Neighborhood Blending Pixel Shader (Third Pass) */
SMAANeighborhoodBlendingOperation *operation3 = new SMAANeighborhoodBlendingOperation();
converter.add_operation(operation3);
converter.map_input_socket(get_input_socket(0), operation3->get_input_socket(0));
converter.add_link(operation2->get_output_socket(), operation3->get_input_socket(1));
converter.map_output_socket(get_output_socket(0), operation3->get_output_socket());
converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0));
converter.map_output_socket(get_output_socket(0), operation->get_output_socket());
}
} // namespace blender::compositor

View File

@ -18,28 +18,13 @@ void CornerPinNode::convert_to_operations(NodeConverter &converter,
PlaneCornerPinMaskOperation *plane_mask_operation = new PlaneCornerPinMaskOperation();
converter.add_operation(plane_mask_operation);
SMAAEdgeDetectionOperation *smaa_edge_detection = new SMAAEdgeDetectionOperation();
converter.add_operation(smaa_edge_detection);
SMAAOperation *smaa_operation = new SMAAOperation();
converter.add_operation(smaa_operation);
converter.add_link(plane_mask_operation->get_output_socket(),
smaa_edge_detection->get_input_socket(0));
smaa_operation->get_input_socket(0));
SMAABlendingWeightCalculationOperation *smaa_blending_weights =
new SMAABlendingWeightCalculationOperation();
converter.add_operation(smaa_blending_weights);
converter.add_link(smaa_edge_detection->get_output_socket(),
smaa_blending_weights->get_input_socket(0));
SMAANeighborhoodBlendingOperation *smaa_neighborhood = new SMAANeighborhoodBlendingOperation();
converter.add_operation(smaa_neighborhood);
converter.add_link(plane_mask_operation->get_output_socket(),
smaa_neighborhood->get_input_socket(0));
converter.add_link(smaa_blending_weights->get_output_socket(),
smaa_neighborhood->get_input_socket(1));
converter.map_output_socket(this->get_output_socket(1), smaa_neighborhood->get_output_socket());
converter.map_output_socket(this->get_output_socket(1), smaa_operation->get_output_socket());
PlaneCornerPinWarpImageOperation *warp_image_operation = new PlaneCornerPinWarpImageOperation();
converter.add_operation(warp_image_operation);
@ -62,7 +47,7 @@ void CornerPinNode::convert_to_operations(NodeConverter &converter,
converter.add_operation(set_alpha_operation);
converter.add_link(warp_image_operation->get_output_socket(),
set_alpha_operation->get_input_socket(0));
converter.add_link(smaa_neighborhood->get_output_socket(),
converter.add_link(smaa_operation->get_output_socket(),
set_alpha_operation->get_input_socket(1));
converter.map_output_socket(this->get_output_socket(0),
set_alpha_operation->get_output_socket());

View File

@ -37,26 +37,10 @@ void DilateErodeNode::convert_to_operations(NodeConverter &converter,
converter.map_input_socket(get_input_socket(0), operation->get_input_socket(0));
if (editor_node->custom3 < 2.0f) {
SMAAEdgeDetectionOperation *smaa_edge_detection = new SMAAEdgeDetectionOperation();
converter.add_operation(smaa_edge_detection);
converter.add_link(operation->get_output_socket(), smaa_edge_detection->get_input_socket(0));
SMAABlendingWeightCalculationOperation *smaa_blending_weights =
new SMAABlendingWeightCalculationOperation();
converter.add_operation(smaa_blending_weights);
converter.add_link(smaa_edge_detection->get_output_socket(),
smaa_blending_weights->get_input_socket(0));
SMAANeighborhoodBlendingOperation *smaa_neighborhood =
new SMAANeighborhoodBlendingOperation();
converter.add_operation(smaa_neighborhood);
converter.add_link(operation->get_output_socket(), smaa_neighborhood->get_input_socket(0));
converter.add_link(smaa_blending_weights->get_output_socket(),
smaa_neighborhood->get_input_socket(1));
converter.map_output_socket(get_output_socket(0), smaa_neighborhood->get_output_socket());
SMAAOperation *smaa_operation = new SMAAOperation();
converter.add_operation(smaa_operation);
converter.add_link(operation->get_output_socket(), smaa_operation->get_input_socket(0));
converter.map_output_socket(get_output_socket(0), smaa_operation->get_output_socket());
}
else {
converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0));

View File

@ -27,27 +27,10 @@ void IDMaskNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(get_output_socket(0), operation->get_output_socket(0));
}
else {
SMAAEdgeDetectionOperation *operation1 = nullptr;
operation1 = new SMAAEdgeDetectionOperation();
converter.add_operation(operation1);
converter.add_link(operation->get_output_socket(0), operation1->get_input_socket(0));
/* Blending Weight Calculation Pixel Shader (Second Pass). */
SMAABlendingWeightCalculationOperation *operation2 =
new SMAABlendingWeightCalculationOperation();
converter.add_operation(operation2);
converter.add_link(operation1->get_output_socket(), operation2->get_input_socket(0));
/* Neighborhood Blending Pixel Shader (Third Pass). */
SMAANeighborhoodBlendingOperation *operation3 = new SMAANeighborhoodBlendingOperation();
converter.add_operation(operation3);
converter.add_link(operation->get_output_socket(0), operation3->get_input_socket(0));
converter.add_link(operation2->get_output_socket(), operation3->get_input_socket(1));
converter.map_output_socket(get_output_socket(0), operation3->get_output_socket());
SMAAOperation *smaa_operation = new SMAAOperation();
converter.add_operation(smaa_operation);
converter.add_link(operation->get_output_socket(0), smaa_operation->get_input_socket(0));
converter.map_output_socket(get_output_socket(0), smaa_operation->get_output_socket());
}
}

View File

@ -35,28 +35,13 @@ void PlaneTrackDeformNode::convert_to_operations(NodeConverter &converter,
}
converter.add_operation(plane_mask_operation);
SMAAEdgeDetectionOperation *smaa_edge_detection = new SMAAEdgeDetectionOperation();
converter.add_operation(smaa_edge_detection);
SMAAOperation *smaa_operation = new SMAAOperation();
converter.add_operation(smaa_operation);
converter.add_link(plane_mask_operation->get_output_socket(),
smaa_edge_detection->get_input_socket(0));
smaa_operation->get_input_socket(0));
SMAABlendingWeightCalculationOperation *smaa_blending_weights =
new SMAABlendingWeightCalculationOperation();
converter.add_operation(smaa_blending_weights);
converter.add_link(smaa_edge_detection->get_output_socket(),
smaa_blending_weights->get_input_socket(0));
SMAANeighborhoodBlendingOperation *smaa_neighborhood = new SMAANeighborhoodBlendingOperation();
converter.add_operation(smaa_neighborhood);
converter.add_link(plane_mask_operation->get_output_socket(),
smaa_neighborhood->get_input_socket(0));
converter.add_link(smaa_blending_weights->get_output_socket(),
smaa_neighborhood->get_input_socket(1));
converter.map_output_socket(this->get_output_socket(1), smaa_neighborhood->get_output_socket());
converter.map_output_socket(this->get_output_socket(1), smaa_operation->get_output_socket());
PlaneTrackWarpImageOperation *warp_image_operation = new PlaneTrackWarpImageOperation();
warp_image_operation->set_movie_clip(clip);
@ -75,7 +60,7 @@ void PlaneTrackDeformNode::convert_to_operations(NodeConverter &converter,
converter.add_operation(set_alpha_operation);
converter.add_link(warp_image_operation->get_output_socket(),
set_alpha_operation->get_input_socket(0));
converter.add_link(smaa_neighborhood->get_output_socket(),
converter.add_link(smaa_operation->get_output_socket(),
set_alpha_operation->get_input_socket(1));
converter.map_output_socket(this->get_output_socket(0),
set_alpha_operation->get_output_socket());

View File

@ -54,25 +54,10 @@ void ZCombineNode::convert_to_operations(NodeConverter &converter,
converter.map_input_socket(get_input_socket(3), maskoperation->get_input_socket(1));
/* Step 2 anti alias mask bit of an expensive operation, but does the trick. */
SMAAEdgeDetectionOperation *smaa_edge_detection = new SMAAEdgeDetectionOperation();
converter.add_operation(smaa_edge_detection);
SMAAOperation *smaa_operation = new SMAAOperation();
converter.add_operation(smaa_operation);
converter.add_link(maskoperation->get_output_socket(),
smaa_edge_detection->get_input_socket(0));
SMAABlendingWeightCalculationOperation *smaa_blending_weights =
new SMAABlendingWeightCalculationOperation();
converter.add_operation(smaa_blending_weights);
converter.add_link(smaa_edge_detection->get_output_socket(),
smaa_blending_weights->get_input_socket(0));
SMAANeighborhoodBlendingOperation *smaa_neighborhood = new SMAANeighborhoodBlendingOperation();
converter.add_operation(smaa_neighborhood);
converter.add_link(maskoperation->get_output_socket(), smaa_neighborhood->get_input_socket(0));
converter.add_link(smaa_blending_weights->get_output_socket(),
smaa_neighborhood->get_input_socket(1));
converter.add_link(maskoperation->get_output_socket(), smaa_operation->get_input_socket(0));
/* use mask to blend between the input colors. */
ZCombineMaskOperation *zcombineoperation = this->get_bnode()->custom1 ?
@ -80,7 +65,7 @@ void ZCombineNode::convert_to_operations(NodeConverter &converter,
new ZCombineMaskOperation();
converter.add_operation(zcombineoperation);
converter.add_link(smaa_neighborhood->get_output_socket(),
converter.add_link(smaa_operation->get_output_socket(),
zcombineoperation->get_input_socket(0));
converter.map_input_socket(get_input_socket(0), zcombineoperation->get_input_socket(1));
converter.map_input_socket(get_input_socket(2), zcombineoperation->get_input_socket(2));

File diff suppressed because it is too large Load Diff

View File

@ -4,89 +4,38 @@
#pragma once
#include "COM_MultiThreadedOperation.h"
#include "COM_NodeOperation.h"
namespace blender::compositor {
/*-----------------------------------------------------------------------------*/
/* Edge Detection (First Pass) */
class SMAAEdgeDetectionOperation : public MultiThreadedOperation {
class SMAAOperation : public NodeOperation {
protected:
float threshold_;
float contrast_limit_;
float threshold_ = 0.1f;
float local_contrast_adaptation_factor_ = 2.0f;
int corner_rounding_ = 25;
public:
SMAAEdgeDetectionOperation();
SMAAOperation();
void set_threshold(float threshold);
void set_threshold(float threshold)
{
threshold_ = threshold;
}
void set_local_contrast_adaptation_factor(float factor);
void set_local_contrast_adaptation_factor(float factor)
{
local_contrast_adaptation_factor_ = factor;
}
void set_corner_rounding(int corner_rounding)
{
corner_rounding_ = corner_rounding;
}
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
/*-----------------------------------------------------------------------------*/
/* Blending Weight Calculation (Second Pass) */
class SMAABlendingWeightCalculationOperation : public MultiThreadedOperation {
private:
std::function<void(int x, int y, float *out)> sample_image_fn_;
int corner_rounding_;
public:
SMAABlendingWeightCalculationOperation();
void set_corner_rounding(float rounding);
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
void update_memory_buffer_started(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
private:
/* Diagonal Search Functions */
/**
* These functions allows to perform diagonal pattern searches.
*/
int search_diag1(int x, int y, int dir, bool *r_found);
int search_diag2(int x, int y, int dir, bool *r_found);
/**
* This searches for diagonal patterns and returns the corresponding weights.
*/
void calculate_diag_weights(int x, int y, const float edges[2], float weights[2]);
bool is_vertical_search_unneeded(int x, int y);
/* Horizontal/Vertical Search Functions */
int search_xleft(int x, int y);
int search_xright(int x, int y);
int search_yup(int x, int y);
int search_ydown(int x, int y);
/* Corner Detection Functions */
void detect_horizontal_corner_pattern(
float weights[2], int left, int right, int y, int d1, int d2);
void detect_vertical_corner_pattern(
float weights[2], int x, int top, int bottom, int d1, int d2);
};
/*-----------------------------------------------------------------------------*/
/* Neighborhood Blending (Third Pass) */
class SMAANeighborhoodBlendingOperation : public MultiThreadedOperation {
public:
SMAANeighborhoodBlendingOperation();
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
void update_memory_buffer(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor