Skip to content

Commit 17ca104

Browse files
committed
✨ Add seven new WebGL effects to the framework
Add comprehensive set of new visual effects with advanced graphics techniques New effects added: - ADHD Hyperfocus: Tunnel vision with dopamine sparks and peripheral fade - Black Hole Spaghettification: Relativistic lensing and accretion disk - Cellular Automaton RGB: Conway's Game of Life and other mathematical automata - Neural Synapse Fire: Real ML mathematics with network visualization - Quantum Foam: Volumetric foam with particle pairs and collapse flashes - Reality.exe Error: Safe glitch aesthetic with multiple visual modes - Voronoi Flow: Domain-warped cellular rivers with high contrast Each effect includes: - Complete GLSL fragment shader implementation - TypeScript WebGL wrapper with full controls - Comprehensive parameter sets for customization - Professional documentation and tooltips - Proper initialization and uniform management All effects registered in main index with proper entry points
1 parent 4a7bbda commit 17ca104

File tree

13 files changed

+3120
-0
lines changed

13 files changed

+3120
-0
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// ADHD Hyperfocus — tunnel vision, dopamine sparks, peripheral fade
2+
precision highp float;
3+
4+
uniform float iTime;
5+
uniform vec2 iResolution;
6+
7+
// Controls (normalized to sensible ranges in TS)
8+
uniform float iFocusRadius; // 0.0 - 1.0 (radius of sharp center)
9+
uniform float iFocusStrength; // 0.0 - 2.0 (center boost)
10+
uniform float iPeripheralBlur; // 0.0 - 2.0 (blur intensity grows with radius)
11+
uniform float iSaturation; // 0.0 - 2.0
12+
uniform float iEnergy; // 0.0 - 2.0 (brightness)
13+
uniform float iSparkDensity; // 0.0 - 2.0
14+
uniform float iTunnelSpeed; // 0.0 - 2.0
15+
uniform float iParalysis; // 0.0 - 1.0 (reduces motion)
16+
uniform float iNoise; // 0.0 - 2.0
17+
uniform int iColorMode; // 0=Dopamine,1=Neon,2=Mono
18+
19+
// Helpers
20+
float hash11(float p) {
21+
p = fract(p * 0.1031);
22+
p *= p + 33.33;
23+
p *= p + p;
24+
return fract(p);
25+
}
26+
27+
float hash21(vec2 p) {
28+
vec3 p3 = fract(vec3(p.x, p.y, p.x) * 0.1031);
29+
p3 += dot(p3, p3.yzx + 33.33);
30+
return fract((p3.x + p3.y) * p3.z);
31+
}
32+
33+
// Basic value noise (trilinear interp)
34+
float vnoise(vec2 x) {
35+
vec2 i = floor(x);
36+
vec2 f = fract(x);
37+
f = f * f * (3.0 - 2.0 * f);
38+
float a = hash21(i);
39+
float b = hash21(i + vec2(1.0, 0.0));
40+
float c = hash21(i + vec2(0.0, 1.0));
41+
float d = hash21(i + vec2(1.0, 1.0));
42+
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
43+
}
44+
45+
vec3 hsv2rgb(vec3 c) {
46+
vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
47+
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
48+
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
49+
}
50+
51+
vec3 palette(float t, int mode) {
52+
if (mode == 1) { // Neon
53+
return 0.5 + 0.5 * cos(6.28318 * (t + vec3(0.00, 0.33, 0.67)));
54+
} else if (mode == 2) { // Mono
55+
return vec3(t);
56+
} else { // Dopamine (hot/cool cycling)
57+
float h = fract(t);
58+
vec3 c = hsv2rgb(vec3(h, 0.9, 1.0));
59+
return c;
60+
}
61+
}
62+
63+
// Dopamine sparks travelling inward
64+
float sparks(vec2 uv, vec2 center, float time, float density, float paralysis) {
65+
// Fewer cells when low density; 10..28
66+
float grid = mix(10.0, 28.0, clamp(density * 0.5, 0.0, 1.0));
67+
vec2 gid = floor(uv * grid);
68+
float h = hash21(gid);
69+
vec2 cellCenter = (gid + 0.5 + 0.25 * vec2(hash11(h), hash11(h + 1.7))) / grid;
70+
71+
// Direction toward focus
72+
vec2 dir = normalize(center - cellCenter + 1e-4);
73+
float spd = mix(1.6, 0.35, paralysis); // paralysis slows down
74+
75+
// Each cell has a spark life
76+
float life = fract(time * spd + h * 7.3);
77+
vec2 pos = mix(cellCenter, center, life);
78+
79+
// Only spawn if outside focus radius
80+
float r = distance(cellCenter, center);
81+
float activeMask = step(0.22 + 0.08 * density, r);
82+
83+
float d = length(uv - pos);
84+
float glow = exp(-d * mix(150.0, 60.0, density));
85+
glow *= smoothstep(0.0, 0.2, life) * smoothstep(1.0, 0.6, life);
86+
return glow * activeMask;
87+
}
88+
89+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
90+
vec2 uv = fragCoord / iResolution.xy;
91+
vec2 center = vec2(0.5);
92+
vec2 p = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
93+
94+
float t = iTime * (0.2 + 0.8 * iTunnelSpeed) * (1.0 - 0.6 * iParalysis);
95+
float r = length(p);
96+
// Avoid GLSL ES 1.0 two-argument atan; angle not required for current visuals
97+
98+
// Tunnel rings animate to enhance hyperfocus pull
99+
float rings = sin(12.0 * r - 3.5 * t);
100+
101+
// Base color via palette
102+
float hueT = fract(0.62 + 0.12 * t + 0.25 * rings);
103+
vec3 base = palette(hueT, iColorMode);
104+
base *= iEnergy;
105+
106+
// Focus factor — strong in center, falling off with radius
107+
float focus = smoothstep(iFocusRadius, 0.0, r);
108+
float centerBoost = mix(1.0, 1.0 + iFocusStrength, 1.0 - focus);
109+
base *= centerBoost;
110+
111+
// Peripheral desaturation and blur proxy
112+
float periph = smoothstep(iFocusRadius * 0.8, 0.75, r);
113+
// Use iPeripheralBlur as a strength multiplier for the periphery falloff
114+
float periphStrength = clamp(iPeripheralBlur, 0.0, 2.0);
115+
float periphFactor = clamp(periph * periphStrength, 0.0, 1.0);
116+
float sat = mix(iSaturation, iSaturation * 0.4, periphFactor);
117+
// Convert to HSV-ish by scaling saturation via luma mix
118+
float l = dot(base, vec3(0.299, 0.587, 0.114));
119+
base = mix(vec3(l), base, clamp(sat, 0.0, 2.0));
120+
121+
// Procedural film/noise (more at the edges)
122+
float n = (vnoise(uv * 800.0 + t * 6.0) - 0.5) * iNoise * (0.4 + 0.6 * periphFactor);
123+
base += n;
124+
125+
// Dopamine sparks
126+
float density = iSparkDensity;
127+
float sp = sparks(uv, center, t, density, iParalysis);
128+
vec3 sparkCol = palette(hueT + 0.1, iColorMode);
129+
base += sparkCol * sp * (0.7 + 0.6 * iSaturation);
130+
131+
fragColor = vec4(base, 1.0);
132+
}
133+
134+
void main() {
135+
mainImage(gl_FragColor, gl_FragCoord.xy);
136+
}
137+
138+
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/**
2+
* ADHD Hyperfocus — WebGL Effect
3+
* Tunnel-vision center clarity, peripheral fade, dopamine sparks, paralysis slider.
4+
*/
5+
6+
import * as THREE from 'three'
7+
import { initializeEffect } from '../../core'
8+
import { ComboboxControl, Effect, NumberControl } from '../../core/controls/decorators'
9+
import { comboboxValueToIndex, normalizePercentage } from '../../core/controls/helpers'
10+
import { WebGLEffect } from '../../core/effects/webgl-effect'
11+
12+
import fragmentShader from './fragment.glsl'
13+
14+
declare global {
15+
interface Window {
16+
focusRadius: number
17+
focusStrength: number
18+
peripheralBlur: number
19+
saturation: number
20+
energy: number
21+
sparkDensity: number
22+
tunnelSpeed: number
23+
paralysis: number
24+
noise: number
25+
colorMode: string | number
26+
}
27+
}
28+
29+
export interface ADHDHyperfocusControls {
30+
focusRadius: number // 0-1
31+
focusStrength: number // 0-2
32+
peripheralBlur: number // 0-2
33+
saturation: number // 0-2
34+
energy: number // 0-2
35+
sparkDensity: number // 0-2
36+
tunnelSpeed: number // 0-2
37+
paralysis: number // 0-1
38+
noise: number // 0-2
39+
colorMode: number // 0..2
40+
}
41+
42+
@Effect({
43+
author: 'hyperb1iss',
44+
description: 'Tunnel vision with hyperfocused center and dopamine sparks. Peripheral fade, paralysis control.',
45+
name: 'ADHD Hyperfocus',
46+
})
47+
export class ADHDHyperfocusEffect extends WebGLEffect<ADHDHyperfocusControls> {
48+
private readonly colorModes = ['Dopamine', 'Neon', 'Mono']
49+
50+
@NumberControl({
51+
default: 28,
52+
label: 'Focus Radius',
53+
max: 100,
54+
min: 5,
55+
tooltip: 'Radius of the sharp center region',
56+
})
57+
focusRadius!: number
58+
59+
@NumberControl({
60+
default: 120,
61+
label: 'Focus Strength',
62+
max: 200,
63+
min: 0,
64+
tooltip: 'Center boost/magnification',
65+
})
66+
focusStrength!: number
67+
68+
@NumberControl({
69+
default: 60,
70+
label: 'Peripheral Blur',
71+
max: 200,
72+
min: 0,
73+
tooltip: 'How much the periphery fades/softens',
74+
})
75+
peripheralBlur!: number
76+
77+
@NumberControl({
78+
default: 120,
79+
label: 'Saturation',
80+
max: 200,
81+
min: 0,
82+
tooltip: 'Color saturation',
83+
})
84+
saturation!: number
85+
86+
@NumberControl({
87+
default: 120,
88+
label: 'Energy (Brightness)',
89+
max: 200,
90+
min: 10,
91+
tooltip: 'Brightness/energy of the effect',
92+
})
93+
energy!: number
94+
95+
@NumberControl({
96+
default: 80,
97+
label: 'Spark Density',
98+
max: 200,
99+
min: 0,
100+
tooltip: 'Amount of dopamine sparks',
101+
})
102+
sparkDensity!: number
103+
104+
@NumberControl({
105+
default: 70,
106+
label: 'Tunnel Speed',
107+
max: 200,
108+
min: 0,
109+
tooltip: 'Motion speed of the tunnel rings',
110+
})
111+
tunnelSpeed!: number
112+
113+
@NumberControl({
114+
default: 25,
115+
label: 'Paralysis',
116+
max: 100,
117+
min: 0,
118+
tooltip: 'Executive dysfunction; reduces motion and spark speed',
119+
})
120+
paralysis!: number
121+
122+
@NumberControl({
123+
default: 40,
124+
label: 'Noise',
125+
max: 200,
126+
min: 0,
127+
tooltip: 'Film/noise amount, stronger in periphery',
128+
})
129+
noise!: number
130+
131+
@ComboboxControl({
132+
default: 'Dopamine',
133+
label: 'Color Mode',
134+
tooltip: 'Dopamine (warm/cool), Neon, or Mono',
135+
values: ['Dopamine', 'Neon', 'Mono'],
136+
})
137+
colorMode!: string
138+
139+
constructor() {
140+
super({
141+
debug: true,
142+
fragmentShader,
143+
id: 'adhd-hyperfocus',
144+
name: 'ADHD Hyperfocus',
145+
})
146+
}
147+
148+
protected initializeControls(): void {
149+
window.focusRadius = 28
150+
window.focusStrength = 120
151+
window.peripheralBlur = 60
152+
window.saturation = 120
153+
window.energy = 120
154+
window.sparkDensity = 80
155+
window.tunnelSpeed = 70
156+
window.paralysis = 25
157+
window.noise = 40
158+
window.colorMode = 'Dopamine'
159+
}
160+
161+
protected getControlValues(): ADHDHyperfocusControls {
162+
const colorModeIndex = comboboxValueToIndex(window.colorMode ?? 'Dopamine', this.colorModes, 0)
163+
return {
164+
colorMode: colorModeIndex,
165+
energy: normalizePercentage(window.energy ?? 120, 120, 0.1) * 2.0,
166+
focusRadius: normalizePercentage(window.focusRadius ?? 28, 100, 0.05),
167+
focusStrength: normalizePercentage(window.focusStrength ?? 120, 100, 0.0) * 2.0,
168+
noise: normalizePercentage(window.noise ?? 40, 100, 0.0) * 2.0,
169+
paralysis: normalizePercentage(window.paralysis ?? 25, 100, 0.0),
170+
peripheralBlur: normalizePercentage(window.peripheralBlur ?? 60, 100, 0.0) * 2.0,
171+
saturation: normalizePercentage(window.saturation ?? 120, 100, 0.0) * 2.0,
172+
sparkDensity: normalizePercentage(window.sparkDensity ?? 80, 100, 0.0) * 2.0,
173+
tunnelSpeed: normalizePercentage(window.tunnelSpeed ?? 70, 100, 0.0) * 2.0,
174+
}
175+
}
176+
177+
protected createUniforms(): Record<string, THREE.IUniform> {
178+
return {
179+
iColorMode: { value: 0 },
180+
iEnergy: { value: 1.2 },
181+
iFocusRadius: { value: 0.28 },
182+
iFocusStrength: { value: 1.2 },
183+
iNoise: { value: 0.8 },
184+
iParalysis: { value: 0.25 },
185+
iPeripheralBlur: { value: 1.2 },
186+
iSaturation: { value: 1.2 },
187+
iSparkDensity: { value: 1.0 },
188+
iTunnelSpeed: { value: 1.0 },
189+
}
190+
}
191+
192+
protected updateUniforms(c: ADHDHyperfocusControls): void {
193+
if (!this.material) return
194+
this.material.uniforms.iFocusRadius.value = c.focusRadius
195+
this.material.uniforms.iFocusStrength.value = c.focusStrength
196+
this.material.uniforms.iPeripheralBlur.value = c.peripheralBlur
197+
this.material.uniforms.iSaturation.value = c.saturation
198+
this.material.uniforms.iEnergy.value = c.energy
199+
this.material.uniforms.iSparkDensity.value = c.sparkDensity
200+
this.material.uniforms.iTunnelSpeed.value = c.tunnelSpeed
201+
this.material.uniforms.iParalysis.value = c.paralysis
202+
this.material.uniforms.iNoise.value = c.noise
203+
this.material.uniforms.iColorMode.value = c.colorMode
204+
}
205+
}
206+
207+
const effect = new ADHDHyperfocusEffect()
208+
initializeEffect(() => effect.initialize())
209+
export default effect

0 commit comments

Comments
 (0)