Page MenuHome

Compositor: Add Anti-Aliasing node
ClosedPublic

Authored by Shinsuke Irie (irie) on Dec 12 2016, 7:05 PM.
Tokens
"Love" token, awarded by PeenusButter."Y So Serious" token, awarded by shader."Love" token, awarded by HARDNAX."Yellow Medal" token, awarded by Galagax."Love" token, awarded by Raimund58."Love" token, awarded by TimBrown."Like" token, awarded by Pipeliner."Burninate" token, awarded by Schamph."Love" token, awarded by corpse."Love" token, awarded by hitrpr."Love" token, awarded by bunny."100" token, awarded by Allosteric.

Details

Summary

This is an implementation of Enhanced Subpixel Morphological Antialiasing (SMAA)

The algorithm was proposed by:

Jorge Jimenez, Jose I. Echevarria, Tiago Sousa, Diego Gutierrez

Homepage URL:

http://www.iryoku.com/smaa/

This node provides only SMAA 1x mode, so the operation will be done with no spatial multisampling nor temporal supersampling.

Here is a comparison between existing antialiasing (Scale3x, imported from GIMP) and the Anti-Aliasing Node (SMAA 1x):


SMAA 1x produces much higher quality results than Scale3x.

The existing AA operation seems to be used only for binary images by some other nodes. Using SMAA for binary images needs no important parameter such as "threshold", so we perhaps can switch the operation to SMAA, though that changes existing behavior.

Currently, the node has 3 options:

  • threshold
  • contrast limit
  • corner rounding

Please refer to devtalk thread for discussion about interface: https://devtalk.blender.org/t/compositor-anti-aliasing-node-d2411/17570

Example: Using Anti-Aliasing Node as an alternative of OLM smoother that is widely used in Japanese animation studios:

Notes:

  1. The program code assumes the screen coordinates are DirectX style that the vertical direction is upside-down, so "top" and "bottom" actually represent bottom and top, respectively
  2. smaa_areatex.cpp is a stand-alone software I [Shinsuke Irie] wrote for another project, so its copyright is still owned by me and under MIT-style license, see https://github.com/iRi-E/smaa-cpp
  3. Unfortunately, this patch doesn't include OpenCL support (I'm not familiar with it...), though SMAA is not so slow

Tested on macOS 11.2.1

Test cases (should be in /Users/habibgahbiche/blender-git/lib/tests/compositor/filter/):

Diff Detail

Repository
rB Blender

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

