react-native-webrtc-kaleidoscope 2.3.0 → 2.5.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.
Files changed (110) hide show
  1. package/README.md +12 -3
  2. package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/ShadersGenerated.kt +354 -0
  3. package/catalog/composites/clouds/clouds.thumb.webp +0 -0
  4. package/catalog/composites/corporate-blobs/corporate-blobs.thumb.webp +0 -0
  5. package/catalog/composites/fairy-cave/fairy-cave.thumb.webp +0 -0
  6. package/catalog/composites/fairy-grotto/fairy-grotto.thumb.webp +0 -0
  7. package/catalog/composites/fairy-hollow/fairy-hollow.thumb.webp +0 -0
  8. package/catalog/composites/nebula/nebula.thumb.webp +0 -0
  9. package/catalog/composites/observation-deck/observation-deck.thumb.webp +0 -0
  10. package/catalog/composites/simianlights/simianlights.thumb.webp +0 -0
  11. package/catalog/composites/underwater/underwater.thumb.webp +0 -0
  12. package/catalog/composites/wizard-tower/wizard-tower.thumb.webp +0 -0
  13. package/catalog/composites/wizard-tower-night/wizard-tower-night.thumb.webp +0 -0
  14. package/catalog/images/debug/debug-resolutions.thumb.webp +0 -0
  15. package/catalog/images/home/home-dark.thumb.webp +0 -0
  16. package/catalog/images/home/home-light.thumb.webp +0 -0
  17. package/catalog/images/nature/landscape-dark.thumb.webp +0 -0
  18. package/catalog/images/nature/landscape-light.thumb.webp +0 -0
  19. package/catalog/images/office/office-dark.thumb.webp +0 -0
  20. package/catalog/images/office/office-light.thumb.webp +0 -0
  21. package/catalog/images/sci-fi/sci-fi-light.thumb.webp +0 -0
  22. package/catalog/images/simiancraft/simiancraft-dark.thumb.webp +0 -0
  23. package/catalog/images/simiancraft/simiancraft-light.thumb.webp +0 -0
  24. package/catalog/images/underwater/oceanscape-dark.thumb.webp +0 -0
  25. package/catalog/shaders/aurora-silk/aurora-silk.form.tsx +35 -0
  26. package/catalog/shaders/aurora-silk/aurora-silk.frag +106 -0
  27. package/catalog/shaders/aurora-silk/aurora-silk.ts +92 -0
  28. package/catalog/shaders/halftone-waves/halftone-waves.form.tsx +35 -0
  29. package/catalog/shaders/halftone-waves/halftone-waves.frag +84 -0
  30. package/catalog/shaders/halftone-waves/halftone-waves.ts +100 -0
  31. package/catalog/shaders/index.ts +16 -0
  32. package/catalog/shaders/kaleidoscope/kaleidoscope.form.tsx +35 -0
  33. package/catalog/shaders/kaleidoscope/kaleidoscope.frag +93 -0
  34. package/catalog/shaders/kaleidoscope/kaleidoscope.ts +81 -0
  35. package/catalog/shaders/neo-memphis/neo-memphis.form.tsx +35 -0
  36. package/catalog/shaders/neo-memphis/neo-memphis.frag +152 -0
  37. package/catalog/shaders/neo-memphis/neo-memphis.ts +84 -0
  38. package/dist/catalog/composites/clouds/clouds.thumb.webp +0 -0
  39. package/dist/catalog/composites/corporate-blobs/corporate-blobs.thumb.webp +0 -0
  40. package/dist/catalog/composites/fairy-cave/fairy-cave.thumb.webp +0 -0
  41. package/dist/catalog/composites/fairy-grotto/fairy-grotto.thumb.webp +0 -0
  42. package/dist/catalog/composites/fairy-hollow/fairy-hollow.thumb.webp +0 -0
  43. package/dist/catalog/composites/nebula/nebula.thumb.webp +0 -0
  44. package/dist/catalog/composites/observation-deck/observation-deck.thumb.webp +0 -0
  45. package/dist/catalog/composites/simianlights/simianlights.thumb.webp +0 -0
  46. package/dist/catalog/composites/underwater/underwater.thumb.webp +0 -0
  47. package/dist/catalog/composites/wizard-tower/wizard-tower.thumb.webp +0 -0
  48. package/dist/catalog/composites/wizard-tower-night/wizard-tower-night.thumb.webp +0 -0
  49. package/dist/catalog/images/debug/debug-resolutions.thumb.webp +0 -0
  50. package/dist/catalog/images/home/home-dark.thumb.webp +0 -0
  51. package/dist/catalog/images/home/home-light.thumb.webp +0 -0
  52. package/dist/catalog/images/nature/landscape-dark.thumb.webp +0 -0
  53. package/dist/catalog/images/nature/landscape-light.thumb.webp +0 -0
  54. package/dist/catalog/images/office/office-dark.thumb.webp +0 -0
  55. package/dist/catalog/images/office/office-light.thumb.webp +0 -0
  56. package/dist/catalog/images/sci-fi/sci-fi-light.thumb.webp +0 -0
  57. package/dist/catalog/images/simiancraft/simiancraft-dark.thumb.webp +0 -0
  58. package/dist/catalog/images/simiancraft/simiancraft-light.thumb.webp +0 -0
  59. package/dist/catalog/images/underwater/oceanscape-dark.thumb.webp +0 -0
  60. package/dist/catalog/shaders/aurora-silk/aurora-silk.d.ts +26 -0
  61. package/dist/catalog/shaders/aurora-silk/aurora-silk.d.ts.map +1 -0
  62. package/dist/catalog/shaders/aurora-silk/aurora-silk.form.d.ts +3 -0
  63. package/dist/catalog/shaders/aurora-silk/aurora-silk.form.d.ts.map +1 -0
  64. package/dist/catalog/shaders/aurora-silk/aurora-silk.form.js +13 -0
  65. package/dist/catalog/shaders/aurora-silk/aurora-silk.form.js.map +1 -0
  66. package/dist/catalog/shaders/aurora-silk/aurora-silk.js +70 -0
  67. package/dist/catalog/shaders/aurora-silk/aurora-silk.js.map +1 -0
  68. package/dist/catalog/shaders/halftone-waves/halftone-waves.d.ts +26 -0
  69. package/dist/catalog/shaders/halftone-waves/halftone-waves.d.ts.map +1 -0
  70. package/dist/catalog/shaders/halftone-waves/halftone-waves.form.d.ts +3 -0
  71. package/dist/catalog/shaders/halftone-waves/halftone-waves.form.d.ts.map +1 -0
  72. package/dist/catalog/shaders/halftone-waves/halftone-waves.form.js +13 -0
  73. package/dist/catalog/shaders/halftone-waves/halftone-waves.form.js.map +1 -0
  74. package/dist/catalog/shaders/halftone-waves/halftone-waves.js +78 -0
  75. package/dist/catalog/shaders/halftone-waves/halftone-waves.js.map +1 -0
  76. package/dist/catalog/shaders/index.d.ts +16 -0
  77. package/dist/catalog/shaders/index.d.ts.map +1 -1
  78. package/dist/catalog/shaders/index.js +9 -1
  79. package/dist/catalog/shaders/index.js.map +1 -1
  80. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.d.ts +24 -0
  81. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.d.ts.map +1 -0
  82. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.form.d.ts +3 -0
  83. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.form.d.ts.map +1 -0
  84. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.form.js +14 -0
  85. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.form.js.map +1 -0
  86. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.js +61 -0
  87. package/dist/catalog/shaders/kaleidoscope/kaleidoscope.js.map +1 -0
  88. package/dist/catalog/shaders/neo-memphis/neo-memphis.d.ts +26 -0
  89. package/dist/catalog/shaders/neo-memphis/neo-memphis.d.ts.map +1 -0
  90. package/dist/catalog/shaders/neo-memphis/neo-memphis.form.d.ts +3 -0
  91. package/dist/catalog/shaders/neo-memphis/neo-memphis.form.d.ts.map +1 -0
  92. package/dist/catalog/shaders/neo-memphis/neo-memphis.form.js +13 -0
  93. package/dist/catalog/shaders/neo-memphis/neo-memphis.form.js.map +1 -0
  94. package/dist/catalog/shaders/neo-memphis/neo-memphis.js +62 -0
  95. package/dist/catalog/shaders/neo-memphis/neo-memphis.js.map +1 -0
  96. package/dist/web-driver/shaders.generated.d.ts +4 -0
  97. package/dist/web-driver/shaders.generated.d.ts.map +1 -1
  98. package/dist/web-driver/shaders.generated.js +351 -1
  99. package/dist/web-driver/shaders.generated.js.map +1 -1
  100. package/ios/KaleidoscopeModule/shaders/GENERATIVE.txt +4 -0
  101. package/ios/KaleidoscopeModule/shaders/SHADERS.txt +4 -0
  102. package/ios/KaleidoscopeModule/shaders/aurora-silk.metalsrc +51 -0
  103. package/ios/KaleidoscopeModule/shaders/halftone-waves.metalsrc +41 -0
  104. package/ios/KaleidoscopeModule/shaders/kaleidoscope.metalsrc +45 -0
  105. package/ios/KaleidoscopeModule/shaders/neo-memphis.metalsrc +181 -0
  106. package/package.json +36 -3
  107. package/tools/thumbnails/book-loader.ts +104 -0
  108. package/tools/thumbnails/make-thumbnails.ts +287 -0
  109. package/tools/thumbnails/office-fixture.webp +0 -0
  110. package/tools/thumbnails/render-page.ts +259 -0
