[Bf-blender-cvs] [a83b6160257] compositor-anti-aliasing: Compositor: Add Anti-Aliasing node

Habib Gahbiche noreply at git.blender.org
Sun Feb 28 17:45:08 CET 2021


Commit: a83b6160257a013f5d23fd2de7682f5e044fe1d4
Author: Habib Gahbiche
Date:   Wed Feb 10 19:11:23 2021 +0100
Branches: compositor-anti-aliasing
https://developer.blender.org/rBa83b6160257a013f5d23fd2de7682f5e044fe1d4

Compositor: Add Anti-Aliasing node

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
local contrast adaptation factor
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:

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
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
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

===================================================================

M	extern/CMakeLists.txt
A	extern/smaa_areatex/CMakeLists.txt
A	extern/smaa_areatex/README.blender
A	extern/smaa_areatex/smaa_areatex.cpp
M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
A	source/blender/blenkernel/intern/node.c
M	source/blender/blenkernel/intern/node.cc
M	source/blender/compositor/CMakeLists.txt
M	source/blender/compositor/intern/COM_Converter.cpp
A	source/blender/compositor/nodes/COM_AntiAliasingNode.cpp
A	source/blender/compositor/nodes/COM_AntiAliasingNode.h
A	source/blender/compositor/operations/COM_SMAAOperation.cpp
A	source/blender/compositor/operations/COM_SMAAOperation.h
M	source/blender/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_composite.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/composite/nodes/node_composite_antialiasing.c

===================================================================

diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 235c2fa931a..824b2fb0e9c 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -109,3 +109,7 @@ endif()
 if(WITH_MOD_FLUID)
   add_subdirectory(mantaflow)
 endif()
