ComfyUI/blueprints/Image Blur.json
Terry Jia 50076f3439
format blueprint (#13315)
Co-authored-by: guill <jacob.e.segal@gmail.com>
2026-04-06 23:33:55 -04:00

382 lines
12 KiB
JSON

{
"revision": 0,
"last_node_id": 8,
"last_link_id": 0,
"nodes": [
{
"id": 8,
"type": "198632a3-ee76-4aab-9ce7-a69c624eaff9",
"pos": [
4470,
-1840
],
"size": [
210,
82
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"label": "image",
"localized_name": "images.image0",
"name": "images.image0",
"type": "IMAGE",
"link": null
}
],
"outputs": [
{
"label": "blurred_image",
"localized_name": "IMAGE0",
"name": "IMAGE0",
"type": "IMAGE",
"links": []
}
],
"properties": {
"proxyWidgets": [
[
"12",
"choice"
],
[
"10",
"value"
]
]
},
"widgets_values": [],
"title": "Image Blur"
}
],
"links": [],
"version": 0.4,
"definitions": {
"subgraphs": [
{
"id": "198632a3-ee76-4aab-9ce7-a69c624eaff9",
"version": 1,
"state": {
"lastGroupId": 0,
"lastNodeId": 12,
"lastLinkId": 11,
"lastRerouteId": 0
},
"revision": 0,
"config": {},
"name": "Image Blur",
"inputNode": {
"id": -10,
"bounding": [
3540,
-2445,
120,
60
]
},
"outputNode": {
"id": -20,
"bounding": [
4620,
-2445,
121.11666870117188,
60
]
},
"inputs": [
{
"id": "7ff2a402-6b11-45e8-a92a-7158d216520a",
"name": "images.image0",
"type": "IMAGE",
"linkIds": [
9
],
"localized_name": "images.image0",
"label": "image",
"pos": [
3640,
-2425
]
}
],
"outputs": [
{
"id": "80a8e19e-ffd9-44a5-90f2-710815a5b063",
"name": "IMAGE0",
"type": "IMAGE",
"linkIds": [
3
],
"localized_name": "IMAGE0",
"label": "blurred_image",
"pos": [
4640,
-2425
]
}
],
"widgets": [],
"nodes": [
{
"id": 12,
"type": "CustomCombo",
"pos": [
3720,
-2620
],
"size": [
270,
174
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"label": "blur_type",
"localized_name": "choice",
"name": "choice",
"type": "COMBO",
"widget": {
"name": "choice"
},
"link": null
}
],
"outputs": [
{
"localized_name": "STRING",
"name": "STRING",
"type": "STRING",
"links": null
},
{
"localized_name": "INDEX",
"name": "INDEX",
"type": "INT",
"links": [
11
]
}
],
"properties": {
"Node name for S&R": "CustomCombo"
},
"widgets_values": [
"Gaussian",
0,
"Gaussian",
"Box",
"Radial",
""
]
},
{
"id": 10,
"type": "PrimitiveFloat",
"pos": [
4020,
-2780
],
"size": [
270,
58
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"label": "strength",
"localized_name": "value",
"name": "value",
"type": "FLOAT",
"widget": {
"name": "value"
},
"link": null
}
],
"outputs": [
{
"localized_name": "FLOAT",
"name": "FLOAT",
"type": "FLOAT",
"links": [
10
]
}
],
"properties": {
"Node name for S&R": "PrimitiveFloat",
"max": 100,
"min": 0
},
"widgets_values": [
20
]
},
{
"id": 1,
"type": "GLSLShader",
"pos": [
4020,
-2670
],
"size": [
430,
212
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"label": "image0",
"localized_name": "images.image0",
"name": "images.image0",
"type": "IMAGE",
"link": 9
},
{
"label": "image1",
"localized_name": "images.image1",
"name": "images.image1",
"shape": 7,
"type": "IMAGE",
"link": null
},
{
"label": "u_float0",
"localized_name": "floats.u_float0",
"name": "floats.u_float0",
"shape": 7,
"type": "FLOAT",
"link": 10
},
{
"label": "u_float1",
"localized_name": "floats.u_float1",
"name": "floats.u_float1",
"shape": 7,
"type": "FLOAT",
"link": null
},
{
"label": "u_int0",
"localized_name": "ints.u_int0",
"name": "ints.u_int0",
"shape": 7,
"type": "INT",
"link": 11
},
{
"label": "u_int1",
"localized_name": "ints.u_int1",
"name": "ints.u_int1",
"shape": 7,
"type": "INT",
"link": null
},
{
"localized_name": "fragment_shader",
"name": "fragment_shader",
"type": "STRING",
"widget": {
"name": "fragment_shader"
},
"link": null
},
{
"localized_name": "size_mode",
"name": "size_mode",
"type": "COMFY_DYNAMICCOMBO_V3",
"widget": {
"name": "size_mode"
},
"link": null
}
],
"outputs": [
{
"localized_name": "IMAGE0",
"name": "IMAGE0",
"type": "IMAGE",
"links": [
3
]
},
{
"localized_name": "IMAGE1",
"name": "IMAGE1",
"type": "IMAGE",
"links": []
},
{
"localized_name": "IMAGE2",
"name": "IMAGE2",
"type": "IMAGE",
"links": []
},
{
"localized_name": "IMAGE3",
"name": "IMAGE3",
"type": "IMAGE",
"links": []
}
],
"properties": {
"Node name for S&R": "GLSLShader"
},
"widgets_values": [
"#version 300 es\n#pragma passes 2\nprecision highp float;\n\n// Blur type constants\nconst int BLUR_GAUSSIAN = 0;\nconst int BLUR_BOX = 1;\nconst int BLUR_RADIAL = 2;\n\n// Radial blur config\nconst int RADIAL_SAMPLES = 12;\nconst float RADIAL_STRENGTH = 0.0003;\n\nuniform sampler2D u_image0;\nuniform vec2 u_resolution;\nuniform int u_int0; // Blur type (BLUR_GAUSSIAN, BLUR_BOX, BLUR_RADIAL)\nuniform float u_float0; // Blur radius/amount\nuniform int u_pass; // Pass index (0 = horizontal, 1 = vertical)\n\nin vec2 v_texCoord;\nlayout(location = 0) out vec4 fragColor0;\n\nfloat gaussian(float x, float sigma) {\n return exp(-(x * x) / (2.0 * sigma * sigma));\n}\n\nvoid main() {\n vec2 texelSize = 1.0 / u_resolution;\n float radius = max(u_float0, 0.0);\n\n // Radial (angular) blur - single pass, doesn't use separable\n if (u_int0 == BLUR_RADIAL) {\n // Only execute on first pass\n if (u_pass > 0) {\n fragColor0 = texture(u_image0, v_texCoord);\n return;\n }\n\n vec2 center = vec2(0.5);\n vec2 dir = v_texCoord - center;\n float dist = length(dir);\n\n if (dist < 1e-4) {\n fragColor0 = texture(u_image0, v_texCoord);\n return;\n }\n\n vec4 sum = vec4(0.0);\n float totalWeight = 0.0;\n float angleStep = radius * RADIAL_STRENGTH;\n\n dir /= dist;\n\n float cosStep = cos(angleStep);\n float sinStep = sin(angleStep);\n\n float negAngle = -float(RADIAL_SAMPLES) * angleStep;\n vec2 rotDir = vec2(\n dir.x * cos(negAngle) - dir.y * sin(negAngle),\n dir.x * sin(negAngle) + dir.y * cos(negAngle)\n );\n\n for (int i = -RADIAL_SAMPLES; i <= RADIAL_SAMPLES; i++) {\n vec2 uv = center + rotDir * dist;\n float w = 1.0 - abs(float(i)) / float(RADIAL_SAMPLES);\n sum += texture(u_image0, uv) * w;\n totalWeight += w;\n\n rotDir = vec2(\n rotDir.x * cosStep - rotDir.y * sinStep,\n rotDir.x * sinStep + rotDir.y * cosStep\n );\n }\n\n fragColor0 = sum / max(totalWeight, 0.001);\n return;\n }\n\n // Separable Gaussian / Box blur\n int samples = int(ceil(radius));\n\n if (samples == 0) {\n fragColor0 = texture(u_image0, v_texCoord);\n return;\n }\n\n // Direction: pass 0 = horizontal, pass 1 = vertical\n vec2 dir = (u_pass == 0) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n\n vec4 color = vec4(0.0);\n float totalWeight = 0.0;\n float sigma = radius / 2.0;\n\n for (int i = -samples; i <= samples; i++) {\n vec2 offset = dir * float(i) * texelSize;\n vec4 sample_color = texture(u_image0, v_texCoord + offset);\n\n float weight;\n if (u_int0 == BLUR_GAUSSIAN) {\n weight = gaussian(float(i), sigma);\n } else {\n // BLUR_BOX\n weight = 1.0;\n }\n\n color += sample_color * weight;\n totalWeight += weight;\n }\n\n fragColor0 = color / totalWeight;\n}\n",
"from_input"
]
}
],
"groups": [],
"links": [
{
"id": 10,
"origin_id": 10,
"origin_slot": 0,
"target_id": 1,
"target_slot": 2,
"type": "FLOAT"
},
{
"id": 11,
"origin_id": 12,
"origin_slot": 1,
"target_id": 1,
"target_slot": 4,
"type": "INT"
},
{
"id": 9,
"origin_id": -10,
"origin_slot": 0,
"target_id": 1,
"target_slot": 0,
"type": "IMAGE"
},
{
"id": 3,
"origin_id": 1,
"origin_slot": 0,
"target_id": -20,
"target_slot": 0,
"type": "IMAGE"
}
],
"extra": {
"workflowRendererVersion": "LG"
},
"category": "Image Tools/Blur"
}
]
}
}