{
	"connections": [
		{
			"from": "gen_inputs",
			"from_port": 0,
			"to": "switch",
			"to_port": 0
		},
		{
			"from": "gen_inputs",
			"from_port": 0,
			"to": "buffer_2",
			"to_port": 0
		},
		{
			"from": "buffer_2",
			"from_port": 0,
			"to": "switch",
			"to_port": 1
		},
		{
			"from": "switch",
			"from_port": 0,
			"to": "shader_1",
			"to_port": 0
		},
		{
			"from": "shader_1",
			"from_port": 0,
			"to": "gen_outputs",
			"to_port": 0
		}
	],
	"label": "Generalized Kuwahara",
	"longdesc": "Edge-preserving smoothing filter",
	"name": "generalized_kuwahara",
	"node_position": {
		"x": 0,
		"y": 0
	},
	"nodes": [
		{
			"name": "gen_parameters",
			"node_position": {
				"x": -720,
				"y": -200
			},
			"parameters": {
				"buffer": 1,
				"resolution": 10,
				"size": 6
			},
			"seed": 56582,
			"type": "remote",
			"widgets": [
				{
					"label": "",
					"linked_widgets": [
						{
							"node": "buffer_2",
							"widget": "size"
						},
						{
							"node": "shader_1",
							"widget": "s"
						}
					],
					"longdesc": "Resolution used to sample the input",
					"name": "resolution",
					"shortdesc": "Resolution",
					"type": "linked_control"
				},
				{
					"label": "Size",
					"linked_widgets": [
						{
							"node": "shader_1",
							"widget": "size"
						}
					],
					"name": "size",
					"shortdesc": "Size of the filter",
					"type": "linked_control"
				},
				{
					"configurations": {
						"False": [
							{
								"node": "switch",
								"value": 0,
								"widget": "source"
							}
						],
						"True": [
							{
								"node": "switch",
								"value": 1,
								"widget": "source"
							}
						]
					},
					"label": "Buffer",
					"linked_widgets": [
						{
							"node": "switch",
							"widget": "source"
						}
					],
					"longdesc": "When set, a buffer is used to sample the input before the kuwahara filter",
					"name": "buffer",
					"shortdesc": "Buffer",
					"type": "config_control"
				}
			]
		},
		{
			"name": "gen_outputs",
			"node_position": {
				"x": -400,
				"y": 40
			},
			"parameters": {

			},
			"ports": [
				{
					"group_size": 0,
					"longdesc": "Filtered Image",
					"name": "out",
					"shortdesc": "Output",
					"type": "rgb"
				}
			],
			"seed": -6314,
			"type": "ios"
		},
		{
			"name": "gen_inputs",
			"node_position": {
				"x": -1080,
				"y": 40
			},
			"parameters": {

			},
			"ports": [
				{
					"group_size": 0,
					"longdesc": "Input image",
					"name": "in",
					"shortdesc": "Input",
					"type": "rgb"
				}
			],
			"seed": 12483,
			"seed_locked": true,
			"type": "ios"
		},
		{
			"name": "switch",
			"node_position": {
				"x": -640,
				"y": 140
			},
			"parameters": {
				"choices": 2,
				"outputs": 1,
				"source": 1
			},
			"seed": -53264,
			"type": "switch"
		},
		{
			"name": "buffer_2",
			"node_position": {
				"x": -900,
				"y": 160
			},
			"parameters": {
				"size": 10
			},
			"seed_int": 0,
			"type": "buffer",
			"version": 1
		},
		{
			"name": "shader_1",
			"node_position": {
				"x": -660,
				"y": 40
			},
			"parameters": {
				"s": 10,
				"size": 6
			},
			"seed_int": 0,
			"shader_model": {
				"code": "",
				"global": "",
				"inputs": [
					{
						"default": "vec3(0.0)",
						"function": true,
						"label": "",
						"name": "in",
						"type": "rgb"
					}
				],
				"instance": [
					"// MIT License - Garrett Gunnell",
					"// Based on https://github.com/GarrettGunnell/Post-Processing/blob/main/Assets/Kuwahara%20Filter/GeneralizedKuwahara.shader",
					"vec3 $(name)_generalized_kuwahara(vec2 uv, int _KernelSize) {",
					"\tvec4 m[8];",
					"\tvec3 s[8];",
					"",
					"\tint kernelRadius = _KernelSize;",
					"",
					"\tfloat zeta = 2.0 / float(kernelRadius);",
					"\tconst float _Q = 18.0;",
					"\tconst float zeroCross = 2.0;",
					"\t",
					"\tfloat sinZeroCross = sin(zeroCross);",
					"\tfloat eta = (zeta + cos(zeroCross)) / (sinZeroCross * sinZeroCross);",
					"",
					"\tfor (int k = 0; k < 8; ++k) {",
					"\t\tm[k] = vec4(0.0);",
					"\t\ts[k] = vec3(0.0);",
					"\t}",
					"",
					"\tfor (int y = -kernelRadius; y <= kernelRadius; ++y) {",
					"\t\tfor (int x = -kernelRadius; x <= kernelRadius; ++x) {",
					"\t\t\tvec2 v = vec2(float(x), float(y)) / float(kernelRadius);",
					"\t\t\tvec3 c = $in(uv + vec2(float(x), float(y)) * 1.0/$s);",
					"\t\t\tc = clamp(c,vec3(0.0),vec3(1.0));",
					"\t\t\tfloat sum = 0.0;",
					"\t\t\tfloat w[8];",
					"\t\t\tfloat z, vxx, vyy;",
					"\t\t\t",
					"\t\t\tvxx = zeta - eta * v.x * v.x;",
					"\t\t\tvyy = zeta - eta * v.y * v.y;",
					"\t\t\tz = max(0, v.y + vxx); ",
					"\t\t\tw[0] = z * z;",
					"\t\t\tsum += w[0];",
					"\t\t\tz = max(0, -v.x + vyy); ",
					"\t\t\tw[2] = z * z;",
					"\t\t\tsum += w[2];",
					"\t\t\tz = max(0, -v.y + vxx); ",
					"\t\t\tw[4] = z * z;",
					"\t\t\tsum += w[4];",
					"\t\t\tz = max(0, v.x + vyy); ",
					"\t\t\tw[6] = z * z;",
					"\t\t\tsum += w[6];",
					"\t\t\tv = sqrt(2.0) / 2.0 * vec2(v.x - v.y, v.x + v.y);",
					"\t\t\tvxx = zeta - eta * v.x * v.x;",
					"\t\t\tvyy = zeta - eta * v.y * v.y;",
					"\t\t\tz = max(0, v.y + vxx); ",
					"\t\t\tw[1] = z * z;",
					"\t\t\tsum += w[1];",
					"\t\t\tz = max(0, -v.x + vyy); ",
					"\t\t\tw[3] = z * z;",
					"\t\t\tsum += w[3];",
					"\t\t\tz = max(0, -v.y + vxx); ",
					"\t\t\tw[5] = z * z;",
					"\t\t\tsum += w[5];",
					"\t\t\tz = max(0, v.x + vyy); ",
					"\t\t\tw[7] = z * z;",
					"\t\t\tsum += w[7];",
					"\t\t\t",
					"\t\t\tfloat g = exp(-3.125 * dot(v,v)) / sum;",
					"\t\t\t",
					"\t\t   for (int k = 0; k < 8; ++k) {",
					"\t\t\t\tfloat wk = w[k] * g;",
					"\t\t\t\tm[k] += vec4(c * wk, wk);",
					"\t\t\t\ts[k] += c * c * wk;",
					"\t\t   }",
					"\t\t}",
					"\t}",
					"",
					"\tvec4 o = vec4(0.0);",
					"\t  for (int k = 0; k < 8; ++k) {",
					"\t\tm[k].rgb /= m[k].w;",
					"\t\ts[k] = abs(s[k] / m[k].w - m[k].rgb * m[k].rgb);",
					"",
					"\t\tfloat sigma2 = s[k].r + s[k].g + s[k].b;",
					"\t\tfloat w = 1.0 / (1.0 + pow(1000.0 * sigma2, 0.5 * _Q));",
					"",
					"\t\to += vec4(m[k].rgb * w, w);",
					"\t}",
					"\treturn clamp(o / o.w,vec4(0.0),vec4(1.0)).rgb;",
					"}"
				],
				"name": "generalized_kuwahara",
				"outputs": [
					{
						"rgb": "$(name)_generalized_kuwahara($uv,int(max($size,1.0)))",
						"type": "rgb"
					}
				],
				"parameters": [
					{
						"default": 10,
						"first": 4,
						"label": "",
						"last": 13,
						"name": "s",
						"type": "size"
					},
					{
						"control": "None",
						"default": 10,
						"label": "Size",
						"max": 50,
						"min": 1,
						"name": "size",
						"step": 1,
						"type": "float"
					}
				]
			},
			"type": "shader"
		}
	],
	"parameters": {
		"buffer": 1,
		"resolution": 10,
		"size": 6
	},
	"seed_int": 0,
	"shortdesc": "Generalized Kuwahara Filter",
	"type": "graph"
}