@@ -0,0 +1,92 @@
1
+ // Aurora-silk layer-shader interface: typed uniforms + control descriptor.
2
+ // Noise-warped ribbon bands over a two-stop gradient (OS-swoosh through SaaS
3
+ // gradient), an opaque BACKGROUND layer (issue #61). One aurora-silk.frag
4
+ // fans out into the book presets (corporate-silk, dusk, polar) by varying
5
+ // these uniforms; the palette and uStyle are the big levers. Shader source is
6
+ // shaders/aurora-silk.frag.
7
+
8
+ import type { RGB } from '../../../src/lib/primitives.types';
9
+ import type { UniformControl } from '../_shared/types';
10
+
11
+ /** Typed uniforms for the `aurora-silk` layer shader. */
12
+ export type AuroraSilkUniforms = {
13
+ /** Gradient color at the flow's low side. */
14
+ readonly uColorLow: RGB;
15
+ /** Gradient color at the flow's high side. */
16
+ readonly uColorHigh: RGB;
17
+ /** Ribbon tint; back-of-stack ribbons shade toward uColorHigh. */
18
+ readonly uRibbonColor: RGB;
19
+ /** Visible ribbon count, 1..5. */
20
+ readonly uRibbons: number;
21
+ /** Ribbon edge softness; 0 = paper-cut crisp, 1 = fully diffuse. */
22
+ readonly uSoftness: number;
23
+ /** Flow direction in radians. */
24
+ readonly uAngle: number;
25
+ /** Drift rate; 0 freezes. */
26
+ readonly uSpeed: number;
27
+ /** Aesthetic morph: 0 flat paper-cut, 1 glowing silk. */
28
+ readonly uStyle: number;
29
+ /** Eases ribbons at frame center (the face zone); 0 = off. */
30
+ readonly uCalm: number;
31
+ };
32
+
33
+ /** The `aurora-silk` shader's tunables; defaults are the "corporate silk" look. */
34
+ export const AURORA_SILK_CONTROLS: readonly UniformControl[] = [
35
+ { name: 'uColorLow', kind: 'color', default: [0.08, 0.11, 0.22], doc: 'Gradient low color.' },
36
+ { name: 'uColorHigh', kind: 'color', default: [0.16, 0.29, 0.48], doc: 'Gradient high color.' },
37
+ { name: 'uRibbonColor', kind: 'color', default: [0.36, 0.62, 0.85], doc: 'Ribbon tint.' },
38
+ {
39
+ name: 'uRibbons',
40
+ kind: 'float',
41
+ default: 4,
42
+ min: 1,
43
+ max: 5,
44
+ step: 1,
45
+ doc: 'Visible ribbon count.',
46
+ },
47
+ {
48
+ name: 'uSoftness',
49
+ kind: 'float',
50
+ default: 0.7,
51
+ min: 0,
52
+ max: 1,
53
+ step: 0.01,
54
+ doc: 'Ribbon edge softness; 0 = paper-cut.',
55
+ },
56
+ {
57
+ name: 'uAngle',
58
+ kind: 'float',
59
+ default: 0.5,
60
+ min: 0,
61
+ max: 6.28,
62
+ step: 0.01,
63
+ doc: 'Flow direction, radians.',
64
+ },
65
+ {
66
+ name: 'uSpeed',
67
+ kind: 'float',
68
+ default: 0.6,
69
+ min: 0,
70
+ max: 2,
71
+ step: 0.01,
72
+ doc: 'Drift rate; 0 freezes.',
73
+ },
74
+ {
75
+ name: 'uStyle',
76
+ kind: 'float',
77
+ default: 0.8,
78
+ min: 0,
79
+ max: 1,
80
+ step: 0.01,
81
+ doc: '0 flat paper-cut, 1 glowing silk.',
82
+ },
83
+ {
84
+ name: 'uCalm',
85
+ kind: 'float',
86
+ default: 0,
87
+ min: 0,
88
+ max: 1,
89
+ step: 0.01,
90
+ doc: 'Eases ribbons at frame center (face zone).',
91
+ },
92
+ ];
@@ -0,0 +1,35 @@
1
+ // Halftone-waves' editor form: the shader OWNS its control layout (the plasma
2
+ // pattern). One <Control uniform="…"/> per uniform in declared order.
3
+ // Conventional layer id: "halftone-waves".
4
+
5
+ import {
6
+ Control,
7
+ ControlForm,
8
+ ControlSection,
9
+ type KaleidoscopeControls,
10
+ } from '../../../src/components/preset-control-panel';
11
+ import { HALFTONE_WAVES_CONTROLS } from './halftone-waves';
12
+
13
+ export function HalftoneWavesForm({ uniforms, onPatch, disabled }: KaleidoscopeControls) {
14
+ return (
15
+ <ControlForm
16
+ id="halftone-waves"
17
+ uniforms={uniforms['halftone-waves'] ?? {}}
18
+ onPatch={onPatch}
19
+ disabled={disabled}
20
+ controls={HALFTONE_WAVES_CONTROLS}
21
+ >
22
+ <ControlSection title="halftone-waves">
23
+ <Control uniform="uPaper" />
24
+ <Control uniform="uInk" />
25
+ <Control uniform="uPitch" />
26
+ <Control uniform="uDotSize" />
27
+ <Control uniform="uWaveAmp" />
28
+ <Control uniform="uSpeed" />
29
+ <Control uniform="uShape" />
30
+ <Control uniform="uAngle" />
31
+ <Control uniform="uCalm" />
32
+ </ControlSection>
33
+ </ControlForm>
34
+ );
35
+ }
@@ -0,0 +1,84 @@
1
+ // Halftone waves: a dot lattice whose dot size is modulated by slow traveling
2
+ // interference waves; the late-2000s "mathematical" tech texture as an opaque
3
+ // BACKGROUND layer (issue #61). The cheapest of the corporate-abstract set:
4
+ // per pixel, one hash-free cell lookup, two sines evaluated at the CELL CENTER
5
+ // (so every pixel of a dot agrees), and one blended distance metric. No noise,
6
+ // no pow, no loops.
7
+ //
8
+ // Overdrive surface: the two-tone palette inverts the whole mood (ink on
9
+ // paper vs paper on ink), uPitch sets the texture scale, uShape morphs the
10
+ // dots diamond -> circle -> square, uWaveAmp and uSpeed set how alive it is.
11
+ // uCalm eases the wave modulation near frame center, where the masked
12
+ // subject's face sits.
13
+ //
14
+ // UV convention: matches passthrough.vert. vUv = (0, 0) at bottom-left,
15
+ // (1, 1) at top-right. fragCoord is reconstructed as vUv * uResolution; no
16
+ // gl_FragCoord. Fully procedural: no input texture, zero net texture flips on
17
+ // every runtime.
18
+ //
19
+ // Precision: highp float, matching the other procedural shaders; the cell
20
+ // math is plain fract/floor and would survive mediump, but consistency wins.
21
+
22
+ #version 300 es
23
+ precision highp float;
24
+
25
+ uniform float uTime; // seconds, monotonically increasing; range [0, inf)
26
+ uniform vec2 uResolution; // framebuffer size in pixels; both components > 0
27
+ uniform vec3 uPaper; // field color (behind the dots)
28
+ uniform vec3 uInk; // dot color
29
+ uniform float uPitch; // dot-grid cells across frame height
30
+ uniform float uDotSize; // base dot radius in cell units, 0..0.5
31
+ uniform float uWaveAmp; // radius modulation depth, 0..1
32
+ uniform float uSpeed; // wave travel rate; 0 freezes
33
+ uniform float uShape; // dot shape: 0 diamond, 1 circle, 2 square
34
+ uniform float uAngle; // wave direction, radians
35
+ uniform float uCalm; // 0..1 eases the waves at frame center (face zone)
36
+
37
+ in highp vec2 vUv;
38
+ out vec4 oColor;
39
+
40
+ // Antialias half-width in cell units; ~1px at the default pitch.
41
+ const float AA = 0.06;
42
+
43
+ void main() {
44
+ // Aspect-correct, screen-centered coordinates (matches plasma/nebula).
45
+ vec2 fragCoord = vUv * uResolution;
46
+ vec2 uv = (fragCoord - 0.5 * uResolution) / uResolution.y;
47
+ float centerDist = length(uv);
48
+
49
+ vec2 luv = uv * uPitch;
50
+ vec2 id = floor(luv);
51
+ vec2 gv = fract(luv) - 0.5;
52
+ // Wave phase is sampled at the CELL CENTER so a dot's radius is uniform
53
+ // across its own pixels (true halftone, not a warped field).
54
+ vec2 c = (id + 0.5) / uPitch;
55
+
56
+ float t = uTime * uSpeed;
57
+ vec2 dir1 = vec2(cos(uAngle), sin(uAngle));
58
+ vec2 dir2 = vec2(cos(uAngle + 2.2), sin(uAngle + 2.2));
59
+ // Two traveling waves at incommensurate frequencies: interference patterns
60
+ // that drift forever without visibly repeating.
61
+ float w = 0.5 + 0.25 * sin(dot(c, dir1) * 3.1 + t) + 0.25 * sin(dot(c, dir2) * 4.7 - t * 0.77);
62
+
63
+ // uCalm: flatten the modulation toward its midpoint near frame center.
64
+ float calm = uCalm * (1.0 - smoothstep(0.15, 0.62, centerDist));
65
+ w = mix(w, 0.5, calm);
66
+
67
+ float radius = uDotSize * mix(1.0 - uWaveAmp, 1.0 + uWaveAmp, w);
68
+
69
+ // Blended distance metric, pow-free (variable-exponent pow lowers to
70
+ // exp2+log2 on mobile): diamond (L1) -> circle (L2) -> square (Linf).
71
+ vec2 q = abs(gv);
72
+ float dDiamond = (q.x + q.y) * 0.7071;
73
+ float dCircle = length(q);
74
+ float dSquare = max(q.x, q.y);
75
+ float d = (uShape < 1.0)
76
+ ? mix(dDiamond, dCircle, clamp(uShape, 0.0, 1.0))
77
+ : mix(dCircle, dSquare, clamp(uShape - 1.0, 0.0, 1.0));
78
+
79
+ float m = smoothstep(radius + AA, radius - AA, d);
80
+ vec3 color = mix(uPaper, uInk, m);
81
+
82
+ // Opaque procedural background; the person is composited over it downstream.
83
+ oColor = vec4(color, 1.0);
84
+ }
@@ -0,0 +1,100 @@
1
+ // Halftone-waves layer-shader interface: typed uniforms + control descriptor.
2
+ // A dot lattice with traveling-wave size modulation (the late-2000s
3
+ // "mathematical" tech texture), an opaque BACKGROUND layer (issue #61). One
4
+ // halftone-waves.frag fans out into the book presets (boardroom, press,
5
+ // ripple) by varying these uniforms; the two-tone palette is the big lever.
6
+ // Shader source is shaders/halftone-waves.frag.
7
+
8
+ import type { RGB } from '../../../src/lib/primitives.types';
9
+ import type { UniformControl } from '../_shared/types';
10
+
11
+ /** Typed uniforms for the `halftone-waves` layer shader. */
12
+ export type HalftoneWavesUniforms = {
13
+ /** Field color behind the dots. */
14
+ readonly uPaper: RGB;
15
+ /** Dot color. */
16
+ readonly uInk: RGB;
17
+ /** Dot-grid cells across frame height; higher = finer texture. */
18
+ readonly uPitch: number;
19
+ /** Base dot radius in cell units. */
20
+ readonly uDotSize: number;
21
+ /** Wave modulation depth; 0 = static even dots. */
22
+ readonly uWaveAmp: number;
23
+ /** Wave travel rate; 0 freezes. */
24
+ readonly uSpeed: number;
25
+ /** Dot shape: 0 diamond, 1 circle, 2 square. */
26
+ readonly uShape: number;
27
+ /** Wave direction in radians. */
28
+ readonly uAngle: number;
29
+ /** Eases the waves at frame center (the face zone); 0 = off. */
30
+ readonly uCalm: number;
31
+ };
32
+
33
+ /** The `halftone-waves` shader's tunables; defaults are the "boardroom" look. */
34
+ export const HALFTONE_WAVES_CONTROLS: readonly UniformControl[] = [
35
+ { name: 'uPaper', kind: 'color', default: [0.95, 0.95, 0.94], doc: 'Field color.' },
36
+ { name: 'uInk', kind: 'color', default: [0.62, 0.66, 0.7], doc: 'Dot color.' },
37
+ {
38
+ name: 'uPitch',
39
+ kind: 'float',
40
+ default: 26,
41
+ min: 8,
42
+ max: 60,
43
+ step: 1,
44
+ doc: 'Dot-grid cells across frame height.',
45
+ },
46
+ {
47
+ name: 'uDotSize',
48
+ kind: 'float',
49
+ default: 0.26,
50
+ min: 0.05,
51
+ max: 0.5,
52
+ step: 0.01,
53
+ doc: 'Base dot radius in cell units.',
54
+ },
55
+ {
56
+ name: 'uWaveAmp',
57
+ kind: 'float',
58
+ default: 0.55,
59
+ min: 0,
60
+ max: 1,
61
+ step: 0.01,
62
+ doc: 'Wave modulation depth.',
63
+ },
64
+ {
65
+ name: 'uSpeed',
66
+ kind: 'float',
67
+ default: 0.5,
68
+ min: 0,
69
+ max: 2,
70
+ step: 0.01,
71
+ doc: 'Wave travel rate; 0 freezes.',
72
+ },
73
+ {
74
+ name: 'uShape',
75
+ kind: 'float',
76
+ default: 1,
77
+ min: 0,
78
+ max: 2,
79
+ step: 0.05,
80
+ doc: 'Dot shape: 0 diamond, 1 circle, 2 square.',
81
+ },
82
+ {
83
+ name: 'uAngle',
84
+ kind: 'float',
85
+ default: 0.6,
86
+ min: 0,
87
+ max: 6.28,
88
+ step: 0.01,
89
+ doc: 'Wave direction, radians.',
90
+ },
91
+ {
92
+ name: 'uCalm',
93
+ kind: 'float',
94
+ default: 0,
95
+ min: 0,
96
+ max: 1,
97
+ step: 0.01,
98
+ doc: 'Eases the waves at frame center (face zone).',
99
+ },
100
+ ];
@@ -4,19 +4,25 @@
4
4
  // re-exported individually; a consumer imports the one its preset's layer needs.
