@dopaminefx/effect-aurora 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,417 @@
1
+ {
2
+ "fmt": "dopamine-effect",
3
+ "v": "1.0.0",
4
+ "id": "dopamine.success.aurora",
5
+ "meta": {
6
+ "name": "Aurora",
7
+ "description": "Hanging curtains of polar light that drape across the upper field, sway and sweep, then gently brighten and fade.",
8
+ "tags": [
9
+ "success",
10
+ "ambient",
11
+ "aurora",
12
+ "directional",
13
+ "curtain"
14
+ ]
15
+ },
16
+ "controls": {
17
+ "mood": {
18
+ "type": "enum",
19
+ "label": "Mood",
20
+ "default": "serene",
21
+ "options": [
22
+ "serene",
23
+ "celebratory",
24
+ "electric"
25
+ ],
26
+ "ui": "segmented"
27
+ },
28
+ "intensity": {
29
+ "type": "scalar",
30
+ "label": "Intensity",
31
+ "default": 0.7,
32
+ "min": 0,
33
+ "max": 1,
34
+ "step": 0.01,
35
+ "ui": "slider",
36
+ "help": "Brightness, curtain coverage and band height."
37
+ },
38
+ "whimsy": {
39
+ "type": "scalar",
40
+ "label": "Whimsy",
41
+ "default": 0.4,
42
+ "min": 0,
43
+ "max": 1,
44
+ "step": 0.01,
45
+ "ui": "slider",
46
+ "help": "Photoreal soft volumetric curtains (0) to stylized hard cel / posterized ribbons (1)."
47
+ },
48
+ "seed": {
49
+ "type": "int",
50
+ "label": "Seed",
51
+ "default": null,
52
+ "nullable": true,
53
+ "help": "Null = unique palette per fire; pin to reproduce."
54
+ },
55
+ "target": {
56
+ "type": "selector",
57
+ "label": "Target",
58
+ "default": "document.body"
59
+ }
60
+ },
61
+ "baselines": {
62
+ "serene": {
63
+ "durationMs": 3200,
64
+ "lightness": 0.86,
65
+ "chroma": 0.1,
66
+ "hueCenter": 168,
67
+ "hueRange": 70,
68
+ "coverage": 0.55,
69
+ "bandY": 0.66,
70
+ "bandHeight": 0.28,
71
+ "sway": 0.06,
72
+ "striation": 0.6,
73
+ "rays": 0.35,
74
+ "overshoot": 0.4
75
+ },
76
+ "celebratory": {
77
+ "durationMs": 2600,
78
+ "lightness": 0.85,
79
+ "chroma": 0.16,
80
+ "hueCenter": 190,
81
+ "hueRange": 200,
82
+ "coverage": 0.7,
83
+ "bandY": 0.64,
84
+ "bandHeight": 0.31,
85
+ "sway": 0.08,
86
+ "striation": 0.72,
87
+ "rays": 0.5,
88
+ "overshoot": 0.7
89
+ },
90
+ "electric": {
91
+ "durationMs": 2100,
92
+ "lightness": 0.84,
93
+ "chroma": 0.23,
94
+ "hueCenter": 320,
95
+ "hueRange": 150,
96
+ "coverage": 0.85,
97
+ "bandY": 0.62,
98
+ "bandHeight": 0.34,
99
+ "sway": 0.11,
100
+ "striation": 0.88,
101
+ "rays": 0.7,
102
+ "overshoot": 1
103
+ }
104
+ },
105
+ "palette": {
106
+ "model": "oklch",
107
+ "space": "linear-srgb",
108
+ "generator": "golden-angle",
109
+ "goldenAngleDeg": 137.50776405003785,
110
+ "stops": 3,
111
+ "hueSpread": 0.22,
112
+ "lightness": {
113
+ "baseline": "lightness",
114
+ "perStop": [
115
+ 0,
116
+ 0.06,
117
+ -0.05
118
+ ]
119
+ },
120
+ "chroma": {
121
+ "from": {
122
+ "mul": [
123
+ {
124
+ "baseline": "chroma"
125
+ },
126
+ {
127
+ "lerp": [
128
+ "intensity",
129
+ 0.7,
130
+ 1.5
131
+ ]
132
+ }
133
+ ]
134
+ },
135
+ "perStop": [
136
+ 0,
137
+ 0.02,
138
+ -0.01
139
+ ]
140
+ },
141
+ "seed": {
142
+ "deterministic": true,
143
+ "source": "controls.seed",
144
+ "prng": "mulberry32"
145
+ },
146
+ "perMood": {
147
+ "serene": {
148
+ "hueCenter": 165,
149
+ "hueRange": 110,
150
+ "lightness": 0.84,
151
+ "chroma": 0.11
152
+ },
153
+ "celebratory": {
154
+ "hueCenter": 200,
155
+ "hueRange": 300,
156
+ "lightness": 0.83,
157
+ "chroma": 0.17
158
+ },
159
+ "electric": {
160
+ "hueCenter": 320,
161
+ "hueRange": 180,
162
+ "lightness": 0.82,
163
+ "chroma": 0.24
164
+ }
165
+ }
166
+ },
167
+ "tempo": {
168
+ "durationMs": {
169
+ "from": {
170
+ "round": {
171
+ "mul": [
172
+ {
173
+ "baseline": "durationMs"
174
+ },
175
+ {
176
+ "lerp": [
177
+ "intensity",
178
+ 1.1,
179
+ 0.9
180
+ ]
181
+ }
182
+ ]
183
+ }
184
+ }
185
+ },
186
+ "frame": {
187
+ "amp": {
188
+ "envelope": [
189
+ {
190
+ "input": "life"
191
+ },
192
+ {
193
+ "param": "overshoot"
194
+ }
195
+ ]
196
+ },
197
+ "extras": {
198
+ "sweep": {
199
+ "mul": [
200
+ 0.02,
201
+ {
202
+ "div": [
203
+ {
204
+ "input": "animMs"
205
+ },
206
+ 1000
207
+ ]
208
+ },
209
+ {
210
+ "sub": [
211
+ 1,
212
+ {
213
+ "mul": [
214
+ 0.5,
215
+ {
216
+ "input": "life"
217
+ }
218
+ ]
219
+ }
220
+ ]
221
+ }
222
+ ]
223
+ }
224
+ }
225
+ },
226
+ "reducedMotion": {
227
+ "peakMs": 520,
228
+ "holdMs": 520
229
+ }
230
+ },
231
+ "geometry": {
232
+ "kind": "directional",
233
+ "viewBox": [
234
+ 0,
235
+ 0,
236
+ 100,
237
+ 100
238
+ ]
239
+ },
240
+ "render": {
241
+ "params": {
242
+ "exposure": {
243
+ "type": "float",
244
+ "from": {
245
+ "lerp": [
246
+ "intensity",
247
+ 0.85,
248
+ 1.55
249
+ ]
250
+ }
251
+ },
252
+ "overshoot": {
253
+ "type": "float",
254
+ "from": {
255
+ "mul": [
256
+ {
257
+ "baseline": "overshoot"
258
+ },
259
+ {
260
+ "lerp": [
261
+ "intensity",
262
+ 0.7,
263
+ 1.2
264
+ ]
265
+ }
266
+ ]
267
+ }
268
+ },
269
+ "coverage": {
270
+ "type": "float",
271
+ "clamp01": true,
272
+ "from": {
273
+ "mul": [
274
+ {
275
+ "baseline": "coverage"
276
+ },
277
+ {
278
+ "lerp": [
279
+ "intensity",
280
+ 0.7,
281
+ 1.25
282
+ ]
283
+ }
284
+ ]
285
+ }
286
+ },
287
+ "bandY": {
288
+ "type": "float",
289
+ "from": {
290
+ "baseline": "bandY"
291
+ }
292
+ },
293
+ "bandHeight": {
294
+ "type": "float",
295
+ "clamp01": true,
296
+ "from": {
297
+ "mul": [
298
+ {
299
+ "baseline": "bandHeight"
300
+ },
301
+ {
302
+ "lerp": [
303
+ "intensity",
304
+ 0.85,
305
+ 1.15
306
+ ]
307
+ }
308
+ ]
309
+ }
310
+ },
311
+ "sway": {
312
+ "type": "float",
313
+ "from": {
314
+ "mul": [
315
+ {
316
+ "baseline": "sway"
317
+ },
318
+ {
319
+ "lerp": [
320
+ "intensity",
321
+ 0.85,
322
+ 1.2
323
+ ]
324
+ }
325
+ ]
326
+ }
327
+ },
328
+ "striation": {
329
+ "type": "float",
330
+ "clamp01": true,
331
+ "from": {
332
+ "mul": [
333
+ {
334
+ "baseline": "striation"
335
+ },
336
+ {
337
+ "lerp": [
338
+ "whimsy",
339
+ 0.9,
340
+ 1.1
341
+ ]
342
+ }
343
+ ]
344
+ }
345
+ },
346
+ "rays": {
347
+ "type": "float",
348
+ "clamp01": true,
349
+ "from": {
350
+ "mul": [
351
+ {
352
+ "baseline": "rays"
353
+ },
354
+ {
355
+ "lerp": [
356
+ "intensity",
357
+ 0.8,
358
+ 1.2
359
+ ]
360
+ }
361
+ ]
362
+ }
363
+ },
364
+ "style": {
365
+ "type": "float",
366
+ "from": {
367
+ "control": "whimsy"
368
+ }
369
+ }
370
+ },
371
+ "shadowHeightFrac": {
372
+ "mul": [
373
+ {
374
+ "param": "bandHeight"
375
+ },
376
+ 0.6
377
+ ]
378
+ },
379
+ "consts": {
380
+ "MAX_CURTAINS": 7
381
+ },
382
+ "config": {
383
+ "usesOrigin": false
384
+ },
385
+ "backends": {
386
+ "webgl2": {
387
+ "stage": "fullscreen-triangle",
388
+ "blend": "screen",
389
+ "shader": {
390
+ "program": "aurora"
391
+ }
392
+ }
393
+ },
394
+ "fallbackOrder": [
395
+ "webgl2"
396
+ ]
397
+ },
398
+ "binding": {
399
+ "note": "CROSS-PLATFORM uniform-binding contract. Which render.params are NOT shader uniforms, the seed-keyed scatter field, the per-frame/host extras, and the texture samplers — one source of truth for the web u<Name> list, the Swift struct + packer, and the MSL struct. SHIPS in the portable .dope (the runtime derives its uniform bindings from it); the toolchain consumes it too for the Metal struct codegen. Only `x-build`, `slug` and `kind` stay toolchain-only.",
400
+ "excludeParams": [
401
+ "style",
402
+ "overshoot",
403
+ "durationMs"
404
+ ],
405
+ "scatterKey": "auroraSeed",
406
+ "scatterWeb": "uSeed",
407
+ "extras": [
408
+ {
409
+ "name": "sweep",
410
+ "type": "float",
411
+ "web": "uSweep",
412
+ "note": "accumulated sideways sweep (fraction of width)"
413
+ }
414
+ ],
415
+ "samplers": []
416
+ }
417
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Aurora — a calm success / ambient effect rendered through the generic
3
+ * fullscreen pass runner.
4
+ *
5
+ * Hanging CURTAINS of polar light drape across the upper field, sway and sweep
6
+ * sideways, then gently brighten and fade. It is DIRECTIONAL/curtain — a
7
+ * horizontal band of vertical light ribbons with soft vertical striations —
8
+ * deliberately NOT a radial bloom (it composes across the whole upper surface,
9
+ * so it ignores the anchor: no origin).
10
+ *
11
+ * FULLY DATA-DRIVEN (P2): everything that isn't the GLSL lives in
12
+ * aurora.dope.json — the mood→params mapping + palette (the loader), AND the
13
+ * per-frame logic: `tempo.frame` (the envelope amp + the accumulated sideways
14
+ * sweep), `render.shadowHeightFrac`, `render.consts`, `render.config` and the
15
+ * uniform `binding` contract. `registerDopeEffect` interprets that data through
16
+ * the generic pass runner; this module is just the shader + the registration
17
+ * call.
18
+ *
19
+ * Feeling mapping:
20
+ * - mood → palette + baselines: serene = cool green/teal/blue,
21
+ * celebratory = balanced multi-hue, electric = vivid magenta/teal.
22
+ * - intensity→ brightness (uExposure) + curtain coverage/height (uCoverage,
23
+ * uBandHeight, ribbon count) + drift (uSway) + overshoot.
24
+ * - whimsy → uStyle: photoreal soft volumetric curtains (0) → stylized hard
25
+ * cel / posterized ribbons (1); the pass runner also snaps the
26
+ * clock "on twos" as style rises.
27
+ */
28
+ import { type EffectFactory, type PassParams } from "@dopaminefx/core";
29
+ /** Resolved aurora params: the loader output + the named scatter seed. */
30
+ export interface AuroraParams extends PassParams {
31
+ exposure: number;
32
+ overshoot: number;
33
+ coverage: number;
34
+ bandY: number;
35
+ bandHeight: number;
36
+ sway: number;
37
+ striation: number;
38
+ rays: number;
39
+ auroraSeed: number;
40
+ }
41
+ export declare const aurora: EffectFactory<AuroraParams>;
42
+ export default aurora;
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAAiC,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKtG,0EAA0E;AAC1E,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,eAAO,MAAM,MAAM,EAGgB,aAAa,CAAC,YAAY,CAAC,CAAC;AAE/D,eAAe,MAAM,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Aurora — a calm success / ambient effect rendered through the generic
3
+ * fullscreen pass runner.
4
+ *
5
+ * Hanging CURTAINS of polar light drape across the upper field, sway and sweep
6
+ * sideways, then gently brighten and fade. It is DIRECTIONAL/curtain — a
7
+ * horizontal band of vertical light ribbons with soft vertical striations —
8
+ * deliberately NOT a radial bloom (it composes across the whole upper surface,
9
+ * so it ignores the anchor: no origin).
10
+ *
11
+ * FULLY DATA-DRIVEN (P2): everything that isn't the GLSL lives in
12
+ * aurora.dope.json — the mood→params mapping + palette (the loader), AND the
13
+ * per-frame logic: `tempo.frame` (the envelope amp + the accumulated sideways
14
+ * sweep), `render.shadowHeightFrac`, `render.consts`, `render.config` and the
15
+ * uniform `binding` contract. `registerDopeEffect` interprets that data through
16
+ * the generic pass runner; this module is just the shader + the registration
17
+ * call.
18
+ *
19
+ * Feeling mapping:
20
+ * - mood → palette + baselines: serene = cool green/teal/blue,
21
+ * celebratory = balanced multi-hue, electric = vivid magenta/teal.
22
+ * - intensity→ brightness (uExposure) + curtain coverage/height (uCoverage,
23
+ * uBandHeight, ribbon count) + drift (uSway) + overshoot.
24
+ * - whimsy → uStyle: photoreal soft volumetric curtains (0) → stylized hard
25
+ * cel / posterized ribbons (1); the pass runner also snaps the
26
+ * clock "on twos" as style rises.
27
+ */
28
+ import { AURORA_FRAGMENT_SRC, AURORA_VERTEX_SRC } from "./aurora-shader.js";
29
+ import { parseDope, registerDopeEffect } from "@dopaminefx/core";
30
+ import doc from "./aurora.dope.json";
31
+ const DOPE = parseDope(doc);
32
+ // The whole factory (resolve / create / reducedMotion / program registration)
33
+ // is data: aurora.dope.json interpreted by the core backbone.
34
+ export const aurora = registerDopeEffect(DOPE, {
35
+ vertex: AURORA_VERTEX_SRC,
36
+ fragment: AURORA_FRAGMENT_SRC,
37
+ });
38
+ export default aurora;
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAuC,MAAM,kBAAkB,CAAC;AACtG,OAAO,GAAG,MAAM,oBAAoB,CAAC;AAErC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAa,CAAC,CAAC;AAetC,8EAA8E;AAC9E,8DAA8D;AAC9D,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE,mBAAmB;CAC9B,CAA6D,CAAC;AAE/D,eAAe,MAAM,CAAC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@dopaminefx/effect-aurora",
3
+ "version": "0.1.0",
4
+ "description": "Aurora — hanging curtains of polar light, a calm ambient success effect for Dopamine.",
5
+ "keywords": [
6
+ "dopamine-effect"
7
+ ],
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "src"
21
+ ],
22
+ "sideEffects": [
23
+ "./src/index.ts",
24
+ "./dist/index.js"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc -p tsconfig.json"
28
+ },
29
+ "dependencies": {
30
+ "@dopaminefx/core": "^0.1.0"
31
+ },
32
+ "license": "MIT",
33
+ "author": "10in30",
34
+ "homepage": "https://github.com/10in30/dopamine#readme",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/10in30/dopamine.git",
38
+ "directory": "effects/aurora/web"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/10in30/dopamine/issues"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }