From 0dd3e3fffa1fd02d15e9a591cc1ae81e8698269d Mon Sep 17 00:00:00 2001 From: ksenia Date: Thu, 9 Jul 2026 19:57:36 +0400 Subject: [PATCH 1/7] allow negative strokeTaper --- docs/src/app/(shaders)/spiral/page.tsx | 2 +- docs/src/shader-defs/spiral-def.ts | 5 +++-- packages/shaders/src/shaders/spiral.ts | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/src/app/(shaders)/spiral/page.tsx b/docs/src/app/(shaders)/spiral/page.tsx index 79e1b127b..104b3db00 100644 --- a/docs/src/app/(shaders)/spiral/page.tsx +++ b/docs/src/app/(shaders)/spiral/page.tsx @@ -27,7 +27,7 @@ const SpiralWithControls = () => { density: { value: defaults.density, min: 0, max: 1, order: 200 }, distortion: { value: defaults.distortion, min: 0, max: 1, order: 201 }, strokeWidth: { value: defaults.strokeWidth, min: 0, max: 1, order: 202 }, - strokeTaper: { value: defaults.strokeTaper, min: 0, max: 1, order: 203 }, + strokeTaper: { value: defaults.strokeTaper, min: -1, max: 1, order: 203 }, strokeCap: { value: defaults.strokeCap, min: 0, max: 1, order: 204 }, noise: { value: defaults.noise, min: 0, max: 1, order: 205 }, noiseFrequency: { value: defaults.noiseFrequency, min: 0, max: 1, order: 206 }, diff --git a/docs/src/shader-defs/spiral-def.ts b/docs/src/shader-defs/spiral-def.ts index 50e4f86ef..00f735d52 100644 --- a/docs/src/shader-defs/spiral-def.ts +++ b/docs/src/shader-defs/spiral-def.ts @@ -50,10 +50,11 @@ export const spiralDef: ShaderDef = { { name: 'strokeTaper', type: 'number', - min: 0, + min: -1, max: 1, defaultValue: defaultParams.strokeTaper, - description: 'how much the stroke is loosing width away from center (0 = full visibility)', + description: + 'Stroke width taper along the spiral; positive = stroke fades out away from center, negative = stroke grows away from center (0 = uniform width)', }, { name: 'strokeCap', diff --git a/packages/shaders/src/shaders/spiral.ts b/packages/shaders/src/shaders/spiral.ts index e212210da..cf0739689 100644 --- a/packages/shaders/src/shaders/spiral.ts +++ b/packages/shaders/src/shaders/spiral.ts @@ -29,7 +29,7 @@ import { simplexNoise, declarePI, colorBandingFix } from '../shader-utils.js'; * - u_density (float): Spacing falloff simulating perspective, 0 = flat spiral (0 to 1) * - u_distortion (float): Power of shape distortion applied along the spiral (0 to 1) * - u_strokeWidth (float): Thickness of spiral curve (0 to 1) - * - u_strokeTaper (float): How much stroke loses width away from center, 0 = full visibility (0 to 1) + * - u_strokeTaper (float): Positive = stroke fades out away from center, negative = stroke grows away from center, 0 = uniform width * - u_strokeCap (float): Extra stroke width at the center, no effect with strokeWidth = 0.5 (0 to 1) * - u_noise (float): Noise distortion applied over the canvas, no effect with noiseFrequency = 0 (0 to 1) * - u_noiseFrequency (float): Noise frequency, no effect with noise = 0 (0 to 1) @@ -83,7 +83,7 @@ void main() { float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.))); width = mix(width, wCap, u_strokeCap); - width *= (1. - clamp(u_strokeTaper, 0., 1.) * l); + width *= (1. - u_strokeTaper * l); float fw = fwidth(offset); float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth))); From 6a8b7e8f10f4edd37ee9f6844a5c95b431f0b788 Mon Sep 17 00:00:00 2001 From: ksenia Date: Thu, 9 Jul 2026 20:05:03 +0400 Subject: [PATCH 2/7] simplified and inverted --- packages/shaders/src/shaders/spiral.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shaders/src/shaders/spiral.ts b/packages/shaders/src/shaders/spiral.ts index cf0739689..ed2961f82 100644 --- a/packages/shaders/src/shaders/spiral.ts +++ b/packages/shaders/src/shaders/spiral.ts @@ -78,12 +78,12 @@ void main() { float stripe = fract(offset); float shape = 2. * abs(stripe - .5); - float width = 1. - clamp(u_strokeWidth, .005 * u_strokeTaper, 1.); + float width = 1. - clamp(u_strokeWidth, 0., 1.); float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.))); width = mix(width, wCap, u_strokeCap); - width *= (1. - u_strokeTaper * l); + width *= (1. + u_strokeTaper * l); float fw = fwidth(offset); float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth))); From ae3a43995f7222c47bcb8e84cd26a1161ef9354b Mon Sep 17 00:00:00 2001 From: ksenia Date: Sun, 12 Jul 2026 12:38:43 +0400 Subject: [PATCH 3/7] default noiseFreq >0 --- packages/shaders-react/src/shaders/spiral.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shaders-react/src/shaders/spiral.tsx b/packages/shaders-react/src/shaders/spiral.tsx index 541c412c1..4f2dfa407 100644 --- a/packages/shaders-react/src/shaders/spiral.tsx +++ b/packages/shaders-react/src/shaders/spiral.tsx @@ -28,7 +28,7 @@ export const defaultPreset: SpiralPreset = { strokeTaper: 0, strokeCap: 0, noise: 0, - noiseFrequency: 0, + noiseFrequency: 0.3, softness: 0, speed: 1, frame: 0, From 3100d5db27a08acda7fde2f2ad82da6801cd4a11 Mon Sep 17 00:00:00 2001 From: ksenia Date: Mon, 13 Jul 2026 19:08:03 +0400 Subject: [PATCH 4/7] better cap + better AA + think lines --- packages/shaders/src/shaders/spiral.ts | 52 +++++++++++++++----------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/packages/shaders/src/shaders/spiral.ts b/packages/shaders/src/shaders/spiral.ts index ed2961f82..f880289b1 100644 --- a/packages/shaders/src/shaders/spiral.ts +++ b/packages/shaders/src/shaders/spiral.ts @@ -30,7 +30,7 @@ import { simplexNoise, declarePI, colorBandingFix } from '../shader-utils.js'; * - u_distortion (float): Power of shape distortion applied along the spiral (0 to 1) * - u_strokeWidth (float): Thickness of spiral curve (0 to 1) * - u_strokeTaper (float): Positive = stroke fades out away from center, negative = stroke grows away from center, 0 = uniform width - * - u_strokeCap (float): Extra stroke width at the center, no effect with strokeWidth = 0.5 (0 to 1) + * - u_strokeCap (float): Extra stroke width added at the center, independent of strokeWidth (0 to 1) * - u_noise (float): Noise distortion applied over the canvas, no effect with noiseFrequency = 0 (0 to 1) * - u_noiseFrequency (float): Noise frequency, no effect with noise = 0 (0 to 1) * - u_softness (float): Color transition sharpness, 0 = hard edge, 1 = smooth gradient (0 to 1) @@ -43,6 +43,7 @@ precision mediump float; uniform float u_time; +uniform vec2 u_resolution; uniform vec4 u_colorBack; uniform vec4 u_colorFront; uniform float u_density; @@ -54,15 +55,17 @@ uniform float u_noise; uniform float u_noiseFrequency; uniform float u_softness; +in vec2 v_objectUV; in vec2 v_patternUV; out vec4 fragColor; -${ declarePI } -${ simplexNoise } +${declarePI} +${simplexNoise} void main() { vec2 uv = 2. * v_patternUV; + vec2 uvObj = 2. * v_objectUV; float t = u_time; float l = length(uv); @@ -76,35 +79,40 @@ void main() { float offset = l + angleNormalised; offset -= u_distortion * (sin(4. * l - .5 * t) * cos(PI + l + .5 * t)); float stripe = fract(offset); - + float shape = 2. * abs(stripe - .5); - float width = 1. - clamp(u_strokeWidth, 0., 1.); + float r = clamp(l, 0., 1.); + float wCap = 1. - r * r * (3. - 2. * r); + float cap = clamp(.5 * u_strokeCap * wCap, 0., 1.); + + float taperArea = clamp(length(uvObj), 0., 1.); + float width = 1. - clamp(u_strokeWidth, 0., 1.); + width = mix(width, 0., u_strokeTaper * taperArea); - float wCap = mix(width, (1. - stripe) * (1. - step(.5, stripe)), (1. - clamp(l, 0., 1.))); - width = mix(width, wCap, u_strokeCap); - width *= (1. + u_strokeTaper * l); + width -= cap; - float fw = fwidth(offset); - float fwMult = 4. - 3. * (smoothstep(.05, .4, 2. * u_strokeWidth) * smoothstep(.05, .4, 2. * (1. - u_strokeWidth))); - float pixelSize = mix(fwMult * fw, fwidth(shape), clamp(fw, 0., 1.)); - pixelSize = mix(pixelSize, .002, u_strokeCap * (1. - clamp(l, 0., 1.))); + float shapeSlope = 2. * sign(stripe - .5); + vec2 dField = shapeSlope * vec2(dFdx(offset), dFdy(offset)) - vec2(dFdx(width), dFdy(width)); + float fw = length(dField); - float res = smoothstep(width - pixelSize - u_softness, width + pixelSize + u_softness, shape); + float res = smoothstep(width - fw - u_softness, width + fw + u_softness, shape); - vec3 fgColor = u_colorFront.rgb * u_colorFront.a; - float fgOpacity = u_colorFront.a; - vec3 bgColor = u_colorBack.rgb * u_colorBack.a; - float bgOpacity = u_colorBack.a; + vec3 fgColor = u_colorFront.rgb * u_colorFront.a; + float fgOpacity = u_colorFront.a; + vec3 bgColor = u_colorBack.rgb * u_colorBack.a; + float bgOpacity = u_colorBack.a; - vec3 color = fgColor * res; - float opacity = fgOpacity * res; + vec3 color = fgColor * res; + float opacity = fgOpacity * res; - color += bgColor * (1. - opacity); - opacity += bgOpacity * (1. - opacity); + color += bgColor * (1. - opacity); + opacity += bgOpacity * (1. - opacity); - ${ colorBandingFix } + ${colorBandingFix} +// color.r = shape; + fragColor = vec4(color, opacity); } `; From ad7d21c89d9284837229939c57ebded1d4f2f1cf Mon Sep 17 00:00:00 2001 From: ksenia Date: Mon, 13 Jul 2026 19:51:05 +0400 Subject: [PATCH 5/7] good one --- docs/src/app/(shaders)/spiral/page.tsx | 2 +- packages/shaders/src/shaders/spiral.ts | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/src/app/(shaders)/spiral/page.tsx b/docs/src/app/(shaders)/spiral/page.tsx index 104b3db00..79e1b127b 100644 --- a/docs/src/app/(shaders)/spiral/page.tsx +++ b/docs/src/app/(shaders)/spiral/page.tsx @@ -27,7 +27,7 @@ const SpiralWithControls = () => { density: { value: defaults.density, min: 0, max: 1, order: 200 }, distortion: { value: defaults.distortion, min: 0, max: 1, order: 201 }, strokeWidth: { value: defaults.strokeWidth, min: 0, max: 1, order: 202 }, - strokeTaper: { value: defaults.strokeTaper, min: -1, max: 1, order: 203 }, + strokeTaper: { value: defaults.strokeTaper, min: 0, max: 1, order: 203 }, strokeCap: { value: defaults.strokeCap, min: 0, max: 1, order: 204 }, noise: { value: defaults.noise, min: 0, max: 1, order: 205 }, noiseFrequency: { value: defaults.noiseFrequency, min: 0, max: 1, order: 206 }, diff --git a/packages/shaders/src/shaders/spiral.ts b/packages/shaders/src/shaders/spiral.ts index f880289b1..00dbcd764 100644 --- a/packages/shaders/src/shaders/spiral.ts +++ b/packages/shaders/src/shaders/spiral.ts @@ -87,17 +87,27 @@ void main() { float cap = clamp(.5 * u_strokeCap * wCap, 0., 1.); float taperArea = clamp(length(uvObj), 0., 1.); + float tapper = pow(u_strokeTaper, 1. + 4. * (1. - u_strokeWidth)) * taperArea; + float width = 1. - clamp(u_strokeWidth, 0., 1.); - width = mix(width, 0., u_strokeTaper * taperArea); + width = mix(width, 1., tapper); width -= cap; float shapeSlope = 2. * sign(stripe - .5); - vec2 dField = shapeSlope * vec2(dFdx(offset), dFdy(offset)) - vec2(dFdx(width), dFdy(width)); - float fw = length(dField); + vec2 dOffset = vec2(dFdx(offset), dFdy(offset)); + vec2 dWidth = vec2(dFdx(width), dFdy(width)); + float fw = length(shapeSlope * dOffset - dWidth); + + float endProx = clamp(2. * abs(width - .5), 0., 1.); + fw *= 1. + pow(endProx, 6.); + shape = mix(shape, 0., tapper); float res = smoothstep(width - fw - u_softness, width + fw + u_softness, shape); + float dw = clamp(length(dWidth), .1, .9); + res *= 1. - smoothstep(1. - dw, 1. + dw, width); + vec3 fgColor = u_colorFront.rgb * u_colorFront.a; float fgOpacity = u_colorFront.a; vec3 bgColor = u_colorBack.rgb * u_colorBack.a; From 11f060a317bd971d9471e750107b18ca02beb414 Mon Sep 17 00:00:00 2001 From: ksenia Date: Mon, 13 Jul 2026 20:00:22 +0400 Subject: [PATCH 6/7] tweaks --- packages/shaders/src/shaders/spiral.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shaders/src/shaders/spiral.ts b/packages/shaders/src/shaders/spiral.ts index 00dbcd764..759ca2fbd 100644 --- a/packages/shaders/src/shaders/spiral.ts +++ b/packages/shaders/src/shaders/spiral.ts @@ -87,7 +87,7 @@ void main() { float cap = clamp(.5 * u_strokeCap * wCap, 0., 1.); float taperArea = clamp(length(uvObj), 0., 1.); - float tapper = pow(u_strokeTaper, 1. + 4. * (1. - u_strokeWidth)) * taperArea; + float tapper = pow(u_strokeTaper, 1. + 2. * (1. - u_strokeWidth)) * taperArea; float width = 1. - clamp(u_strokeWidth, 0., 1.); width = mix(width, 1., tapper); From 7d66315dc3069b1300ddd03c4b8604463f7f26a7 Mon Sep 17 00:00:00 2001 From: ksenia Date: Mon, 13 Jul 2026 20:36:45 +0400 Subject: [PATCH 7/7] non-clamped tapper area --- packages/shaders/src/shaders/spiral.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shaders/src/shaders/spiral.ts b/packages/shaders/src/shaders/spiral.ts index 759ca2fbd..d275fff13 100644 --- a/packages/shaders/src/shaders/spiral.ts +++ b/packages/shaders/src/shaders/spiral.ts @@ -86,7 +86,7 @@ void main() { float wCap = 1. - r * r * (3. - 2. * r); float cap = clamp(.5 * u_strokeCap * wCap, 0., 1.); - float taperArea = clamp(length(uvObj), 0., 1.); + float taperArea = length(uvObj);; float tapper = pow(u_strokeTaper, 1. + 2. * (1. - u_strokeWidth)) * taperArea; float width = 1. - clamp(u_strokeWidth, 0., 1.);