5
5
 
6
6
  import type { AnamorphicLensFlareUniforms } from './anamorphic-lensflare/anamorphic-lensflare';
7
+ import type { AuroraSilkUniforms } from './aurora-silk/aurora-silk';
7
8
  import type { BlurUniforms } from './blur/blur';
8
9
  import type { CloudsUniforms } from './clouds/clouds';
9
10
  import type { CorporateBlobsUniforms } from './corporate-blobs/corporate-blobs';
10
11
  import type { FirefliesUniforms } from './fireflies/fireflies';
11
12
  import type { GodraysUniforms } from './godrays/godrays';
13
+ import type { HalftoneWavesUniforms } from './halftone-waves/halftone-waves';
14
+ import type { KaleidoscopeShaderUniforms } from './kaleidoscope/kaleidoscope';
12
15
  import type { LightBeamsAndMotesUniforms } from './light-beams-and-motes/light-beams-and-motes';
13
16
  import type { NebulaUniforms } from './nebula/nebula';
17
+ import type { NeoMemphisUniforms } from './neo-memphis/neo-memphis';
14
18
  import type { PlasmaUniforms } from './plasma/plasma';
15
19
  import type { SimianlightsUniforms } from './simianlights/simianlights';
16
20
 
17
21
  export { defaultUniforms, type UniformControl } from './_shared/types';