@Shinsuke Irie (irie) Sad to see this patch just hanging here for several years without any conclusion.
Maybe you could submit this(and your other compositor node: https://developer.blender.org/D2493) to Manuel Castilla's rewrite of the Blender compositor:
https://github.com/m-castilla/blender/tree/compositor-up
He has builds on GraphicAll: https://blender.community/c/graphicall, so this way people using those builds could, benefit from your nodes?

Jeroen Bakker (jbakker) updated this revision to Diff 33469.EditedFeb 3 2021, 8:33 AM

Sorry for this late reply. This patch slipped my review queue but was brought to my attention by Sebastian Parborg as anime studios are requesting for it.
@Shinsuke Irie (irie) do you still have interest to continue with this patch? otherwise we need to see if we can find someone who could take it over.

Rebased with latest master.

Did a quick test. And some parts aren't clear from a user side.

  • What does the value input do? Should it be used as an effect interpolation slider? I am not able to see any difference if set to 0 or 1. Looking at the code it is used when detection mode is Value and here it is called SMAADepthEdgeDetectionOperation. Perhaps this socket should only be visible when it makes sense and name it better. Currently will confuse users and developers.
  • Resetting node values aren't supported. Might be a limitation of Blender, not this patch.
  • From user perspective how should the Edges output socket work, or is it only for debugging purposes and should it be hidden from the UI.


I think the UI could deserve some work to be less confusing. Technical part seems ok. Still want to go over it once more.

source/blender/makesdna/DNA_node_types.h
719

No need to abbreviate Could use similar names as in RNA.

723

would prefer to use edge_detection_mode.

724

use_corner_detection

I tested this for a bit and find it quite useful, though indeed rather confusing.
I would get rid of the Corner Rounding checkbox. Instead just use the slider. If it is zero, no rounding is happening, but if rounding is required, the user only has to increase the slider without having to click on a checkbox.
The Value input is indeed doing something, as I found out while trying the last file in the comment from @Michael P. (forest-house) from January 6th 2017. So I guess it's needed.
The Edge output I guess is mostly for debugging? But does it have to be colored? The keying node has an edge output too, but that one is just a value output. Maybe we could use that here as well?
More problematic are the three edge detection methods. I can only comment from a user perspective, not sure if the code is doing anything in the background that I am not aware of.
I tested with colored and with bw images.

  1. Value

When edgedetection is set to Value, the threshold parameter doesn't seem to do anything. If it is anything else than zero, no AA seems to be happening whatsoever. So when using Value ED I suggest to drop the threshold slider. Unless I am missing something here.

  1. Luma and Color seem to be very similar, and using the 2 sliders does indeed do *something*, but from a user perspective it is really not clear if there is a useful difference and what exactly the sliders do. Maybe the two an can be unified somehow?

I suppose most users will probably use it to smooth masks and ID passes, so I suggest to make Value be the default setting, and the user would only need 1 slider for corner rounding.

I'd like to continue working on this if @Shinsuke Irie (irie) is not available. The relevant parts of the node logic have already been copied from https://github.com/iRi-E/smaa-cpp and the basic node code has been made available by @Shinsuke Irie (irie). So I see following remaining tasks:

  1. Node design:
    • define the final interface from a user's perspective
    • clarify what each parameter is for exactly. I'm having a closer look at the paper and code for that.
    • maybe create thread in blenderartists.org for feedback
  2. polish code:
    • adapt to blender/compositor style, e.g. use BLI_ functions
    • add unit tests and possibly bug fixing

That would be great. Note that you can also use devtalk for getting feedback on design issues.

Hi,

Is this still being worked on? We can really use this.

@Habib Gahbiche (zazizizou)
apologize for the ping -- but to clarify, are you actively working on this?

regards

Hi,

Is this still being worked on? We can really use this.

@Habib Gahbiche (zazizizou)
apologize for the ping -- but to clarify, are you actively working on this?

regards

Hi @RR (An0xi),
yes I am. I have already gone through the paper and experimented a bit with current code. There are still a couple things I don't understand and I'm working on this on my free time, so expect a devtalk thread around this weekend.

Simplified interface and updated to latest master. See also devtalk post: https://devtalk.blender.org/t/compositor-anti-aliasing-node-d2411/17570

Is the description up to date? Most interestingly, is the node interface up to date?

We should not be exposing options which do not have clear meaning to artists. I like the simplified 3 slider node from the devtalk proposal though :)

Is the description up to date? Most interestingly, is the node interface up to date?

It is now ;)

ogierm removed a subscriber: ogierm.Feb 15 2021, 11:22 PM

Updates:

Started polishing:

  • renamed variables
  • removed unused code
  • mapping between UI values and algorithm values is done through scalenorm()

Hi @Jeroen Bakker (jbakker), do you think it's possible to add this to 2.93 targets? I'm available to work on this for the next few weeks if you have time for review.

source/blender/compositor/operations/COM_SMAAOperation.cc
259

Add {}

278

add {}

338

add {}

356

add {}

source/blender/makesrna/intern/rna_nodetree.c
8671

Consider using PROP_FACTOR as the fields are a factor.

8681

Local Contrast Adaptation Factor is too long

I would suggest Contrast Limit and perhaps make the default size of the node a bit wider so the text fits.

source/blender/nodes/composite/nodes/node_composite_antialiasing.c
49

use 1.0f;
Not sure if 1.0 is a good default. as you add the node and nothing happens.

50

use floats no doubles.

I don't see any big issues with this patch. Just cleanup. If you're using linux please try to compile with clang tidy enabled.

source/blender/makesdna/DNA_node_types.h
1661

Unused code?

addressed comments from code review:

  • Made node slightly larger to make text fit
  • Renamed "Local Contrast Adaptation Factor" to "Contrast Limit"
  • Removed unused enum
  • Style: added brackets around if
  • Style: Ran make format (excluded changes from unrelated files)
  • Rebased on latest master
source/blender/compositor/operations/COM_SMAAOperation.cc
259

Done

278

done

338

done

source/blender/makesrna/intern/rna_nodetree.c
8681

done

source/blender/nodes/composite/nodes/node_composite_antialiasing.c
49

It depends on the input of course but 1 (equivalent to 0,5 in algorithm) is the value chosen by the paper's authors. I prefer to keep 1 as default and keep testing if that's ok

50

done

  • Fix clang-tidy errors.
This revision is now accepted and ready to land.Mar 17 2021, 10:01 AM
Jeroen Bakker (jbakker) requested changes to this revision.Mar 17 2021, 5:01 PM

It seems to crash for me when adding the node in release mode on linux. Not sure why. Need to look into it.

# Blender 2.93.0, Commit date: 2021-03-17 15:44, Hash 722fa6e4e34f
bpy.context.scene.use_nodes = True  # Property
bpy.ops.node.select(wait_to_deselect_others=True, mouse_x=904, mouse_y=331, extend=False, deselect_all=True)  # Operator
bpy.ops.node.add_node(type="CompositorNodeCryptomatteV2", use_transform=True)  # Operator
bpy.ops.node.translate_attach_remove_on_cancel(TRANSFORM_OT_translate={"value":(-205.731, 337.271, 0), "orient_type":'GLOBAL', "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, False), "mirror":True, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":True, "release_confirm":False, "use_accurate":False, "use_automerge_and_split":False}, NODE_OT_attach={}, NODE_OT_insert_offset={})  # Operator
bpy.ops.node.select(wait_to_deselect_others=True, mouse_x=948, mouse_y=404, extend=False, deselect_all=True)  # Operator
bpy.ops.node.add_node(type="CompositorNodeAntiAliasing", use_transform=True)  # Operator

# backtrace
b(BLI_system_backtrace+0x37) [0x9c94cb7]
b() [0xf3c5fa]
/lib/x86_64-linux-gnu/libc.so.6(+0x46210) [0x7efd43909210]
b(_ZN20NodeOperationBuilder29add_operation_input_constantsEv+0x15a) [0x19007ba]
b(_ZN20NodeOperationBuilder19convertToOperationsEP15ExecutionSystem+0x332) [0x1901d52]
b(_ZN15ExecutionSystemC1EP10RenderDataP5SceneP9bNodeTreebbPK24ColorManagedViewSettingsPK27ColorManagedDisplaySettingsPKc+0x12f) [0x18fed2f]
b(COM_execute+0x164) [0x18fea74]
b() [0x1d2e39e]
b() [0x131e676]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x9609) [0x7efd4405a609]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x43) [0x7efd439e5293]

# Python backtrace
This revision now requires changes to proceed.Mar 17 2021, 5:01 PM

Thanks for testing @Jeroen Bakker (jbakker). It seems to work fine for me in release on mac, also after your changes (built with make release full)

It seems to crash for me when adding the node in release mode on linux. Not sure why. Need to look into it.

...
# Blender 2.93.0, Commit date: 2021-03-17 15:44, Hash 722fa6e4e34f
bpy.ops.node.add_node(type="CompositorNodeCryptomatteV2", use_transform=True)  # Operator
...
bpy.ops.node.add_node(type="CompositorNodeAntiAliasing", use_transform=True)  # Operator
...

How did you produce the crash exactly? I only see CompositorNodeCryptomatte when I add a cryptomatte (no V2 in the name). Also, I'm keeping this patch in sync with the branch compositor-anti-aliasing in case you want to push your changes... Does this build from a few days ago crash for you? https://builder.blender.org/download/compositor-anti-aliasing/

compositor-anti-aliasing works for me, so we should redo the merge from master and the clang tidy cleanups.

  • Reverted changes from clang-tidy
  • Rebase on current master
  • Cleanup: replace NULL with nullptr and add brackets around if

I think we are really close. I would take notice of the clang-tidy stuff as it points out an issue with the code. See