+
+if (WITH_COMPOSITOR)
+	add_subdirectory(smaa_areatex)
+endif()
diff --git a/extern/smaa_areatex/CMakeLists.txt b/extern/smaa_areatex/CMakeLists.txt
new file mode 100644
index 00000000000..2386b0e7b79
--- /dev/null
+++ b/extern/smaa_areatex/CMakeLists.txt
@@ -0,0 +1,26 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2017, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): IRIE Shinsuke
+#
+# ***** END GPL LICENSE BLOCK *****
+
+add_executable(smaa_areatex smaa_areatex.cpp)
diff --git a/extern/smaa_areatex/README.blender b/extern/smaa_areatex/README.blender
new file mode 100644
index 00000000000..9c409142ae8
--- /dev/null
+++ b/extern/smaa_areatex/README.blender
@@ -0,0 +1,5 @@
+Project: smaa-cpp
+URL: https://github.com/iRi-E/smaa-cpp
+License: MIT
+Upstream version: 0.4.0
+Local modifications:
diff --git a/extern/smaa_areatex/smaa_areatex.cpp b/extern/smaa_areatex/smaa_areatex.cpp
new file mode 100644
index 00000000000..971706fd64d
--- /dev/null
+++ b/extern/smaa_areatex/smaa_areatex.cpp
@@ -0,0 +1,1208 @@
+/**
+ * Copyright (C) 2016-2017 IRIE Shinsuke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * smaa_areatex.cpp  version 0.4.0
+ *
+ * This is a part of smaa-cpp that is an implementation of
+ * Enhanced Subpixel Morphological Antialiasing (SMAA) written in C++.
+ *
+ * This program is C++ rewrite of AreaTex.py included in the original
+ * SMAA ditribution:
+ *
+ *   https://github.com/iryoku/smaa/tree/master/Scripts
+ */
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include <cmath>
+
+/*------------------------------------------------------------------------------*/
+/* Type Definitions */
+
+class Int2;
+class Dbl2;
+
+class Int2 {
+public:
+	int x, y;
+
+	Int2() { this->x = this->y = 0; }
+	Int2(int x) { this->x = this->y = x; }
+	Int2(int x, int y) { this->x = x; this->y = y; }
+
+	operator Dbl2();
+
+	Int2 operator + (Int2 other) { return Int2(x + other.x, y + other.y); }
+	Int2 operator * (Int2 other) { return Int2(x * other.x, y * other.y); }
+};
+
+class Dbl2 {
+public:
+	double x, y;
+
+	Dbl2() { this->x = this->y = 0.0; }
+	Dbl2(double x) { this->x = this->y = x; }
+	Dbl2(double x, double y) { this->x = x; this->y = y; }
+
+	Dbl2 apply(double (* func)(double)) { return Dbl2(func(x), func(y)); }
+
+	operator Int2();
+
+	Dbl2 operator + (Dbl2 other) { return Dbl2(x + other.x, y + other.y); }
+	Dbl2 operator - (Dbl2 other) { return Dbl2(x - other.x, y - other.y); }
+	Dbl2 operator * (Dbl2 other) { return Dbl2(x * other.x, y * other.y); }
+	Dbl2 operator / (Dbl2 other) { return Dbl2(x / other.x, y / other.y); }
+	Dbl2 operator += (Dbl2 other) { return Dbl2(x += other.x, y += other.y); }
+	bool operator == (Dbl2 other) { return (x == other.x && y == other.y); }
+};
+
+Int2::operator Dbl2() { return Dbl2((double)x, (double)y); }
+Dbl2::operator Int2() { return Int2((int)x, (int)y); }
+
+/*------------------------------------------------------------------------------*/
+/* Data to Calculate Areatex */
+
+/* Texture sizes: */
+/* (it's quite possible that this is not easily configurable) */
+static const int SUBSAMPLES_ORTHO = 7;
+static const int SUBSAMPLES_DIAG  = 5;
+static const int MAX_DIST_ORTHO_COMPAT = 16;
+static const int MAX_DIST_ORTHO = 20;
+static const int MAX_DIST_DIAG  = 20;
+static const int TEX_SIZE_ORTHO = 80; /* 16 * 5 slots = 80 */
+static const int TEX_SIZE_DIAG  = 80; /* 20 * 4 slots = 80 */
+
+/* Number of samples for calculating areas in the diagonal textures: */
+/* (diagonal areas are calculated using brute force sampling) */
+static const int SAMPLES_DIAG = 30;
+
+/* Maximum distance for smoothing u-shapes: */
+static const int SMOOTH_MAX_DISTANCE = 32;
+
+/*------------------------------------------------------------------------------*/
+/* Offset Tables */
+
+/* Offsets for subsample rendering */
+static const double subsample_offsets_ortho[SUBSAMPLES_ORTHO] = {
+	0.0,    /* 0 */
+	-0.25,  /* 1 */
+	0.25,   /* 2 */
+	-0.125, /* 3 */
+	0.125,  /* 4 */
+	-0.375, /* 5 */
+	0.375   /* 6 */
+};
+
+static const Dbl2 subsample_offsets_diag[SUBSAMPLES_DIAG] = {
+	{ 0.00,   0.00},  /* 0 */
+	{ 0.25,  -0.25},  /* 1 */
+	{-0.25,   0.25},  /* 2 */
+	{ 0.125, -0.125}, /* 3 */
+	{-0.125,  0.125}  /* 4 */
+};
+
+/* Mapping offsets for placing each pattern subtexture into its place */
+enum edgesorthoIndices
+{
+	EDGESORTHO_NONE_NONE = 0,
+	EDGESORTHO_NONE_NEGA = 1,
+	EDGESORTHO_NONE_POSI = 2,
+	EDGESORTHO_NONE_BOTH = 3,
+	EDGESORTHO_NEGA_NONE = 4,
+	EDGESORTHO_NEGA_NEGA = 5,
+	EDGESORTHO_NEGA_POSI = 6,
+	EDGESORTHO_NEGA_BOTH = 7,
+	EDGESORTHO_POSI_NONE = 8,
+	EDGESORTHO_POSI_NEGA = 9,
+	EDGESORTHO_POSI_POSI = 10,
+	EDGESORTHO_POSI_BOTH = 11,
+	EDGESORTHO_BOTH_NONE = 12,
+	EDGESORTHO_BOTH_NEGA = 13,
+	EDGESORTHO_BOTH_POSI = 14,
+	EDGESORTHO_BOTH_BOTH = 15,
+};
+
+static const Int2 edgesortho_compat[16] = {
+	{0, 0}, {0, 1}, {0, 3}, {0, 4}, {1, 0}, {1, 1}, {1, 3}, {1, 4},
+	{3, 0}, {3, 1}, {3, 3}, {3, 4}, {4, 0}, {4, 1}, {4, 3}, {4, 4}
+};
+
+static const Int2 edgesortho[16] = {
+	{0, 0}, {0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 1}, {1, 2}, {1, 3},
+	{2, 0}, {2, 1}, {2, 2}, {2, 3}, {3, 0}, {3, 1}, {3, 2}, {3, 3}
+};
+
+enum edgesdiagIndices
+{
+	EDGESDIAG_NONE_NONE = 0,
+	EDGESDIAG_NONE_VERT = 1,
+	EDGESDIAG_NONE_HORZ = 2,
+	EDGESDIAG_NONE_BOTH = 3,
+	EDGESDIAG_VERT_NONE = 4,
+	EDGESDIAG_VERT_VERT = 5,
+	EDGESDIAG_VERT_HORZ = 6,
+	EDGESDIAG_VERT_BOTH = 7,
+	EDGESDIAG_HORZ_NONE = 8,
+	EDGESDIAG_HORZ_VERT = 9,
+	EDGESDIAG_HORZ_HORZ = 10,
+	EDGESDIAG_HORZ_BOTH = 11,
+	EDGESDIAG_BOTH_NONE = 12,
+	EDGESDIAG_BOTH_VERT = 13,
+	EDGESDIAG_BOTH_HORZ = 14,
+	EDGESDIAG_BOTH_BOTH = 15,
+};
+
+static const Int2 edgesdiag[16] = {
+	{0, 0}, {0, 1}, {0, 2}, {0, 3}, {1, 0}, {1, 1}, {1, 2}, {1, 3},
+	{2, 0}, {2, 1}, {2, 2}, {2, 3}, {3, 0}, {3, 1}, {3, 2}, {3, 3}
+};
+
+/*------------------------------------------------------------------------------*/
+/* Miscellaneous Utility Functions */
+
+/* Linear interpolation: */
+static Dbl2 lerp(Dbl2 a, Dbl2 b, double p)
+{
+	return a + (b - a) * Dbl2(p);
+}
+
+/* Saturates a value to [0..1] range: */
+static double saturate(double x)
+{
+	return 0.0 < x ? (x < 1.0 ? x : 1.0) : 0.0;
+}
+
+/*------------------------------------------------------------------------------*/
+/* Horizontal/Vertical Areas */
+
+class AreaOrtho {
+	double m_data[SUBSAMPLES_ORTHO][TEX_SIZE_ORTHO][TEX_SIZE_ORTHO][2];
+	bool m_compat;
+	bool m_orig_u;
+public:
+	AreaOrtho(bool compat, bool orig_u) : m_compat(compat), m_orig_u(orig_u) {}
+
+	double *getData() { return (double *)&m_data; }
+	Dbl2 getPixel(int offset_index, Int2 coords) {
+		return Dbl2(m_data[offset_index][coords.y][coords.x][0],
+			    m_data[offset_index][coords.y][coords.x][1]);
+	}
+
+	void areaTex(int offset_index);
+private:
+	void putPixel(int offset_index, Int2 coords, Dbl2 pixel) {
+		m_data[offset_index][coords.y][coords.x][0] = pixel.x;
+		m_data[offset_index][coords.y][coords.x][1] = pixel.y;
+	}
+
+	Dbl2 smoothArea(double d, Dbl2 a1, Dbl2 a2);
+	Dbl2 makeQuad(int x, double d, double o);
+	Dbl2 area(Dbl2 p1, Dbl2 p2, int x);
+	Dbl2 calculate(int pattern, int left, int right, double offset);
+};
+
+/* Smoothing function for small u-patterns: */
+Dbl2 AreaOrtho::smoothArea(double d, Dbl2 a1, Dbl2 a2)
+{
+	Dbl2 b1 = (a1 * Dbl2(2.0)).apply(sqrt) * Dbl2(0.5);
+	Dbl2 b2 = (a2 * Dbl2(2.0)).apply(sqrt) * Dbl2(0.5);
+	double p = saturate(d / (double)SMOOTH_MAX_DISTANCE);
+	return lerp(b1, a1, p) + lerp(b2, a2, p);
+}
+
+/* Smoothing u-patterns by quadratic function: */
+Dbl2 AreaOrtho::makeQuad(int x, double d, double o)
+{
+	double r = (double)x;
+
+	/* fmin() below is a trick to smooth tiny u-patterns: */
+	return Dbl2(r, (1.0 - fmin(4.0, d) * r * (d - r) / (d * d)) * o);
+}
+
+/* Calculates the area under the line p1->p2, for the pixel x..x+1: */
+Dbl2 AreaOrtho::area(Dbl2 p1, Dbl2 p2, int x)
+{
+	Dbl2 d = p2 - p1;
+	double x1 = (double)x;
+	double x2 = x1 + 1.0;
+
+	if ((x1 >= p1.x && x1 < p2.x) || (x2 > p1.x && x2 <= p2.x)) { /* inside? */
+		double y1 = p1.y + (x1 - p1.x) * d.y / d.x;
+		double y2 = p1.y + (x2 - p1.x) * d.y / d.x;
+
+		if ((copysign(1.0, y1) == cop

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list