18
22
  export type { AnamorphicLensFlareUniforms } from './anamorphic-lensflare/anamorphic-lensflare';
19
23
  export { ANAMORPHIC_LENSFLARE_CONTROLS } from './anamorphic-lensflare/anamorphic-lensflare';
24
+ export type { AuroraSilkUniforms } from './aurora-silk/aurora-silk';
25
+ export { AURORA_SILK_CONTROLS } from './aurora-silk/aurora-silk';
20
26
  export type { BlurUniforms } from './blur/blur';
21
27
  export { BLUR_CONTROLS } from './blur/blur';
22
28
  export type { CloudsUniforms } from './clouds/clouds';
@@ -27,10 +33,16 @@ export type { FirefliesUniforms } from './fireflies/fireflies';
27
33
  export { FIREFLIES_CONTROLS } from './fireflies/fireflies';
28
34
  export type { GodraysUniforms } from './godrays/godrays';
29
35
  export { GODRAYS_CONTROLS } from './godrays/godrays';
36
+ export type { HalftoneWavesUniforms } from './halftone-waves/halftone-waves';
37
+ export { HALFTONE_WAVES_CONTROLS } from './halftone-waves/halftone-waves';
38
+ export type { KaleidoscopeShaderUniforms } from './kaleidoscope/kaleidoscope';
39
+ export { KALEIDOSCOPE_CONTROLS } from './kaleidoscope/kaleidoscope';
30
40
  export type { LightBeamsAndMotesUniforms } from './light-beams-and-motes/light-beams-and-motes';