1diff --git a/source/blender/compositor/nodes/COM_AntiAliasingNode.cc b/source/blender/compositor/nodes/COM_AntiAliasingNode.cc
2index 554579306ff..1574804208f 100644
3--- a/source/blender/compositor/nodes/COM_AntiAliasingNode.cc
4+++ b/source/blender/compositor/nodes/COM_AntiAliasingNode.cc
5@@ -29,9 +29,7 @@ void AntiAliasingNode::convertToOperations(NodeConverter &converter,
6 NodeAntiAliasingData *data = (NodeAntiAliasingData *)node->storage;
7
8 /* Edge Detection (First Pass) */
9- SMAAEdgeDetectionOperation *operation1 = nullptr;
10-
11- operation1 = new SMAALumaEdgeDetectionOperation();
12+ SMAALumaEdgeDetectionOperation *operation1 = new SMAALumaEdgeDetectionOperation();
13 operation1->setThreshold(data->threshold);
14 operation1->setLocalContrastAdaptationFactor(data->contrast_limit);
15 converter.addOperation(operation1);
16diff --git a/source/blender/compositor/operations/COM_SMAAOperation.cc b/source/blender/compositor/operations/COM_SMAAOperation.cc
17index 887f7a760f3..e73c2fbb51c 100644
18--- a/source/blender/compositor/operations/COM_SMAAOperation.cc
19+++ b/source/blender/compositor/operations/COM_SMAAOperation.cc
20@@ -156,7 +156,7 @@ static void area_diag(int d1, int d2, int e1, int e2, float weights[2])
21 /* Edge Detection (First Pass) */
22 /*-----------------------------------------------------------------------------*/
23
24-SMAAEdgeDetectionOperation::SMAAEdgeDetectionOperation() : NodeOperation()
25+SMAALumaEdgeDetectionOperation::SMAALumaEdgeDetectionOperation()
26 {
27 this->addInputSocket(DataType::Color); /* image */
28 this->addInputSocket(DataType::Value); /* depth, material ID, etc. */
29@@ -168,31 +168,31 @@ SMAAEdgeDetectionOperation::SMAAEdgeDetectionOperation() : NodeOperation()
30 this->m_contrast_limit = 2.0f;
31 }
32
33-void SMAAEdgeDetectionOperation::initExecution()
34+void SMAALumaEdgeDetectionOperation::initExecution()
35 {
36 this->m_imageReader = this->getInputSocketReader(0);
37 this->m_valueReader = this->getInputSocketReader(1);
38 }
39
40-void SMAAEdgeDetectionOperation::deinitExecution()
41+void SMAALumaEdgeDetectionOperation::deinitExecution()
42 {
43 this->m_imageReader = nullptr;
44 this->m_valueReader = nullptr;
45 }
46
47-void SMAAEdgeDetectionOperation::setThreshold(float threshold)
48+void SMAALumaEdgeDetectionOperation::setThreshold(float threshold)
49 {
50 /* UI values are between 0 and 1 for simplicity but algorithm expects values between 0 and 0.5 */
51 m_threshold = scalenorm(0, 0.5, threshold);
52 }
53
54-void SMAAEdgeDetectionOperation::setLocalContrastAdaptationFactor(float factor)
55+void SMAALumaEdgeDetectionOperation::setLocalContrastAdaptationFactor(float factor)
56 {
57 /* UI values are between 0 and 1 for simplicity but algorithm expects values between 1 and 10 */
58 m_contrast_limit = scalenorm(1, 10, factor);
59 }
60
61-bool SMAAEdgeDetectionOperation::determineDependingAreaOfInterest(
62+bool SMAALumaEdgeDetectionOperation::determineDependingAreaOfInterest(
63 rcti *input, ReadBufferOperation *readOperation, rcti *output)
64 {
65 rcti newInput;
66@@ -287,122 +287,11 @@ void SMAALumaEdgeDetectionOperation::executePixel(float output[4], int x, int y,
67 }
68 }
69
70-/* Color Edge Detection */
71-
72-static float color_delta(const float color1[4], const float color2[4])
73-{
74- return fmaxf(fmaxf(fabsf(color1[0] - color2[0]), fabsf(color1[1] - color2[1])),
75- fabsf(color1[2] - color2[2]));
76-}
77-
78-void SMAAColorEdgeDetectionOperation::executePixel(float output[4], int x, int y, void * /*data*/)
79-{
80- /* Calculate color deltas: */
81- float C[4], Cleft[4], Ctop[4];
82- sample(m_imageReader, x, y, C);
83- sample(m_imageReader, x - 1, y, Cleft);
84- sample(m_imageReader, x, y - 1, Ctop);
85- float Dleft = color_delta(C, Cleft);
86- float Dtop = color_delta(C, Ctop);
87-
88- /* We do the usual threshold: */
89- output[0] = (x > 0 && Dleft >= m_threshold) ? 1.0f : 0.0f;
90- output[1] = (y > 0 && Dtop >= m_threshold) ? 1.0f : 0.0f;
91- output[2] = 0.0f;
92- output[3] = 1.0f;
93-
94- /* Then discard if there is no edge: */
95- if (is_zero_v2(output)) {
96- return;
97- }
98-
99- /* Calculate right and bottom deltas: */
100- float Cright[4], Cbottom[4];
101- sample(m_imageReader, x + 1, y, Cright);
102- sample(m_imageReader, x, y + 1, Cbottom);
103- float Dright = color_delta(C, Cright);
104- float Dbottom = color_delta(C, Cbottom);
105-
106- /* Calculate the maximum delta in the direct neighborhood: */
107- float maxDelta = fmaxf(fmaxf(Dleft, Dright), fmaxf(Dtop, Dbottom));
108-
109- /* Get color used for both left and top edges: */
110- float Clefttop[4];
111- sample(m_imageReader, x - 1, y - 1, Clefttop);
112-
113- /* Left edge */
114- if (output[0] != 0.0f) {
115- /* Calculate deltas around the left pixel: */
116- float Cleftleft[4], Cleftbottom[4];
117- sample(m_imageReader, x - 2, y, Cleftleft);
118- sample(m_imageReader, x - 1, y + 1, Cleftbottom);
119- float Dleftleft = color_delta(Cleft, Cleftleft);
120- float Dlefttop = color_delta(Cleft, Clefttop);
121- float Dleftbottom = color_delta(Cleft, Cleftbottom);
122-
123- /* Calculate the final maximum delta: */
124- maxDelta = fmaxf(maxDelta, fmaxf(Dleftleft, fmaxf(Dlefttop, Dleftbottom)));
125-
126- /* Local contrast adaptation: */
127- if (maxDelta > m_contrast_limit * Dleft) {
128- output[0] = 0.0f;
129- }
130- }
131-
132- /* Top edge */
133- if (output[1] != 0.0f) {
134- /* Calculate deltas around the top pixel: */
135- float Ctoptop[4], Ctopright[4];
136- sample(m_imageReader, x, y - 2, Ctoptop);
137- sample(m_imageReader, x + 1, y - 1, Ctopright);
138- float Dtoptop = color_delta(Ctop, Ctoptop);
139- float Dtopleft = color_delta(Ctop, Clefttop);
140- float Dtopright = color_delta(Ctop, Ctopright);
141-
142- /* Calculate the final maximum delta: */
143- maxDelta = fmaxf(maxDelta, fmaxf(Dtoptop, fmaxf(Dtopleft, Dtopright)));
144-
145- /* Local contrast adaptation: */
146- if (maxDelta > m_contrast_limit * Dtop) {
147- output[1] = 0.0f;
148- }
149- }
150-}
151-
152-/* Depth Edge Detection */
153-
154-void SMAADepthEdgeDetectionOperation::executePixel(float output[4], int x, int y, void * /*data*/)
155-{
156- float here[4], left[4], top[4];
157-
158- sample(m_valueReader, x, y, here);
159- sample(m_valueReader, x - 1, y, left);
160- sample(m_valueReader, x, y - 1, top);
161-
162- output[0] = (x > 0 && fabsf(here[0] - left[0]) >= m_threshold) ? 1.0f : 0.0f;
163- output[1] = (y > 0 && fabsf(here[0] - top[0]) >= m_threshold) ? 1.0f : 0.0f;
164- output[2] = 0.0f;
165- output[3] = 1.0f;
166-}
167-
168-bool SMAADepthEdgeDetectionOperation::determineDependingAreaOfInterest(
169- rcti *input, ReadBufferOperation *readOperation, rcti *output)
170-{
171- rcti newInput;
172-
173- newInput.xmax = input->xmax;
174- newInput.xmin = input->xmin - 1;
175- newInput.ymax = input->ymax;
176- newInput.ymin = input->ymin - 1;
177-
178- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
179-}
180-
181 /*-----------------------------------------------------------------------------*/
182 /* Blending Weight Calculation (Second Pass) */
183 /*-----------------------------------------------------------------------------*/
184
185-SMAABlendingWeightCalculationOperation::SMAABlendingWeightCalculationOperation() : NodeOperation()
186+SMAABlendingWeightCalculationOperation::SMAABlendingWeightCalculationOperation()
187 {
188 this->addInputSocket(DataType::Color); /* edges */
189 this->addOutputSocket(DataType::Color);
190@@ -888,7 +777,7 @@ void SMAABlendingWeightCalculationOperation::detectVerticalCornerPattern(
191 /* Neighborhood Blending (Third Pass) */
192 /*-----------------------------------------------------------------------------*/
193
194-SMAANeighborhoodBlendingOperation::SMAANeighborhoodBlendingOperation() : NodeOperation()
195+SMAANeighborhoodBlendingOperation::SMAANeighborhoodBlendingOperation()
196 {
197 this->addInputSocket(DataType::Color); /* image */
198 this->addInputSocket(DataType::Color); /* blend */
199diff --git a/source/blender/compositor/operations/COM_SMAAOperation.h b/source/blender/compositor/operations/COM_SMAAOperation.h
200index c2fdd9fef72..94e67c8402f 100644
201--- a/source/blender/compositor/operations/COM_SMAAOperation.h
202+++ b/source/blender/compositor/operations/COM_SMAAOperation.h
203@@ -25,7 +25,7 @@
204 /*-----------------------------------------------------------------------------*/
205 /* Edge Detection (First Pass) */
206
207-class SMAAEdgeDetectionOperation : public NodeOperation {
208+class SMAALumaEdgeDetectionOperation : public NodeOperation {
209 protected:
210 SocketReader *m_imageReader;
211 SocketReader *m_valueReader;
212@@ -34,12 +34,12 @@ class SMAAEdgeDetectionOperation : public NodeOperation {
213 float m_contrast_limit;
214
215 public:
216- SMAAEdgeDetectionOperation();
217+ SMAALumaEdgeDetectionOperation();
218
219 /**
220 * the inner loop of this program
221 */
222- virtual void executePixel(float output[4], int x, int y, void *data) = 0;
223+ void executePixel(float output[4], int x, int y, void *data);
224
225 /**
226 * Initialize the execution
227@@ -60,24 +60,6 @@ class SMAAEdgeDetectionOperation : public NodeOperation {
228 rcti *output);
229 };
230
231-class SMAALumaEdgeDetectionOperation : public SMAAEdgeDetectionOperation {
232- public:
233- void executePixel(float output[4], int x, int y, void *data);
234-};
235-
236-class SMAAColorEdgeDetectionOperation : public SMAAEdgeDetectionOperation {
237- public:
238- void executePixel(float output[4], int x, int y, void *data);
239-};
240-
241-class SMAADepthEdgeDetectionOperation : public SMAAEdgeDetectionOperation {
242- public:
243- void executePixel(float output[4], int x, int y, void *data);
244- bool determineDependingAreaOfInterest(rcti *input,
245- ReadBufferOperation *readOperation,
246- rcti *output);
247-};
248-
249 /*-----------------------------------------------------------------------------*/
250 /* Blending Weight Calculation (Second Pass) */
251
for the diff. Many devs have it enabled and won't be able to compile blender when this patch lands.

source/blender/compositor/operations/COM_SMAAOperation.cc
160

initializer for base class 'NodeOperation' is redundant

399

This skips the hierarchy chain (SMAAEdgeDetectionOperation is skipped.)
As SMAADepthEdgeDetectionOperation and SMAAColorEdgeDetectionOperation are unused we should remove both classes.

And consider to merge SMAAEdgeDetectionOperation with SMAALumaEdgeDetectionOperation.

406
892
Jeroen Bakker (jbakker) requested changes to this revision.Mar 22 2021, 9:18 AM
This revision now requires changes to proceed.Mar 22 2021, 9:18 AM
  • created 5 test cases before doing any changes (see revision description)
  • rebase on latest master
  • use one class for edge detection
  • removed redundant init
Habib Gahbiche (zazizizou) added inline comments.
source/blender/compositor/operations/COM_SMAAOperation.cc
160

done

399

done

406

done

This revision is now accepted and ready to land.Mar 29 2021, 7:56 AM
This revision was automatically updated to reflect the committed changes.