@brochington/shader-backgrounds 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,128 @@
1
+ import { Color } from 'ogl';
2
+ import { ShaderPlugin } from '../core/types';
3
+
4
+ export type AuroraWavesConfig = {
5
+ /** Base background color */
6
+ backgroundColor: string;
7
+ /** Aurora ribbon primary color */
8
+ color1: string;
9
+ /** Aurora ribbon secondary color */
10
+ color2: string;
11
+ /** Overall brightness multiplier */
12
+ intensity?: number; // default 0.9
13
+ /** Motion speed */
14
+ speed?: number; // default 0.6
15
+ /** Noise scale (bigger = larger features) */
16
+ scale?: number; // default 1.6
17
+ /** Subtle film grain */
18
+ grainAmount?: number; // default 0.05
19
+ };
20
+
21
+ export class AuroraWavesPlugin implements ShaderPlugin {
22
+ name = 'aurora-waves';
23
+
24
+ fragmentShader = /* glsl */ `
25
+ precision highp float;
26
+ uniform float uTimeInternal;
27
+ uniform vec2 uResolution;
28
+ uniform vec3 uBg;
29
+ uniform vec3 uC1;
30
+ uniform vec3 uC2;
31
+ uniform float uIntensity;
32
+ uniform float uScale;
33
+ uniform float uGrain;
34
+
35
+ varying vec2 vUv;
36
+
37
+ float hash12(vec2 p) {
38
+ vec3 p3 = fract(vec3(p.xyx) * 0.1031);
39
+ p3 += dot(p3, p3.yzx + 33.33);
40
+ return fract((p3.x + p3.y) * p3.z);
41
+ }
42
+
43
+ float noise(vec2 p) {
44
+ vec2 i = floor(p);
45
+ vec2 f = fract(p);
46
+ float a = hash12(i);
47
+ float b = hash12(i + vec2(1.0, 0.0));
48
+ float c = hash12(i + vec2(0.0, 1.0));
49
+ float d = hash12(i + vec2(1.0, 1.0));
50
+ vec2 u = f * f * (3.0 - 2.0 * f);
51
+ return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
52
+ }
53
+
54
+ float fbm(vec2 p) {
55
+ float v = 0.0;
56
+ float a = 0.5;
57
+ mat2 rot = mat2(0.80, -0.60, 0.60, 0.80);
58
+ for (int i = 0; i < 5; i++) {
59
+ v += a * noise(p);
60
+ p = rot * p * 2.02 + 19.19;
61
+ a *= 0.55;
62
+ }
63
+ return v;
64
+ }
65
+
66
+ void main() {
67
+ float aspect = uResolution.x / uResolution.y;
68
+ vec2 uv = vUv;
69
+ vec2 p = (uv - 0.5) * vec2(aspect, 1.0);
70
+
71
+ float t = uTimeInternal;
72
+ vec3 col = uBg;
73
+
74
+ // Ribbon field: layered sin waves warped by fbm
75
+ float warp = fbm(p * (uScale * 0.9) + vec2(0.0, 0.10 * t));
76
+ float warp2 = fbm(p * (uScale * 1.3) + vec2(4.0, -0.07 * t));
77
+ float y = p.y + (warp - 0.5) * 0.55 + (warp2 - 0.5) * 0.35;
78
+
79
+ // Multiple ribbons at different heights
80
+ float band1 = exp(-pow((y - 0.15 + 0.08 * sin(p.x * 1.2 + t * 0.6)), 2.0) * 18.0);
81
+ float band2 = exp(-pow((y + 0.05 + 0.10 * sin(p.x * 0.9 - t * 0.5)), 2.0) * 14.0);
82
+ float band3 = exp(-pow((y - 0.35 + 0.06 * sin(p.x * 1.6 + t * 0.4)), 2.0) * 22.0);
83
+
84
+ float bands = clamp(band1 + 0.8 * band2 + 0.6 * band3, 0.0, 1.5);
85
+ // Soft flicker-free shimmer via low-frequency fbm
86
+ float shimmer = 0.65 + 0.35 * fbm(p * (uScale * 0.6) + vec2(2.0, t * 0.12));
87
+
88
+ vec3 aur = mix(uC1, uC2, clamp(0.5 + 0.5 * sin(p.x * 0.7 + t * 0.25 + warp * 2.0), 0.0, 1.0));
89
+ col += aur * (bands * shimmer) * uIntensity;
90
+
91
+ // Gentle vertical fade (so content remains readable)
92
+ float fade = smoothstep(-0.9, 0.2, p.y);
93
+ col = mix(col, uBg, fade * 0.35);
94
+
95
+ // Grain
96
+ float g = (hash12(uv * uResolution + t * 60.0) - 0.5) * 2.0;
97
+ col += g * uGrain;
98
+
99
+ gl_FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
100
+ }
101
+ `;
102
+
103
+ uniforms: any;
104
+ private speed: number;
105
+
106
+ constructor(config: AuroraWavesConfig) {
107
+ const bg = new Color(config.backgroundColor);
108
+ const c1 = new Color(config.color1);
109
+ const c2 = new Color(config.color2);
110
+ this.speed = config.speed ?? 0.6;
111
+
112
+ this.uniforms = {
113
+ uBg: { value: [bg.r, bg.g, bg.b] },
114
+ uC1: { value: [c1.r, c1.g, c1.b] },
115
+ uC2: { value: [c2.r, c2.g, c2.b] },
116
+ uIntensity: { value: config.intensity ?? 0.9 },
117
+ uScale: { value: config.scale ?? 1.6 },
118
+ uGrain: { value: config.grainAmount ?? 0.05 },
119
+ uTimeInternal: { value: 0 },
120
+ };
121
+ }
122
+
123
+ onRender(dt: number) {
124
+ this.uniforms.uTimeInternal.value += dt * 0.001 * this.speed;
125
+ }
126
+ }
127
+
128
+
@@ -0,0 +1,128 @@
1
+ import { Color } from 'ogl';
2
+ import { ShaderPlugin } from '../core/types';
3
+
4
+ export type CausticsConfig = {
5
+ color: string; // The light color (e.g. Cyan/White)
6
+ backgroundColor: string; // Deep blue
7
+ intensity?: number; // Brightness of the lines
8
+ speed?: number;
9
+ scale?: number; // Pattern scale, default 2.2
10
+ distortion?: number; // 0..2, default 0.9
11
+ sharpness?: number; // 1..6, default 3.2
12
+ antiAlias?: number; // 0..2, default 1.0 (higher = smoother)
13
+ };
14
+
15
+ export class CausticsPlugin implements ShaderPlugin {
16
+ name = 'caustics';
17
+
18
+ fragmentShader = /* glsl */ `
19
+ precision highp float;
20
+ #ifdef GL_OES_standard_derivatives
21
+ #extension GL_OES_standard_derivatives : enable
22
+ #endif
23
+
24
+ uniform float uTimeInternal;
25
+ uniform vec2 uResolution;
26
+ uniform vec3 uColor;
27
+ uniform vec3 uBgColor;
28
+ uniform float uIntensity;
29
+ uniform float uScale;
30
+ uniform float uDistortion;
31
+ uniform float uSharpness;
32
+ uniform float uAA;
33
+
34
+ varying vec2 vUv;
35
+
36
+ float aawidth(float x) {
37
+ #ifdef GL_OES_standard_derivatives
38
+ return fwidth(x);
39
+ #else
40
+ // Fallback: approximate 1 pixel in normalized space.
41
+ return 1.0 / max(1.0, min(uResolution.x, uResolution.y));
42
+ #endif
43
+ }
44
+
45
+ float hash12(vec2 p) {
46
+ vec3 p3 = fract(vec3(p.xyx) * 0.1031);
47
+ p3 += dot(p3, p3.yzx + 33.33);
48
+ return fract((p3.x + p3.y) * p3.z);
49
+ }
50
+
51
+ // Textureless "caustics-ish" pattern: warped cells + exponential falloff
52
+ float caustics(vec2 p, float t) {
53
+ float c = 0.0;
54
+ float a = 1.0;
55
+
56
+ // Add a slow, large-scale warp so it doesn't look like static tiles
57
+ p += uDistortion * vec2(
58
+ sin(p.y * 1.7 + t * 0.8),
59
+ sin(p.x * 1.3 - t * 0.7)
60
+ );
61
+
62
+ for (int i = 0; i < 4; i++) {
63
+ // repeat + distance to nearest cell edge (0 at edges)
64
+ vec2 q = abs(fract(p) - 0.5);
65
+ float edgeDist = min(q.x, q.y);
66
+
67
+ // Derivative-based AA: widen the transition as frequency increases
68
+ float w = aawidth(edgeDist) * (1.0 + uAA * 2.0);
69
+
70
+ // Bright lines near edges, with controllable sharpness
71
+ float line = 1.0 - smoothstep(0.0, w, edgeDist);
72
+ // Emphasize peaks without introducing harsh aliasing
73
+ float web = pow(clamp(line, 0.0, 1.0), uSharpness);
74
+ c += web * a;
75
+
76
+ // zoom and drift
77
+ p = p * 1.65 + vec2(0.12 * t, -0.10 * t);
78
+ p += (hash12(p + float(i) * 7.7) - 0.5) * 0.25;
79
+ a *= 0.72;
80
+ }
81
+
82
+ return c;
83
+ }
84
+
85
+ void main() {
86
+ float aspect = uResolution.x / uResolution.y;
87
+ vec2 p = (vUv - 0.5) * vec2(aspect, 1.0);
88
+ float t = uTimeInternal;
89
+
90
+ // scale in aspect-correct domain
91
+ p *= uScale;
92
+
93
+ float c = caustics(p, t);
94
+
95
+ // shape + intensity
96
+ float brightness = pow(clamp(c, 0.0, 2.0), 1.35) * uIntensity;
97
+
98
+ vec3 col = uBgColor + uColor * brightness;
99
+
100
+ gl_FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
101
+ }
102
+ `;
103
+
104
+ uniforms: any;
105
+ private speed: number;
106
+
107
+ constructor(config: CausticsConfig) {
108
+ const c = new Color(config.color);
109
+ const bg = new Color(config.backgroundColor);
110
+ this.speed = config.speed ?? 0.5;
111
+
112
+ this.uniforms = {
113
+ uColor: { value: [c.r, c.g, c.b] },
114
+ uBgColor: { value: [bg.r, bg.g, bg.b] },
115
+ uIntensity: { value: config.intensity ?? 1.0 },
116
+ uScale: { value: config.scale ?? 2.2 },
117
+ uDistortion: { value: config.distortion ?? 0.9 },
118
+ uSharpness: { value: config.sharpness ?? 3.2 },
119
+ uAA: { value: config.antiAlias ?? 1.0 },
120
+ uTimeInternal: { value: 0 },
121
+ };
122
+ }
123
+
124
+ onRender(dt: number) {
125
+ // We update our own time uniform to control the wave speed
126
+ this.uniforms.uTimeInternal.value += dt * 0.001 * this.speed;
127
+ }
128
+ }
@@ -0,0 +1,148 @@
1
+ import { Color } from 'ogl';
2
+ import { ShaderPlugin } from '../core/types';
3
+
4
+ export type ContourLinesConfig = {
5
+ backgroundColor: string;
6
+ lineColor: string;
7
+ accentColor?: string; // default derived from lineColor
8
+ /** Lines per unit */
9
+ density?: number; // default 12
10
+ /** Line thickness */
11
+ thickness?: number; // default 0.075
12
+ /** Warp amount */
13
+ warp?: number; // default 0.9
14
+ /** Motion speed */
15
+ speed?: number; // default 0.35
16
+ /** Glow amount */
17
+ glow?: number; // default 0.35
18
+ /** Grain amount */
19
+ grainAmount?: number; // default 0.04
20
+ };
21
+
22
+ export class ContourLinesPlugin implements ShaderPlugin {
23
+ name = 'contour-lines';
24
+
25
+ fragmentShader = /* glsl */ `
26
+ precision highp float;
27
+ #ifdef GL_OES_standard_derivatives
28
+ #extension GL_OES_standard_derivatives : enable
29
+ #endif
30
+
31
+ uniform float uTimeInternal;
32
+ uniform vec2 uResolution;
33
+ uniform vec3 uBg;
34
+ uniform vec3 uLine;
35
+ uniform vec3 uAccent;
36
+ uniform float uDensity;
37
+ uniform float uThickness;
38
+ uniform float uWarp;
39
+ uniform float uGlow;
40
+ uniform float uGrain;
41
+
42
+ varying vec2 vUv;
43
+
44
+ float hash12(vec2 p) {
45
+ vec3 p3 = fract(vec3(p.xyx) * 0.1031);
46
+ p3 += dot(p3, p3.yzx + 33.33);
47
+ return fract((p3.x + p3.y) * p3.z);
48
+ }
49
+
50
+ float noise(vec2 p) {
51
+ vec2 i = floor(p);
52
+ vec2 f = fract(p);
53
+ float a = hash12(i);
54
+ float b = hash12(i + vec2(1.0, 0.0));
55
+ float c = hash12(i + vec2(0.0, 1.0));
56
+ float d = hash12(i + vec2(1.0, 1.0));
57
+ vec2 u = f * f * (3.0 - 2.0 * f);
58
+ return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
59
+ }
60
+
61
+ float fbm(vec2 p) {
62
+ float v = 0.0;
63
+ float a = 0.5;
64
+ mat2 rot = mat2(0.80, -0.60, 0.60, 0.80);
65
+ for (int i = 0; i < 5; i++) {
66
+ v += a * noise(p);
67
+ p = rot * p * 2.02 + 19.19;
68
+ a *= 0.55;
69
+ }
70
+ return v;
71
+ }
72
+
73
+ float aawidth(float x) {
74
+ #ifdef GL_OES_standard_derivatives
75
+ return fwidth(x);
76
+ #else
77
+ return 1.0 / max(1.0, min(uResolution.x, uResolution.y));
78
+ #endif
79
+ }
80
+
81
+ void main() {
82
+ float aspect = uResolution.x / uResolution.y;
83
+ vec2 uv = vUv;
84
+ vec2 p = (uv - 0.5) * vec2(aspect, 1.0);
85
+ float t = uTimeInternal;
86
+
87
+ // Height field
88
+ vec2 flow = vec2(0.10 * t, -0.06 * t);
89
+ float h = fbm(p * 1.25 + flow);
90
+ float h2 = fbm(p * 2.10 + vec2(-0.05 * t, 0.08 * t));
91
+ float height = h + 0.55 * h2;
92
+
93
+ // Warp the domain so contours bend naturally
94
+ vec2 w = vec2(
95
+ fbm(p * 1.2 + vec2(2.0, 0.15 * t)),
96
+ fbm(p * 1.2 + vec2(7.0, -0.12 * t))
97
+ );
98
+ p += (w - 0.5) * uWarp;
99
+
100
+ // Contour function: periodic bands
101
+ float c = fract((height + 0.35 * fbm(p * 1.75 + 4.0)) * uDensity);
102
+ float distToLine = min(c, 1.0 - c);
103
+ float wAA = aawidth(distToLine) * 1.4;
104
+ float line = 1.0 - smoothstep(uThickness, uThickness + wAA, distToLine);
105
+
106
+ // Glow around lines
107
+ float glow = smoothstep(0.45, 0.0, distToLine) * uGlow;
108
+
109
+ vec3 col = uBg;
110
+ col += uLine * line;
111
+ col += uAccent * glow;
112
+
113
+ // Grain
114
+ float g = (hash12(uv * uResolution + t * 60.0) - 0.5) * 2.0;
115
+ col += g * uGrain;
116
+
117
+ gl_FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
118
+ }
119
+ `;
120
+
121
+ uniforms: any;
122
+ private speed: number;
123
+
124
+ constructor(config: ContourLinesConfig) {
125
+ const bg = new Color(config.backgroundColor);
126
+ const line = new Color(config.lineColor);
127
+ const accent = new Color(config.accentColor ?? config.lineColor);
128
+ this.speed = config.speed ?? 0.35;
129
+
130
+ this.uniforms = {
131
+ uBg: { value: [bg.r, bg.g, bg.b] },
132
+ uLine: { value: [line.r, line.g, line.b] },
133
+ uAccent: { value: [accent.r, accent.g, accent.b] },
134
+ uDensity: { value: config.density ?? 12 },
135
+ uThickness: { value: config.thickness ?? 0.075 },
136
+ uWarp: { value: config.warp ?? 0.9 },
137
+ uGlow: { value: config.glow ?? 0.35 },
138
+ uGrain: { value: config.grainAmount ?? 0.04 },
139
+ uTimeInternal: { value: 0 },
140
+ };
141
+ }
142
+
143
+ onRender(dt: number) {
144
+ this.uniforms.uTimeInternal.value += dt * 0.001 * this.speed;
145
+ }
146
+ }
147
+
148
+
@@ -0,0 +1,191 @@
1
+ import { Color } from 'ogl';
2
+ import { ShaderPlugin } from '../core/types';
3
+
4
+ export type DreamyBokehConfig = {
5
+ /** Background gradient bottom/top */
6
+ backgroundBottom: string;
7
+ backgroundTop: string;
8
+
9
+ /** A 3-color palette for the bokeh highlights */
10
+ colorA?: string; // default "#ffd1f3"
11
+ colorB?: string; // default "#8be9ff"
12
+ colorC?: string; // default "#b7ff9b"
13
+
14
+ /** Bokeh density multiplier (0..3) */
15
+ density?: number; // default 1.0
16
+ /** Bokeh size multiplier (0.5..2) */
17
+ size?: number; // default 1.0
18
+ /** Edge softness / blur multiplier (0.5..2) */
19
+ blur?: number; // default 1.0
20
+ /** Motion speed */
21
+ speed?: number; // default 0.25
22
+ /** Vignette strength (0..1) */
23
+ vignette?: number; // default 0.35
24
+ /** Grain strength (0..0.15) */
25
+ grainAmount?: number; // default 0.03
26
+ };
27
+
28
+ export class DreamyBokehPlugin implements ShaderPlugin {
29
+ name = 'dreamy-bokeh';
30
+
31
+ fragmentShader = /* glsl */ `
32
+ precision highp float;
33
+
34
+ uniform float uTimeInternal;
35
+ uniform vec2 uResolution;
36
+ uniform vec3 uBg0;
37
+ uniform vec3 uBg1;
38
+ uniform vec3 uA;
39
+ uniform vec3 uB;
40
+ uniform vec3 uC;
41
+ uniform float uDensity;
42
+ uniform float uSize;
43
+ uniform float uBlur;
44
+ uniform float uVignette;
45
+ uniform float uGrain;
46
+
47
+ varying vec2 vUv;
48
+
49
+ float hash12(vec2 p) {
50
+ vec3 p3 = fract(vec3(p.xyx) * 0.1031);
51
+ p3 += dot(p3, p3.yzx + 33.33);
52
+ return fract((p3.x + p3.y) * p3.z);
53
+ }
54
+
55
+ vec2 hash22(vec2 p) {
56
+ float n = hash12(p);
57
+ return vec2(n, hash12(p + n + 19.19));
58
+ }
59
+
60
+ float softCircle(vec2 d, float r, float blur) {
61
+ float dist = length(d);
62
+ // inside -> 1, outside -> 0, with soft falloff
63
+ // NOTE: smoothstep requires edge0 < edge1.
64
+ float b = max(0.0001, blur);
65
+ float a = 1.0 - smoothstep(max(0.0, r - b), r, dist);
66
+ return a * a;
67
+ }
68
+
69
+ vec3 palette3(float h) {
70
+ // Smoothly mix between 3 user colors
71
+ float t0 = smoothstep(0.0, 1.0, h);
72
+ vec3 ab = mix(uA, uB, smoothstep(0.0, 0.65, t0));
73
+ return mix(ab, uC, smoothstep(0.35, 1.0, t0));
74
+ }
75
+
76
+ vec3 bokehLayer(vec2 uv, float scale, float t, float seed, float weight) {
77
+ vec2 p = uv * scale;
78
+ vec2 ip = floor(p);
79
+ vec2 fp = fract(p);
80
+
81
+ vec3 col = vec3(0.0);
82
+ float acc = 0.0;
83
+
84
+ // Look at neighboring cells so circles crossing boundaries still render.
85
+ for (int j = -1; j <= 1; j++) {
86
+ for (int i = -1; i <= 1; i++) {
87
+ vec2 cell = ip + vec2(float(i), float(j));
88
+ float r0 = hash12(cell + seed);
89
+
90
+ // density gate: fewer circles when density is low
91
+ float present = step(0.18, r0) * clamp(uDensity, 0.0, 3.0);
92
+ if (present <= 0.0) continue;
93
+
94
+ vec2 o = hash22(cell + seed * 1.7);
95
+
96
+ // Slow drift to avoid looking tiled/static.
97
+ // Drift amplitude intentionally small for background usage.
98
+ vec2 drift = 0.08 * vec2(
99
+ sin(t * 0.25 + r0 * 6.2831),
100
+ cos(t * 0.21 + r0 * 4.9132)
101
+ );
102
+
103
+ // Center in this cell (0..1), then shift to neighbor offset
104
+ vec2 c = vec2(float(i), float(j)) + o + drift;
105
+ vec2 d = fp - c;
106
+
107
+ float radius = mix(0.10, 0.44, pow(r0, 2.3)) * uSize;
108
+ float blur = mix(0.05, 0.18, hash12(cell + seed + 7.7)) * uBlur;
109
+
110
+ float a = softCircle(d, radius, blur);
111
+
112
+ // Add a soft “lens glow” lobe (subtle)
113
+ float glow = exp(-dot(d, d) / max(0.0001, radius * radius) * 1.9);
114
+ a = a * 0.72 + glow * 0.28;
115
+
116
+ // Color per circle, slightly biased to highlight variety
117
+ vec3 ccol = palette3(hash12(cell + seed + 3.3));
118
+
119
+ // Gentle twinkle (avoid flicker)
120
+ float tw = 1.0 + 0.12 * sin(t * 1.1 + r0 * 10.0);
121
+
122
+ col += ccol * a * tw;
123
+ acc += a;
124
+ }
125
+ }
126
+
127
+ // Normalize by accumulated alpha to keep brightness stable.
128
+ col *= weight / (1.0 + acc * 0.85);
129
+ return col;
130
+ }
131
+
132
+ void main() {
133
+ float aspect = uResolution.x / uResolution.y;
134
+ vec2 uv = vUv;
135
+ vec2 p = (uv - 0.5) * vec2(aspect, 1.0);
136
+ float t = uTimeInternal;
137
+
138
+ // Background gradient with a slight vertical curve.
139
+ float g = smoothstep(-0.7, 0.85, p.y + 0.08 * sin(p.x * 0.7));
140
+ vec3 col = mix(uBg0, uBg1, g);
141
+
142
+ // Multi-scale bokeh (parallax-ish via slight offsets).
143
+ col += bokehLayer(uv + vec2(-0.010 * t, 0.006 * t), 10.0, t, 11.0, 1.0);
144
+ col += bokehLayer(uv + vec2(-0.018 * t, 0.010 * t), 16.0, t + 3.7, 37.0, 0.9);
145
+ col += bokehLayer(uv + vec2(-0.030 * t, 0.016 * t), 26.0, t + 9.1, 83.0, 0.7);
146
+
147
+ // Vignette
148
+ float v = 1.0 - smoothstep(0.25, 1.15, length(p * vec2(1.0, 0.9)));
149
+ col *= mix(1.0, v, clamp(uVignette, 0.0, 1.0));
150
+
151
+ // Grain
152
+ float gr = (hash12(uv * uResolution + t * 61.0) - 0.5) * 2.0;
153
+ col += gr * uGrain;
154
+
155
+ gl_FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
156
+ }
157
+ `;
158
+
159
+ uniforms: any;
160
+ private speed: number;
161
+
162
+ constructor(config: DreamyBokehConfig) {
163
+ const bg0 = new Color(config.backgroundBottom);
164
+ const bg1 = new Color(config.backgroundTop);
165
+ const a = new Color(config.colorA ?? '#ffd1f3');
166
+ const b = new Color(config.colorB ?? '#8be9ff');
167
+ const c = new Color(config.colorC ?? '#b7ff9b');
168
+
169
+ this.speed = config.speed ?? 0.25;
170
+
171
+ this.uniforms = {
172
+ uBg0: { value: [bg0.r, bg0.g, bg0.b] },
173
+ uBg1: { value: [bg1.r, bg1.g, bg1.b] },
174
+ uA: { value: [a.r, a.g, a.b] },
175
+ uB: { value: [b.r, b.g, b.b] },
176
+ uC: { value: [c.r, c.g, c.b] },
177
+ uDensity: { value: config.density ?? 1.0 },
178
+ uSize: { value: config.size ?? 1.0 },
179
+ uBlur: { value: config.blur ?? 1.0 },
180
+ uVignette: { value: config.vignette ?? 0.35 },
181
+ uGrain: { value: config.grainAmount ?? 0.03 },
182
+ uTimeInternal: { value: 0 },
183
+ };
184
+ }
185
+
186
+ onRender(dt: number) {
187
+ this.uniforms.uTimeInternal.value += dt * 0.001 * this.speed;
188
+ }
189
+ }
190
+
191
+