31
41
  export { LIGHT_BEAMS_AND_MOTES_CONTROLS } from './light-beams-and-motes/light-beams-and-motes';
32
42
  export type { NebulaUniforms } from './nebula/nebula';
33
43
  export { NEBULA_CONTROLS } from './nebula/nebula';
44
+ export type { NeoMemphisUniforms } from './neo-memphis/neo-memphis';
45
+ export { NEO_MEMPHIS_CONTROLS } from './neo-memphis/neo-memphis';
34
46
  export type { PlasmaUniforms } from './plasma/plasma';
35
47
  export { PLASMA_CONTROLS } from './plasma/plasma';
36
48
  export type { SimianlightsUniforms } from './simianlights/simianlights';
@@ -47,10 +59,14 @@ export type ShaderUniformsMap = {
47
59
  readonly clouds: CloudsUniforms;
48
60
  readonly godrays: GodraysUniforms;
49
61
  readonly fireflies: FirefliesUniforms;
62
+ readonly kaleidoscope: KaleidoscopeShaderUniforms;
63
+ readonly 'halftone-waves': HalftoneWavesUniforms;
50
64
  readonly plasma: PlasmaUniforms;
51
65
  readonly nebula: NebulaUniforms;
66
+ readonly 'neo-memphis': NeoMemphisUniforms;
52
67
  readonly simianlights: SimianlightsUniforms;
53
68
  readonly 'anamorphic-lensflare': AnamorphicLensFlareUniforms;
69
+ readonly 'aurora-silk': AuroraSilkUniforms;
54
70
  readonly 'light-beams-and-motes': LightBeamsAndMotesUniforms;
55
71
  readonly 'corporate-blobs': CorporateBlobsUniforms;
56
72
  };
