mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-05-02 13:22:32 +08:00
Merge branch 'master' into fix/sqlalchemy-version-format
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Build package / Build Test (3.10) (push) Has been cancelled
Build package / Build Test (3.11) (push) Has been cancelled
Build package / Build Test (3.12) (push) Has been cancelled
Build package / Build Test (3.13) (push) Has been cancelled
Build package / Build Test (3.14) (push) Has been cancelled
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Build package / Build Test (3.10) (push) Has been cancelled
Build package / Build Test (3.11) (push) Has been cancelled
Build package / Build Test (3.12) (push) Has been cancelled
Build package / Build Test (3.13) (push) Has been cancelled
Build package / Build Test (3.14) (push) Has been cancelled
This commit is contained in:
commit
57dfad1867
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,6 +21,5 @@ venv*/
|
|||||||
*.log
|
*.log
|
||||||
web_custom_versions/
|
web_custom_versions/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
openapi.yaml
|
|
||||||
filtered-openapi.yaml
|
filtered-openapi.yaml
|
||||||
uv.lock
|
uv.lock
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
uniform sampler2D u_image0;
|
uniform sampler2D u_image0;
|
||||||
uniform vec2 u_resolution;
|
|
||||||
uniform int u_int0; // Blend mode
|
uniform int u_int0; // Blend mode
|
||||||
uniform int u_int1; // Color tint
|
uniform int u_int1; // Color tint
|
||||||
uniform float u_float0; // Intensity
|
uniform float u_float0; // Intensity
|
||||||
@ -75,7 +74,7 @@ void main() {
|
|||||||
float t0 = threshold - 0.15;
|
float t0 = threshold - 0.15;
|
||||||
float t1 = threshold + 0.15;
|
float t1 = threshold + 0.15;
|
||||||
|
|
||||||
vec2 texelSize = 1.0 / u_resolution;
|
vec2 texelSize = 1.0 / vec2(textureSize(u_image0, 0));
|
||||||
float radius2 = radius * radius;
|
float radius2 = radius * radius;
|
||||||
|
|
||||||
float sampleScale = clamp(radius * 0.75, 0.35, 1.0);
|
float sampleScale = clamp(radius * 0.75, 0.35, 1.0);
|
||||||
|
|||||||
@ -12,7 +12,6 @@ const int RADIAL_SAMPLES = 12;
|
|||||||
const float RADIAL_STRENGTH = 0.0003;
|
const float RADIAL_STRENGTH = 0.0003;
|
||||||
|
|
||||||
uniform sampler2D u_image0;
|
uniform sampler2D u_image0;
|
||||||
uniform vec2 u_resolution;
|
|
||||||
uniform int u_int0; // Blur type (BLUR_GAUSSIAN, BLUR_BOX, BLUR_RADIAL)
|
uniform int u_int0; // Blur type (BLUR_GAUSSIAN, BLUR_BOX, BLUR_RADIAL)
|
||||||
uniform float u_float0; // Blur radius/amount
|
uniform float u_float0; // Blur radius/amount
|
||||||
uniform int u_pass; // Pass index (0 = horizontal, 1 = vertical)
|
uniform int u_pass; // Pass index (0 = horizontal, 1 = vertical)
|
||||||
@ -25,7 +24,7 @@ float gaussian(float x, float sigma) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 texelSize = 1.0 / u_resolution;
|
vec2 texelSize = 1.0 / vec2(textureSize(u_image0, 0));
|
||||||
float radius = max(u_float0, 0.0);
|
float radius = max(u_float0, 0.0);
|
||||||
|
|
||||||
// Radial (angular) blur - single pass, doesn't use separable
|
// Radial (angular) blur - single pass, doesn't use separable
|
||||||
|
|||||||
@ -2,14 +2,13 @@
|
|||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform sampler2D u_image0;
|
uniform sampler2D u_image0;
|
||||||
uniform vec2 u_resolution;
|
|
||||||
uniform float u_float0; // strength [0.0 – 2.0] typical: 0.3–1.0
|
uniform float u_float0; // strength [0.0 – 2.0] typical: 0.3–1.0
|
||||||
|
|
||||||
in vec2 v_texCoord;
|
in vec2 v_texCoord;
|
||||||
layout(location = 0) out vec4 fragColor0;
|
layout(location = 0) out vec4 fragColor0;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 texel = 1.0 / u_resolution;
|
vec2 texel = 1.0 / vec2(textureSize(u_image0, 0));
|
||||||
|
|
||||||
// Sample center and neighbors
|
// Sample center and neighbors
|
||||||
vec4 center = texture(u_image0, v_texCoord);
|
vec4 center = texture(u_image0, v_texCoord);
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
uniform sampler2D u_image0;
|
uniform sampler2D u_image0;
|
||||||
uniform vec2 u_resolution;
|
|
||||||
uniform float u_float0; // amount [0.0 - 3.0] typical: 0.5-1.5
|
uniform float u_float0; // amount [0.0 - 3.0] typical: 0.5-1.5
|
||||||
uniform float u_float1; // radius [0.5 - 10.0] blur radius in pixels
|
uniform float u_float1; // radius [0.5 - 10.0] blur radius in pixels
|
||||||
uniform float u_float2; // threshold [0.0 - 0.1] min difference to sharpen
|
uniform float u_float2; // threshold [0.0 - 0.1] min difference to sharpen
|
||||||
@ -19,7 +18,7 @@ float getLuminance(vec3 color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 texel = 1.0 / u_resolution;
|
vec2 texel = 1.0 / vec2(textureSize(u_image0, 0));
|
||||||
float radius = max(u_float1, 0.5);
|
float radius = max(u_float1, 0.5);
|
||||||
float amount = u_float0;
|
float amount = u_float0;
|
||||||
float threshold = u_float2;
|
float threshold = u_float2;
|
||||||
|
|||||||
@ -268,7 +268,7 @@
|
|||||||
"Node name for S&R": "GLSLShader"
|
"Node name for S&R": "GLSLShader"
|
||||||
},
|
},
|
||||||
"widgets_values": [
|
"widgets_values": [
|
||||||
"#version 300 es\nprecision mediump float;\n\nuniform sampler2D u_image0;\nuniform vec2 u_resolution;\nuniform int u_int0; // Blend mode\nuniform int u_int1; // Color tint\nuniform float u_float0; // Intensity\nuniform float u_float1; // Radius\nuniform float u_float2; // Threshold\n\nin vec2 v_texCoord;\nout vec4 fragColor;\n\nconst int BLEND_ADD = 0;\nconst int BLEND_SCREEN = 1;\nconst int BLEND_SOFT = 2;\nconst int BLEND_OVERLAY = 3;\nconst int BLEND_LIGHTEN = 4;\n\nconst float GOLDEN_ANGLE = 2.39996323;\nconst int MAX_SAMPLES = 48;\nconst vec3 LUMA = vec3(0.299, 0.587, 0.114);\n\nfloat hash(vec2 p) {\n p = fract(p * vec2(123.34, 456.21));\n p += dot(p, p + 45.32);\n return fract(p.x * p.y);\n}\n\nvec3 hexToRgb(int h) {\n return vec3(\n float((h >> 16) & 255),\n float((h >> 8) & 255),\n float(h & 255)\n ) * (1.0 / 255.0);\n}\n\nvec3 blend(vec3 base, vec3 glow, int mode) {\n if (mode == BLEND_SCREEN) {\n return 1.0 - (1.0 - base) * (1.0 - glow);\n }\n if (mode == BLEND_SOFT) {\n return mix(\n base - (1.0 - 2.0 * glow) * base * (1.0 - base),\n base + (2.0 * glow - 1.0) * (sqrt(base) - base),\n step(0.5, glow)\n );\n }\n if (mode == BLEND_OVERLAY) {\n return mix(\n 2.0 * base * glow,\n 1.0 - 2.0 * (1.0 - base) * (1.0 - glow),\n step(0.5, base)\n );\n }\n if (mode == BLEND_LIGHTEN) {\n return max(base, glow);\n }\n return base + glow;\n}\n\nvoid main() {\n vec4 original = texture(u_image0, v_texCoord);\n \n float intensity = u_float0 * 0.05;\n float radius = u_float1 * u_float1 * 0.012;\n \n if (intensity < 0.001 || radius < 0.1) {\n fragColor = original;\n return;\n }\n \n float threshold = 1.0 - u_float2 * 0.01;\n float t0 = threshold - 0.15;\n float t1 = threshold + 0.15;\n \n vec2 texelSize = 1.0 / u_resolution;\n float radius2 = radius * radius;\n \n float sampleScale = clamp(radius * 0.75, 0.35, 1.0);\n int samples = int(float(MAX_SAMPLES) * sampleScale);\n \n float noise = hash(gl_FragCoord.xy);\n float angleOffset = noise * GOLDEN_ANGLE;\n float radiusJitter = 0.85 + noise * 0.3;\n \n float ca = cos(GOLDEN_ANGLE);\n float sa = sin(GOLDEN_ANGLE);\n vec2 dir = vec2(cos(angleOffset), sin(angleOffset));\n \n vec3 glow = vec3(0.0);\n float totalWeight = 0.0;\n \n // Center tap\n float centerMask = smoothstep(t0, t1, dot(original.rgb, LUMA));\n glow += original.rgb * centerMask * 2.0;\n totalWeight += 2.0;\n \n for (int i = 1; i < MAX_SAMPLES; i++) {\n if (i >= samples) break;\n \n float fi = float(i);\n float dist = sqrt(fi / float(samples)) * radius * radiusJitter;\n \n vec2 offset = dir * dist * texelSize;\n vec3 c = texture(u_image0, v_texCoord + offset).rgb;\n float mask = smoothstep(t0, t1, dot(c, LUMA));\n \n float w = 1.0 - (dist * dist) / (radius2 * 1.5);\n w = max(w, 0.0);\n w *= w;\n \n glow += c * mask * w;\n totalWeight += w;\n \n dir = vec2(\n dir.x * ca - dir.y * sa,\n dir.x * sa + dir.y * ca\n );\n }\n \n glow *= intensity / max(totalWeight, 0.001);\n \n if (u_int1 > 0) {\n glow *= hexToRgb(u_int1);\n }\n \n vec3 result = blend(original.rgb, glow, u_int0);\n result += (noise - 0.5) * (1.0 / 255.0);\n \n fragColor = vec4(clamp(result, 0.0, 1.0), original.a);\n}",
|
"#version 300 es\nprecision mediump float;\n\nuniform sampler2D u_image0;\nuniform int u_int0; // Blend mode\nuniform int u_int1; // Color tint\nuniform float u_float0; // Intensity\nuniform float u_float1; // Radius\nuniform float u_float2; // Threshold\n\nin vec2 v_texCoord;\nout vec4 fragColor;\n\nconst int BLEND_ADD = 0;\nconst int BLEND_SCREEN = 1;\nconst int BLEND_SOFT = 2;\nconst int BLEND_OVERLAY = 3;\nconst int BLEND_LIGHTEN = 4;\n\nconst float GOLDEN_ANGLE = 2.39996323;\nconst int MAX_SAMPLES = 48;\nconst vec3 LUMA = vec3(0.299, 0.587, 0.114);\n\nfloat hash(vec2 p) {\n p = fract(p * vec2(123.34, 456.21));\n p += dot(p, p + 45.32);\n return fract(p.x * p.y);\n}\n\nvec3 hexToRgb(int h) {\n return vec3(\n float((h >> 16) & 255),\n float((h >> 8) & 255),\n float(h & 255)\n ) * (1.0 / 255.0);\n}\n\nvec3 blend(vec3 base, vec3 glow, int mode) {\n if (mode == BLEND_SCREEN) {\n return 1.0 - (1.0 - base) * (1.0 - glow);\n }\n if (mode == BLEND_SOFT) {\n return mix(\n base - (1.0 - 2.0 * glow) * base * (1.0 - base),\n base + (2.0 * glow - 1.0) * (sqrt(base) - base),\n step(0.5, glow)\n );\n }\n if (mode == BLEND_OVERLAY) {\n return mix(\n 2.0 * base * glow,\n 1.0 - 2.0 * (1.0 - base) * (1.0 - glow),\n step(0.5, base)\n );\n }\n if (mode == BLEND_LIGHTEN) {\n return max(base, glow);\n }\n return base + glow;\n}\n\nvoid main() {\n vec4 original = texture(u_image0, v_texCoord);\n \n float intensity = u_float0 * 0.05;\n float radius = u_float1 * u_float1 * 0.012;\n \n if (intensity < 0.001 || radius < 0.1) {\n fragColor = original;\n return;\n }\n \n float threshold = 1.0 - u_float2 * 0.01;\n float t0 = threshold - 0.15;\n float t1 = threshold + 0.15;\n \n vec2 texelSize = 1.0 / vec2(textureSize(u_image0, 0));\n float radius2 = radius * radius;\n \n float sampleScale = clamp(radius * 0.75, 0.35, 1.0);\n int samples = int(float(MAX_SAMPLES) * sampleScale);\n \n float noise = hash(gl_FragCoord.xy);\n float angleOffset = noise * GOLDEN_ANGLE;\n float radiusJitter = 0.85 + noise * 0.3;\n \n float ca = cos(GOLDEN_ANGLE);\n float sa = sin(GOLDEN_ANGLE);\n vec2 dir = vec2(cos(angleOffset), sin(angleOffset));\n \n vec3 glow = vec3(0.0);\n float totalWeight = 0.0;\n \n // Center tap\n float centerMask = smoothstep(t0, t1, dot(original.rgb, LUMA));\n glow += original.rgb * centerMask * 2.0;\n totalWeight += 2.0;\n \n for (int i = 1; i < MAX_SAMPLES; i++) {\n if (i >= samples) break;\n \n float fi = float(i);\n float dist = sqrt(fi / float(samples)) * radius * radiusJitter;\n \n vec2 offset = dir * dist * texelSize;\n vec3 c = texture(u_image0, v_texCoord + offset).rgb;\n float mask = smoothstep(t0, t1, dot(c, LUMA));\n \n float w = 1.0 - (dist * dist) / (radius2 * 1.5);\n w = max(w, 0.0);\n w *= w;\n \n glow += c * mask * w;\n totalWeight += w;\n \n dir = vec2(\n dir.x * ca - dir.y * sa,\n dir.x * sa + dir.y * ca\n );\n }\n \n glow *= intensity / max(totalWeight, 0.001);\n \n if (u_int1 > 0) {\n glow *= hexToRgb(u_int1);\n }\n \n vec3 result = blend(original.rgb, glow, u_int0);\n result += (noise - 0.5) * (1.0 / 255.0);\n \n fragColor = vec4(clamp(result, 0.0, 1.0), original.a);\n}",
|
||||||
"from_input"
|
"from_input"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -331,7 +331,7 @@
|
|||||||
"Node name for S&R": "GLSLShader"
|
"Node name for S&R": "GLSLShader"
|
||||||
},
|
},
|
||||||
"widgets_values": [
|
"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",
|
"#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 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 / vec2(textureSize(u_image0, 0));\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"
|
"from_input"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -267,7 +267,7 @@
|
|||||||
"Node name for S&R": "GLSLShader"
|
"Node name for S&R": "GLSLShader"
|
||||||
},
|
},
|
||||||
"widgets_values": [
|
"widgets_values": [
|
||||||
"#version 300 es\nprecision highp float;\n\nuniform sampler2D u_image0;\nuniform vec2 u_resolution;\nuniform float u_float0; // strength [0.0 – 2.0] typical: 0.3–1.0\n\nin vec2 v_texCoord;\nlayout(location = 0) out vec4 fragColor0;\n\nvoid main() {\n vec2 texel = 1.0 / u_resolution;\n \n // Sample center and neighbors\n vec4 center = texture(u_image0, v_texCoord);\n vec4 top = texture(u_image0, v_texCoord + vec2( 0.0, -texel.y));\n vec4 bottom = texture(u_image0, v_texCoord + vec2( 0.0, texel.y));\n vec4 left = texture(u_image0, v_texCoord + vec2(-texel.x, 0.0));\n vec4 right = texture(u_image0, v_texCoord + vec2( texel.x, 0.0));\n \n // Edge enhancement (Laplacian)\n vec4 edges = center * 4.0 - top - bottom - left - right;\n \n // Add edges back scaled by strength\n vec4 sharpened = center + edges * u_float0;\n \n fragColor0 = vec4(clamp(sharpened.rgb, 0.0, 1.0), center.a);\n}",
|
"#version 300 es\nprecision highp float;\n\nuniform sampler2D u_image0;\nuniform float u_float0; // strength [0.0 – 2.0] typical: 0.3–1.0\n\nin vec2 v_texCoord;\nlayout(location = 0) out vec4 fragColor0;\n\nvoid main() {\n vec2 texel = 1.0 / vec2(textureSize(u_image0, 0));\n \n // Sample center and neighbors\n vec4 center = texture(u_image0, v_texCoord);\n vec4 top = texture(u_image0, v_texCoord + vec2( 0.0, -texel.y));\n vec4 bottom = texture(u_image0, v_texCoord + vec2( 0.0, texel.y));\n vec4 left = texture(u_image0, v_texCoord + vec2(-texel.x, 0.0));\n vec4 right = texture(u_image0, v_texCoord + vec2( texel.x, 0.0));\n \n // Edge enhancement (Laplacian)\n vec4 edges = center * 4.0 - top - bottom - left - right;\n \n // Add edges back scaled by strength\n vec4 sharpened = center + edges * u_float0;\n \n fragColor0 = vec4(clamp(sharpened.rgb, 0.0, 1.0), center.a);\n}",
|
||||||
"from_input"
|
"from_input"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -383,7 +383,7 @@
|
|||||||
"Node name for S&R": "GLSLShader"
|
"Node name for S&R": "GLSLShader"
|
||||||
},
|
},
|
||||||
"widgets_values": [
|
"widgets_values": [
|
||||||
"#version 300 es\nprecision highp float;\n\nuniform sampler2D u_image0;\nuniform vec2 u_resolution;\nuniform float u_float0; // amount [0.0 - 3.0] typical: 0.5-1.5\nuniform float u_float1; // radius [0.5 - 10.0] blur radius in pixels\nuniform float u_float2; // threshold [0.0 - 0.1] min difference to sharpen\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\nfloat getLuminance(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\n\nvoid main() {\n vec2 texel = 1.0 / u_resolution;\n float radius = max(u_float1, 0.5);\n float amount = u_float0;\n float threshold = u_float2;\n\n vec4 original = texture(u_image0, v_texCoord);\n\n // Gaussian blur for the \"unsharp\" mask\n int samples = int(ceil(radius));\n float sigma = radius / 2.0;\n\n vec4 blurred = vec4(0.0);\n float totalWeight = 0.0;\n\n for (int x = -samples; x <= samples; x++) {\n for (int y = -samples; y <= samples; y++) {\n vec2 offset = vec2(float(x), float(y)) * texel;\n vec4 sample_color = texture(u_image0, v_texCoord + offset);\n\n float dist = length(vec2(float(x), float(y)));\n float weight = gaussian(dist, sigma);\n blurred += sample_color * weight;\n totalWeight += weight;\n }\n }\n blurred /= totalWeight;\n\n // Unsharp mask = original - blurred\n vec3 mask = original.rgb - blurred.rgb;\n\n // Luminance-based threshold with smooth falloff\n float lumaDelta = abs(getLuminance(original.rgb) - getLuminance(blurred.rgb));\n float thresholdScale = smoothstep(0.0, threshold, lumaDelta);\n mask *= thresholdScale;\n\n // Sharpen: original + mask * amount\n vec3 sharpened = original.rgb + mask * amount;\n\n fragColor0 = vec4(clamp(sharpened, 0.0, 1.0), original.a);\n}\n",
|
"#version 300 es\nprecision highp float;\n\nuniform sampler2D u_image0;\nuniform float u_float0; // amount [0.0 - 3.0] typical: 0.5-1.5\nuniform float u_float1; // radius [0.5 - 10.0] blur radius in pixels\nuniform float u_float2; // threshold [0.0 - 0.1] min difference to sharpen\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\nfloat getLuminance(vec3 color) {\n return dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\n\nvoid main() {\n vec2 texel = 1.0 / vec2(textureSize(u_image0, 0));\n float radius = max(u_float1, 0.5);\n float amount = u_float0;\n float threshold = u_float2;\n\n vec4 original = texture(u_image0, v_texCoord);\n\n // Gaussian blur for the \"unsharp\" mask\n int samples = int(ceil(radius));\n float sigma = radius / 2.0;\n\n vec4 blurred = vec4(0.0);\n float totalWeight = 0.0;\n\n for (int x = -samples; x <= samples; x++) {\n for (int y = -samples; y <= samples; y++) {\n vec2 offset = vec2(float(x), float(y)) * texel;\n vec4 sample_color = texture(u_image0, v_texCoord + offset);\n\n float dist = length(vec2(float(x), float(y)));\n float weight = gaussian(dist, sigma);\n blurred += sample_color * weight;\n totalWeight += weight;\n }\n }\n blurred /= totalWeight;\n\n // Unsharp mask = original - blurred\n vec3 mask = original.rgb - blurred.rgb;\n\n // Luminance-based threshold with smooth falloff\n float lumaDelta = abs(getLuminance(original.rgb) - getLuminance(blurred.rgb));\n float thresholdScale = smoothstep(0.0, threshold, lumaDelta);\n mask *= thresholdScale;\n\n // Sharpen: original + mask * amount\n vec3 sharpened = original.rgb + mask * amount;\n\n fragColor0 = vec4(clamp(sharpened, 0.0, 1.0), original.a);\n}\n",
|
||||||
"from_input"
|
"from_input"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ from comfy_api.latest._input import (
|
|||||||
CurveInput,
|
CurveInput,
|
||||||
MonotoneCubicCurve,
|
MonotoneCubicCurve,
|
||||||
LinearCurve,
|
LinearCurve,
|
||||||
|
RangeInput,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -21,4 +22,5 @@ __all__ = [
|
|||||||
"CurveInput",
|
"CurveInput",
|
||||||
"MonotoneCubicCurve",
|
"MonotoneCubicCurve",
|
||||||
"LinearCurve",
|
"LinearCurve",
|
||||||
|
"RangeInput",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from .basic_types import ImageInput, AudioInput, MaskInput, LatentInput
|
from .basic_types import ImageInput, AudioInput, MaskInput, LatentInput
|
||||||
from .curve_types import CurvePoint, CurveInput, MonotoneCubicCurve, LinearCurve
|
from .curve_types import CurvePoint, CurveInput, MonotoneCubicCurve, LinearCurve
|
||||||
|
from .range_types import RangeInput
|
||||||
from .video_types import VideoInput
|
from .video_types import VideoInput
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -12,4 +13,5 @@ __all__ = [
|
|||||||
"CurveInput",
|
"CurveInput",
|
||||||
"MonotoneCubicCurve",
|
"MonotoneCubicCurve",
|
||||||
"LinearCurve",
|
"LinearCurve",
|
||||||
|
"RangeInput",
|
||||||
]
|
]
|
||||||
|
|||||||
70
comfy_api/latest/_input/range_types.py
Normal file
70
comfy_api/latest/_input/range_types.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import math
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class RangeInput:
|
||||||
|
"""Represents a levels/range adjustment: input range [min, max] with
|
||||||
|
optional midpoint (gamma control).
|
||||||
|
|
||||||
|
Generates a 1D LUT identical to GIMP's levels mapping:
|
||||||
|
1. Normalize input to [0, 1] using [min, max]
|
||||||
|
2. Apply gamma correction: pow(value, 1/gamma)
|
||||||
|
3. Clamp to [0, 1]
|
||||||
|
|
||||||
|
The midpoint field is a position in [0, 1] representing where the
|
||||||
|
midtone falls within [min, max]. It maps to gamma via:
|
||||||
|
gamma = -log2(midpoint)
|
||||||
|
So midpoint=0.5 → gamma=1.0 (linear).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, min_val: float, max_val: float, midpoint: float | None = None):
|
||||||
|
self.min_val = min_val
|
||||||
|
self.max_val = max_val
|
||||||
|
self.midpoint = midpoint
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_raw(data) -> RangeInput:
|
||||||
|
if isinstance(data, RangeInput):
|
||||||
|
return data
|
||||||
|
if isinstance(data, dict):
|
||||||
|
return RangeInput(
|
||||||
|
min_val=float(data.get("min", 0.0)),
|
||||||
|
max_val=float(data.get("max", 1.0)),
|
||||||
|
midpoint=float(data["midpoint"]) if data.get("midpoint") is not None else None,
|
||||||
|
)
|
||||||
|
raise TypeError(f"Cannot convert {type(data)} to RangeInput")
|
||||||
|
|
||||||
|
def to_lut(self, size: int = 256) -> np.ndarray:
|
||||||
|
"""Generate a float64 lookup table mapping [0, 1] input through this
|
||||||
|
levels adjustment.
|
||||||
|
|
||||||
|
The LUT maps normalized input values (0..1) to output values (0..1),
|
||||||
|
matching the GIMP levels formula.
|
||||||
|
"""
|
||||||
|
xs = np.linspace(0.0, 1.0, size, dtype=np.float64)
|
||||||
|
|
||||||
|
in_range = self.max_val - self.min_val
|
||||||
|
if abs(in_range) < 1e-10:
|
||||||
|
return np.where(xs >= self.min_val, 1.0, 0.0).astype(np.float64)
|
||||||
|
|
||||||
|
# Normalize: map [min, max] → [0, 1]
|
||||||
|
result = (xs - self.min_val) / in_range
|
||||||
|
result = np.clip(result, 0.0, 1.0)
|
||||||
|
|
||||||
|
# Gamma correction from midpoint
|
||||||
|
if self.midpoint is not None and self.midpoint > 0 and self.midpoint != 0.5:
|
||||||
|
gamma = max(-math.log2(self.midpoint), 0.001)
|
||||||
|
inv_gamma = 1.0 / gamma
|
||||||
|
mask = result > 0
|
||||||
|
result[mask] = np.power(result[mask], inv_gamma)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
mid = f", midpoint={self.midpoint}" if self.midpoint is not None else ""
|
||||||
|
return f"RangeInput(min={self.min_val}, max={self.max_val}{mid})"
|
||||||
@ -248,8 +248,8 @@ class VideoFromFile(VideoInput):
|
|||||||
continue
|
continue
|
||||||
if self.__duration and frame.pts >= end_pts:
|
if self.__duration and frame.pts >= end_pts:
|
||||||
break
|
break
|
||||||
img = frame.to_ndarray(format='rgb24') # shape: (H, W, 3)
|
img = frame.to_ndarray(format='gbrpf32le') # shape: (H, W, 3)
|
||||||
img = torch.from_numpy(img) / 255.0 # shape: (H, W, 3)
|
img = torch.from_numpy(img)
|
||||||
frames.append(img)
|
frames.append(img)
|
||||||
|
|
||||||
images = torch.stack(frames) if len(frames) > 0 else torch.zeros(0, 3, 0, 0)
|
images = torch.stack(frames) if len(frames) > 0 else torch.zeros(0, 3, 0, 0)
|
||||||
|
|||||||
@ -1266,6 +1266,43 @@ class Histogram(ComfyTypeIO):
|
|||||||
Type = list[int]
|
Type = list[int]
|
||||||
|
|
||||||
|
|
||||||
|
@comfytype(io_type="RANGE")
|
||||||
|
class Range(ComfyTypeIO):
|
||||||
|
from comfy_api.input import RangeInput
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
Type = RangeInput
|
||||||
|
|
||||||
|
class Input(WidgetInput):
|
||||||
|
def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str=None,
|
||||||
|
socketless: bool=True, default: dict=None,
|
||||||
|
display: str=None,
|
||||||
|
gradient_stops: list=None,
|
||||||
|
show_midpoint: bool=None,
|
||||||
|
midpoint_scale: str=None,
|
||||||
|
value_min: float=None,
|
||||||
|
value_max: float=None,
|
||||||
|
advanced: bool=None):
|
||||||
|
super().__init__(id, display_name, optional, tooltip, None, default, socketless, None, None, None, None, advanced)
|
||||||
|
if default is None:
|
||||||
|
self.default = {"min": 0.0, "max": 1.0}
|
||||||
|
self.display = display
|
||||||
|
self.gradient_stops = gradient_stops
|
||||||
|
self.show_midpoint = show_midpoint
|
||||||
|
self.midpoint_scale = midpoint_scale
|
||||||
|
self.value_min = value_min
|
||||||
|
self.value_max = value_max
|
||||||
|
|
||||||
|
def as_dict(self):
|
||||||
|
return super().as_dict() | prune_dict({
|
||||||
|
"display": self.display,
|
||||||
|
"gradient_stops": self.gradient_stops,
|
||||||
|
"show_midpoint": self.show_midpoint,
|
||||||
|
"midpoint_scale": self.midpoint_scale,
|
||||||
|
"value_min": self.value_min,
|
||||||
|
"value_max": self.value_max,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
DYNAMIC_INPUT_LOOKUP: dict[str, Callable[[dict[str, Any], dict[str, Any], tuple[str, dict[str, Any]], str, list[str] | None], None]] = {}
|
DYNAMIC_INPUT_LOOKUP: dict[str, Callable[[dict[str, Any], dict[str, Any], tuple[str, dict[str, Any]], str, list[str] | None], None]] = {}
|
||||||
def register_dynamic_input_func(io_type: str, func: Callable[[dict[str, Any], dict[str, Any], tuple[str, dict[str, Any]], str, list[str] | None], None]):
|
def register_dynamic_input_func(io_type: str, func: Callable[[dict[str, Any], dict[str, Any], tuple[str, dict[str, Any]], str, list[str] | None], None]):
|
||||||
DYNAMIC_INPUT_LOOKUP[io_type] = func
|
DYNAMIC_INPUT_LOOKUP[io_type] = func
|
||||||
@ -2276,5 +2313,6 @@ __all__ = [
|
|||||||
"BoundingBox",
|
"BoundingBox",
|
||||||
"Curve",
|
"Curve",
|
||||||
"Histogram",
|
"Histogram",
|
||||||
|
"Range",
|
||||||
"NodeReplace",
|
"NodeReplace",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -33,9 +33,13 @@ class OpenAIVideoSora2(IO.ComfyNode):
|
|||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return IO.Schema(
|
return IO.Schema(
|
||||||
node_id="OpenAIVideoSora2",
|
node_id="OpenAIVideoSora2",
|
||||||
display_name="OpenAI Sora - Video",
|
display_name="OpenAI Sora - Video (Deprecated)",
|
||||||
category="api node/video/Sora",
|
category="api node/video/Sora",
|
||||||
description="OpenAI video and audio generation.",
|
description=(
|
||||||
|
"OpenAI video and audio generation.\n\n"
|
||||||
|
"DEPRECATION NOTICE: OpenAI will stop serving the Sora v2 API in September 2026. "
|
||||||
|
"This node will be removed from ComfyUI at that time."
|
||||||
|
),
|
||||||
inputs=[
|
inputs=[
|
||||||
IO.Combo.Input(
|
IO.Combo.Input(
|
||||||
"model",
|
"model",
|
||||||
|
|||||||
3231
openapi.yaml
Normal file
3231
openapi.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
comfyui-frontend-package==1.42.14
|
comfyui-frontend-package==1.42.15
|
||||||
comfyui-workflow-templates==0.9.62
|
comfyui-workflow-templates==0.9.62
|
||||||
comfyui-embedded-docs==0.4.4
|
comfyui-embedded-docs==0.4.4
|
||||||
torch
|
torch
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user