@@ -0,0 +1,35 @@
1
+ // Kaleidoscope's editor form: the shader OWNS its control layout (the plasma
2
+ // pattern). One <Control uniform="…"/> per uniform in declared order; layout
3
+ // or grouping changes are a local edit here. Conventional layer id:
4
+ // "kaleidoscope".
5
+
6
+ import {
7
+ Control,
8
+ ControlForm,
9
+ ControlSection,
10
+ type KaleidoscopeControls,
11
+ } from '../../../src/components/preset-control-panel';
12
+ import { KALEIDOSCOPE_CONTROLS } from './kaleidoscope';
13
+
14
+ export function KaleidoscopeForm({ uniforms, onPatch, disabled }: KaleidoscopeControls) {
15
+ return (
16
+ <ControlForm
17
+ id="kaleidoscope"
18
+ uniforms={uniforms.kaleidoscope ?? {}}
19
+ onPatch={onPatch}
20
+ disabled={disabled}
21
+ controls={KALEIDOSCOPE_CONTROLS}
22
+ >
23
+ <ControlSection title="kaleidoscope">
24
+ <Control uniform="uColorA" />
25
+ <Control uniform="uColorB" />
26
+ <Control uniform="uColorC" />
27
+ <Control uniform="uSegments" />
28
+ <Control uniform="uSpeed" />
29
+ <Control uniform="uRotate" />
30
+ <Control uniform="uZoom" />
31
+ <Control uniform="uCalm" />
32
+ </ControlSection>
33
+ </ControlForm>
34
+ );
35
+ }
@@ -0,0 +1,93 @@
1
+ // Kaleidoscope: the library's namesake. A mirrored polar fold (angle modulo
2
+ // 2pi/N) over a cheap drifting sine field; the fold makes any source field
3
+ // read as ornamental cut glass. An opaque BACKGROUND layer (issue #61).
4
+ //
5
+ // Overdrive surface: uSegments changes the whole character (6 = bold facets,
6
+ // 12 = lace), the three palette colors re-skin it completely, uRotate/uSpeed
7
+ // set the energy. uCalm eases contrast toward frame center, where the masked
8
+ // subject's face sits, so the pattern stays lively at the edges without
9
+ // flickering behind a speaker.
10
+ //
11
+ // UV convention: matches passthrough.vert. vUv = (0, 0) at bottom-left,
12
+ // (1, 1) at top-right. fragCoord is reconstructed as vUv * uResolution so this
13
+ // stays on the vUv convention and never reads gl_FragCoord (whose Y
14
+ // orientation flips between OpenGL and Metal). Fully procedural: no input
15
+ // texture, so there is no texture-origin handoff to flip. Net texture flips:
16
+ // zero on every runtime. The polar fold is rotation-symmetric, so even a
17
+ // hypothetical flip would be invisible here; the convention is kept anyway.
18
+ //
19
+ // Precision: highp float, matching the other procedural shaders (bounded
20
+ // sine sums, but vUv is highp by the passthrough.vert contract and the fold's
21
+ // atan/mod chain benefits from full mantissa at high segment counts).
22
+ //
23
+ // Cost class: plasma plus one atan and a mod; no loops, no noise, no hashing.
24
+
25
+ #version 300 es
26
+ precision highp float;
27
+
28
+ uniform float uTime; // seconds, monotonically increasing; range [0, inf)
29
+ uniform vec2 uResolution; // framebuffer size in pixels; both components > 0
30
+ uniform vec3 uColorA; // base palette color (also the calm midpoint pole)
31
+ uniform vec3 uColorB; // second palette color
32
+ uniform vec3 uColorC; // accent color, layered over the A/B field
33
+ uniform float uSegments; // mirror segment count; floor()ed, clamped >= 3
34
+ uniform float uSpeed; // source-field drift rate; 0 freezes the pattern
35
+ uniform float uRotate; // whole-field rotation rate; sign sets direction
36
+ uniform float uZoom; // pattern scale; higher = more rings of detail
37
+ uniform float uCalm; // 0..1 eases contrast at frame center (face zone)
38
+
39
+ in highp vec2 vUv;
40
+ out vec4 oColor;
41
+
42
+ const float TAU = 6.28318530718;
43
+
44
+ void main() {
45
+ // Aspect-correct, screen-centered coordinates (matches plasma/nebula).
46
+ vec2 fragCoord = vUv * uResolution;
47
+ vec2 uv = (fragCoord - 0.5 * uResolution) / uResolution.y;
48
+ float centerDist = length(uv);
49
+
50
+ // Whole-field rotation: the slow "turning the scope" motion.
51
+ float ra = uTime * uRotate;
52
+ float cs = cos(ra);
53
+ float sn = sin(ra);
54
+ uv = mat2(cs, -sn, sn, cs) * uv;
55
+
56
+ // Mirrored polar fold. The 1e-5 nudge keeps atan() off the undefined (0,0)
57
+ // input under Metal; it is far below one pixel at any resolution.
58
+ float r = centerDist * uZoom * (1.0 + 0.06 * sin(uTime * 0.23));
59
+ float seg = TAU / max(3.0, floor(uSegments));
60
+ float a = atan(uv.y, uv.x + 1e-5);
61
+ a = mod(a, seg);
62
+ a = abs(a - seg * 0.5);
63
+ vec2 p = r * vec2(cos(a), sin(a));
64
+
65
+ float t = uTime * uSpeed;
66
+
67
+ // Drifting source field, plasma-class: a few sines of folded position and
68
+ // time. The off-axis moving center in the length() term keeps the pattern
69
+ // evolving (non-repeating) rather than pulsing in place.
70
+ float f1 = sin(p.x * 6.0 + t)
71
+ + sin((p.x + p.y) * 4.2 - t * 0.7)
72
+ + sin(length(p - vec2(0.9 + 0.25 * sin(t * 0.31), 0.0)) * 7.0 + t * 1.1);
73
+ float f2 = sin(p.y * 5.0 - t * 0.9 + sin(p.x * 3.1 + t * 0.4));
74
+ float m1 = 0.5 + 0.5 * sin(f1);
75
+ float m2 = smoothstep(0.25, 0.9, 0.5 + 0.5 * sin(f2 + f1 * 0.5));
76
+
77
+ vec3 color = mix(uColorA, uColorB, m1);
78
+ color = mix(color, uColorC, m2 * 0.65);
79
+
80
+ // Thin darkening along both mirror lines sells the cut-glass facets.
81
+ float seam = smoothstep(0.035, 0.0, abs(a - seg * 0.5)) + smoothstep(0.035, 0.0, a);
82
+ color *= 1.0 - 0.18 * seam;
83
+
84
+ // uCalm: ease toward the palette midpoint near frame center. Spatial-only
85
+ // (never scales time per pixel, which would shear the field across the
86
+ // falloff ring).
87
+ vec3 mid = 0.5 * (uColorA + uColorB);
88
+ float calm = uCalm * (1.0 - smoothstep(0.15, 0.62, centerDist));
89
+ color = mix(color, mid, calm * 0.6);
90
+
91
+ // Opaque procedural background; the person is composited over it downstream.
92
+ oColor = vec4(color, 1.0);
93
+ }
@@ -0,0 +1,81 @@
1
+ // Kaleidoscope layer-shader interface: typed uniforms + control descriptor.
2
+ // The library's namesake: a mirrored polar fold over a drifting sine field, an
3
+ // opaque BACKGROUND layer (issue #61). One kaleidoscope.frag fans out into the
4
+ // book presets (stained-glass, mandala, prism) by varying these uniforms; the
5
+ // segment count and palette are the big levers. Shader source is
6
+ // shaders/kaleidoscope.frag.
7
+
8
+ import type { RGB } from '../../../src/lib/primitives.types';
9
+ import type { UniformControl } from '../_shared/types';
10
+
11
+ /** Typed uniforms for the `kaleidoscope` layer shader. */
12
+ export type KaleidoscopeShaderUniforms = {
13
+ /** Base palette color; also the pole uCalm eases toward. */
14
+ readonly uColorA: RGB;
15
+ /** Second palette color. */
16
+ readonly uColorB: RGB;
17
+ /** Accent color layered over the A/B field. */
18
+ readonly uColorC: RGB;
19
+ /** Mirror segment count; 6 = bold facets, 12 = lace. */
20
+ readonly uSegments: number;
21
+ /** Source-field drift rate; 0 freezes the pattern. */
22
+ readonly uSpeed: number;
23
+ /** Whole-field rotation rate; sign sets direction. */
24
+ readonly uRotate: number;
25
+ /** Pattern scale; higher = more rings of detail. */
26
+ readonly uZoom: number;
27
+ /** Eases contrast at frame center (the face zone); 0 = off. */
28
+ readonly uCalm: number;
29
+ };
30
+
31
+ /** The `kaleidoscope` shader's tunables; defaults are the "stained glass" look. */
32
+ export const KALEIDOSCOPE_CONTROLS: readonly UniformControl[] = [
33
+ { name: 'uColorA', kind: 'color', default: [0.07, 0.15, 0.36], doc: 'Base palette color.' },
34
+ { name: 'uColorB', kind: 'color', default: [0.1, 0.55, 0.62], doc: 'Second palette color.' },
35
+ { name: 'uColorC', kind: 'color', default: [0.93, 0.69, 0.21], doc: 'Accent color.' },
36
+ {
37
+ name: 'uSegments',
38
+ kind: 'float',
39
+ default: 8,
40
+ min: 3,
41
+ max: 16,
42
+ step: 1,
43
+ doc: 'Mirror segment count; 6 = bold facets, 12 = lace.',
44
+ },
45
+ {
46
+ name: 'uSpeed',
47
+ kind: 'float',
48
+ default: 0.35,
49
+ min: 0,
50
+ max: 2,
51
+ step: 0.01,
52
+ doc: 'Drift rate; 0 freezes.',
53
+ },
54
+ {
55
+ name: 'uRotate',
56
+ kind: 'float',
57
+ default: 0.04,
58
+ min: -0.5,
59
+ max: 0.5,
60
+ step: 0.005,
61
+ doc: 'Whole-field rotation rate; sign sets direction.',
62
+ },
63
+ {
64
+ name: 'uZoom',
65
+ kind: 'float',
66
+ default: 1.6,
67
+ min: 0.5,
68
+ max: 4,
69
+ step: 0.05,
70
+ doc: 'Pattern scale; higher = more rings of detail.',
71
+ },
72
+ {
73
+ name: 'uCalm',
74
+ kind: 'float',
75
+ default: 0,
76
+ min: 0,
77
+ max: 1,
78
+ step: 0.01,
79
+ doc: 'Eases contrast at frame center (face zone).',
80
+ },
81
+ ];
@@ -0,0 +1,35 @@
1
+ // Neo-Memphis's editor form: the shader OWNS its control layout (the plasma
2
+ // pattern). One <Control uniform="…"/> per uniform in declared order.
3
+ // Conventional layer id: "neo-memphis".
4
+
5
+ import {
6
+ Control,
7
+ ControlForm,
8
+ ControlSection,
9
+ type KaleidoscopeControls,
10
+ } from '../../../src/components/preset-control-panel';
11
+ import { NEO_MEMPHIS_CONTROLS } from './neo-memphis';
12
+
13
+ export function NeoMemphisForm({ uniforms, onPatch, disabled }: KaleidoscopeControls) {
14
+ return (
15
+ <ControlForm
16
+ id="neo-memphis"
17
+ uniforms={uniforms['neo-memphis'] ?? {}}
18
+ onPatch={onPatch}
19
+ disabled={disabled}
20
+ controls={NEO_MEMPHIS_CONTROLS}
21
+ >
22
+ <ControlSection title="neo-memphis">
23
+ <Control uniform="uBgColor" />
24
+ <Control uniform="uColorA" />
25
+ <Control uniform="uColorB" />
26
+ <Control uniform="uColorC" />
27
+ <Control uniform="uScale" />
28
+ <Control uniform="uDensity" />
29
+ <Control uniform="uOutline" />
30
+ <Control uniform="uDrift" />
31
+ <Control uniform="uCalm" />
32
+ </ControlSection>
33
+ </ControlForm>
34
+ );
35
+ }