react-shadertoy 0.3.0 → 0.6.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.
package/README.md CHANGED
@@ -3,10 +3,13 @@
3
3
  Run [Shadertoy](https://www.shadertoy.com/) GLSL shaders in React. Copy-paste and it works.
4
4
 
5
5
  - Zero dependencies (just React)
6
- - All Shadertoy uniforms supported (`iTime`, `iResolution`, `iMouse`, `iDate`, etc.)
6
+ - WebGL2 (GLSL ES 3.0) full Shadertoy compatibility
7
+ - All uniforms: `iTime`, `iResolution`, `iMouse`, `iDate`, `iFrame`, etc.
8
+ - iChannel0-3 textures (image URL, video, canvas, with wrap/filter/vflip)
9
+ - Multipass rendering (Buffer A-D with ping-pong FBO)
10
+ - Shadertoy API integration (`<Shadertoy id="MdX3zr" />`)
7
11
  - Mouse & touch interaction built-in
8
12
  - TypeScript-first
9
- - < 4KB gzipped
10
13
 
11
14
  ## Install
12
15
 
@@ -14,7 +17,7 @@ Run [Shadertoy](https://www.shadertoy.com/) GLSL shaders in React. Copy-paste an
14
17
  npm install react-shadertoy
15
18
  ```
16
19
 
17
- ## Usage
20
+ ## Quick Start
18
21
 
19
22
  ```tsx
20
23
  import { Shadertoy } from 'react-shadertoy'
@@ -36,13 +39,99 @@ function App() {
36
39
 
37
40
  Find a shader on [Shadertoy](https://www.shadertoy.com/), copy the GLSL code, paste it into `fragmentShader`. Done.
38
41
 
42
+ ## Textures
43
+
44
+ Pass image URLs, video elements, or canvas elements as textures:
45
+
46
+ ```tsx
47
+ <Shadertoy
48
+ fragmentShader={code}
49
+ textures={{
50
+ iChannel0: '/noise.png',
51
+ iChannel1: videoRef.current,
52
+ iChannel2: canvasRef.current,
53
+ }}
54
+ />
55
+ ```
56
+
57
+ ### Texture Options
58
+
59
+ Control wrap mode, filtering, and vertical flip:
60
+
61
+ ```tsx
62
+ <Shadertoy
63
+ fragmentShader={code}
64
+ textures={{
65
+ iChannel0: {
66
+ src: '/noise.png',
67
+ wrap: 'repeat', // 'clamp' | 'repeat' (default: 'clamp')
68
+ filter: 'mipmap', // 'nearest' | 'linear' | 'mipmap' (default: 'mipmap')
69
+ vflip: true, // vertical flip (default: true)
70
+ },
71
+ iChannel1: '/simple.png', // shorthand = default options
72
+ }}
73
+ />
74
+ ```
75
+
76
+ ## Multipass
77
+
78
+ Buffer A-D with self-referencing feedback loops:
79
+
80
+ ```tsx
81
+ <Shadertoy
82
+ passes={{
83
+ BufferA: {
84
+ code: bufferACode,
85
+ iChannel0: 'BufferA', // self-reference (previous frame)
86
+ iChannel1: '/noise.png', // external texture
87
+ },
88
+ BufferB: {
89
+ code: bufferBCode,
90
+ iChannel0: 'BufferA', // read Buffer A output
91
+ },
92
+ Image: {
93
+ code: imageCode,
94
+ iChannel0: 'BufferA',
95
+ iChannel1: 'BufferB',
96
+ },
97
+ }}
98
+ />
99
+ ```
100
+
101
+ ## Shadertoy API
102
+
103
+ Load shaders directly from Shadertoy by ID:
104
+
105
+ ```tsx
106
+ <Shadertoy
107
+ id="MdX3zr"
108
+ apiKey="your-api-key"
109
+ />
110
+ ```
111
+
112
+ Shows an author/name overlay by default. Disable with `showLicense={false}`.
113
+
114
+ API key from [shadertoy.com/myapps](https://www.shadertoy.com/myapps).
115
+
116
+ ### Build-Time Fetch
117
+
118
+ For production, fetch at build time to avoid runtime API calls:
119
+
120
+ ```ts
121
+ import { fetchShader, apiToConfig } from 'react-shadertoy'
122
+
123
+ const shader = await fetchShader('MdX3zr', process.env.SHADERTOY_API_KEY)
124
+ const config = apiToConfig(shader)
125
+ // Save config to JSON, use passes prop at runtime
126
+ ```
127
+
39
128
  ## Hooks API
40
129
 
41
130
  ```tsx
42
131
  import { useShadertoy } from 'react-shadertoy'
43
132
 
44
133
  function MyShader() {
45
- const { canvasRef, isReady, error, pause, resume } = useShadertoy({
134
+ const { canvasRef, isReady, error, pause, resume, meta } = useShadertoy({
46
135
  fragmentShader: `
47
136
  void mainImage(out vec4 fragColor, in vec2 fragCoord) {
48
137
  vec2 uv = fragCoord / iResolution.xy;
@@ -59,7 +148,12 @@ function MyShader() {
59
148
 
60
149
  | Prop | Type | Default | Description |
61
150
  |------|------|---------|-------------|
62
- | `fragmentShader` | `string` | required | Shadertoy GLSL code |
151
+ | `fragmentShader` | `string` | | Shadertoy GLSL code |
152
+ | `textures` | `TextureInputs` | — | iChannel0-3 texture sources |
153
+ | `passes` | `MultipassConfig` | — | Multipass Buffer A-D + Image |
154
+ | `id` | `string` | — | Shadertoy shader ID (API mode) |
155
+ | `apiKey` | `string` | — | Shadertoy API key |
156
+ | `showLicense` | `boolean` | `true` (API) | Show author overlay |
63
157
  | `style` | `CSSProperties` | — | Container style |
64
158
  | `className` | `string` | — | Container className |
65
159
  | `paused` | `boolean` | `false` | Pause rendering |
@@ -79,6 +173,8 @@ function MyShader() {
79
173
  | `iFrame` | `int` | Frame counter |
80
174
  | `iMouse` | `vec4` | Mouse position & click state |
81
175
  | `iDate` | `vec4` | Year, month, day, seconds |
176
+ | `iChannel0-3` | `sampler2D` | Texture inputs |
177
+ | `iChannelResolution` | `vec3[4]` | Texture dimensions |
82
178
 
83
179
  ## License
84
180
 
package/dist/index.d.mts CHANGED
@@ -3,18 +3,104 @@ import { CSSProperties, RefObject } from 'react';
3
3
 
4
4
  /** Texture source: URL string, or an HTML element for dynamic textures */
5
5
  type TextureSource = string | HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;
6
+ type TextureWrap = 'clamp' | 'repeat';
7
+ type TextureFilter = 'nearest' | 'linear' | 'mipmap';
8
+ /** Advanced texture options with wrap/filter/vflip control */
9
+ interface TextureOptions {
10
+ src: TextureSource;
11
+ wrap?: TextureWrap;
12
+ filter?: TextureFilter;
13
+ vflip?: boolean;
14
+ }
15
+ /** A texture input: shorthand source or full options object */
16
+ type TextureInput = TextureSource | TextureOptions;
6
17
  /** Texture inputs mapped to Shadertoy channels */
7
18
  type TextureInputs = {
8
- iChannel0?: TextureSource;
9
- iChannel1?: TextureSource;
10
- iChannel2?: TextureSource;
11
- iChannel3?: TextureSource;
19
+ iChannel0?: TextureInput;
20
+ iChannel1?: TextureInput;
21
+ iChannel2?: TextureInput;
22
+ iChannel3?: TextureInput;
23
+ };
24
+ type PassName = 'BufferA' | 'BufferB' | 'BufferC' | 'BufferD' | 'Image';
25
+ /** A channel input for a multipass pass: external texture or another pass name */
26
+ type PassInput = TextureInput | PassName;
27
+ /** Configuration for a single render pass */
28
+ interface PassConfig {
29
+ code: string;
30
+ iChannel0?: PassInput;
31
+ iChannel1?: PassInput;
32
+ iChannel2?: PassInput;
33
+ iChannel3?: PassInput;
34
+ }
35
+ /** Multipass configuration: Buffer A-D + Image */
36
+ type MultipassConfig = {
37
+ [K in PassName]?: PassConfig;
12
38
  };
39
+ interface ShadertoyApiSampler {
40
+ filter: string;
41
+ wrap: string;
42
+ vflip: string;
43
+ srgb: string;
44
+ internal: string;
45
+ }
46
+ interface ShadertoyApiInput {
47
+ id: number;
48
+ src: string;
49
+ ctype: string;
50
+ channel: number;
51
+ sampler: ShadertoyApiSampler;
52
+ published: number;
53
+ }
54
+ interface ShadertoyApiOutput {
55
+ id: number;
56
+ channel: number;
57
+ }
58
+ interface ShadertoyApiRenderPass {
59
+ inputs: ShadertoyApiInput[];
60
+ outputs: ShadertoyApiOutput[];
61
+ code: string;
62
+ name: string;
63
+ description: string;
64
+ type: string;
65
+ }
66
+ interface ShadertoyApiInfo {
67
+ id: string;
68
+ date: string;
69
+ viewed: number;
70
+ name: string;
71
+ username: string;
72
+ description: string;
73
+ likes: number;
74
+ published: number;
75
+ flags: number;
76
+ tags: string[];
77
+ hasliked: number;
78
+ }
79
+ interface ShadertoyApiShader {
80
+ ver: string;
81
+ info: ShadertoyApiInfo;
82
+ renderpass: ShadertoyApiRenderPass[];
83
+ }
84
+ interface ShaderMeta {
85
+ name: string;
86
+ author: string;
87
+ description: string;
88
+ tags: string[];
89
+ license?: string;
90
+ }
13
91
  interface ShadertoyProps {
14
92
  /** Shadertoy-compatible GLSL fragment shader (must contain mainImage) */
15
- fragmentShader: string;
16
- /** Texture inputs for iChannel0-3 */
93
+ fragmentShader?: string;
94
+ /** Multipass configuration (Buffer A-D + Image) */
95
+ passes?: MultipassConfig;
96
+ /** Texture inputs for iChannel0-3 (single-pass mode) */
17
97
  textures?: TextureInputs;
98
+ /** Shadertoy shader ID — fetches shader from API */
99
+ id?: string;
100
+ /** Shadertoy API key (required when using id) */
101
+ apiKey?: string;
102
+ /** Show license/author overlay (default: true when using id) */
103
+ showLicense?: boolean;
18
104
  /** Container style */
19
105
  style?: CSSProperties;
20
106
  /** Container className */
@@ -33,8 +119,11 @@ interface ShadertoyProps {
33
119
  onLoad?: () => void;
34
120
  }
35
121
  interface UseShadertoyOptions {
36
- fragmentShader: string;
122
+ fragmentShader?: string;
123
+ passes?: MultipassConfig;
37
124
  textures?: TextureInputs;
125
+ id?: string;
126
+ apiKey?: string;
38
127
  paused?: boolean;
39
128
  speed?: number;
40
129
  pixelRatio?: number;
@@ -48,10 +137,26 @@ interface UseShadertoyReturn {
48
137
  error: string | null;
49
138
  pause: () => void;
50
139
  resume: () => void;
140
+ meta: ShaderMeta | null;
51
141
  }
52
142
 
53
- declare function Shadertoy({ fragmentShader, textures, style, className, paused, speed, pixelRatio, mouse, onError, onLoad, }: ShadertoyProps): react_jsx_runtime.JSX.Element;
143
+ declare function Shadertoy({ fragmentShader, passes, textures, id, apiKey, showLicense, style, className, paused, speed, pixelRatio, mouse, onError, onLoad, }: ShadertoyProps): react_jsx_runtime.JSX.Element;
54
144
 
55
- declare function useShadertoy({ fragmentShader, textures: texturesProp, paused, speed, pixelRatio, mouse: mouseEnabled, onError, onLoad, }: UseShadertoyOptions): UseShadertoyReturn;
145
+ declare function useShadertoy({ fragmentShader, passes: passesProp, textures: texturesProp, id, apiKey, paused, speed, pixelRatio, mouse: mouseEnabled, onError, onLoad, }: UseShadertoyOptions): UseShadertoyReturn & {
146
+ meta: ShaderMeta | null;
147
+ };
148
+
149
+ /**
150
+ * Fetch a shader from the Shadertoy API.
151
+ */
152
+ declare function fetchShader(id: string, apiKey: string): Promise<ShadertoyApiShader>;
153
+ /**
154
+ * Convert a Shadertoy API shader to our MultipassConfig + TextureInputs + meta.
155
+ */
156
+ declare function apiToConfig(shader: ShadertoyApiShader): {
157
+ passes: MultipassConfig;
158
+ textures: TextureInputs;
159
+ meta: ShaderMeta;
160
+ };
56
161
 
57
- export { Shadertoy, type ShadertoyProps, type TextureInputs, type UseShadertoyOptions, type UseShadertoyReturn, useShadertoy };
162
+ export { type MultipassConfig, type PassConfig, type PassName, type ShaderMeta, Shadertoy, type ShadertoyApiShader, type ShadertoyProps, type TextureFilter, type TextureInput, type TextureInputs, type TextureOptions, type TextureWrap, type UseShadertoyOptions, type UseShadertoyReturn, apiToConfig, fetchShader, useShadertoy };
package/dist/index.d.ts CHANGED
@@ -3,18 +3,104 @@ import { CSSProperties, RefObject } from 'react';
3
3
 
4
4
  /** Texture source: URL string, or an HTML element for dynamic textures */
5
5
  type TextureSource = string | HTMLImageElement | HTMLVideoElement | HTMLCanvasElement;
6
+ type TextureWrap = 'clamp' | 'repeat';
7
+ type TextureFilter = 'nearest' | 'linear' | 'mipmap';
8
+ /** Advanced texture options with wrap/filter/vflip control */
9
+ interface TextureOptions {
10
+ src: TextureSource;
11
+ wrap?: TextureWrap;
12
+ filter?: TextureFilter;
13
+ vflip?: boolean;
14
+ }
15
+ /** A texture input: shorthand source or full options object */
16
+ type TextureInput = TextureSource | TextureOptions;
6
17
  /** Texture inputs mapped to Shadertoy channels */
7
18
  type TextureInputs = {
8
- iChannel0?: TextureSource;
9
- iChannel1?: TextureSource;
10
- iChannel2?: TextureSource;
11
- iChannel3?: TextureSource;
19
+ iChannel0?: TextureInput;
20
+ iChannel1?: TextureInput;
21
+ iChannel2?: TextureInput;
22
+ iChannel3?: TextureInput;
23
+ };
24
+ type PassName = 'BufferA' | 'BufferB' | 'BufferC' | 'BufferD' | 'Image';
25
+ /** A channel input for a multipass pass: external texture or another pass name */
26
+ type PassInput = TextureInput | PassName;
27
+ /** Configuration for a single render pass */
28
+ interface PassConfig {
29
+ code: string;
30
+ iChannel0?: PassInput;
31
+ iChannel1?: PassInput;
32
+ iChannel2?: PassInput;
33
+ iChannel3?: PassInput;
34
+ }
35
+ /** Multipass configuration: Buffer A-D + Image */
36
+ type MultipassConfig = {
37
+ [K in PassName]?: PassConfig;
12
38
  };
39
+ interface ShadertoyApiSampler {
40
+ filter: string;
41
+ wrap: string;
42
+ vflip: string;
43
+ srgb: string;
44
+ internal: string;
45
+ }
46
+ interface ShadertoyApiInput {
47
+ id: number;
48
+ src: string;
49
+ ctype: string;
50
+ channel: number;
51
+ sampler: ShadertoyApiSampler;
52
+ published: number;
53
+ }
54
+ interface ShadertoyApiOutput {
55
+ id: number;
56
+ channel: number;
57
+ }
58
+ interface ShadertoyApiRenderPass {
59
+ inputs: ShadertoyApiInput[];
60
+ outputs: ShadertoyApiOutput[];
61
+ code: string;
62
+ name: string;
63
+ description: string;
64
+ type: string;
65
+ }
66
+ interface ShadertoyApiInfo {
67
+ id: string;
68
+ date: string;
69
+ viewed: number;
70
+ name: string;
71
+ username: string;
72
+ description: string;
73
+ likes: number;
74
+ published: number;
75
+ flags: number;
76
+ tags: string[];
77
+ hasliked: number;
78
+ }
79
+ interface ShadertoyApiShader {
80
+ ver: string;
81
+ info: ShadertoyApiInfo;
82
+ renderpass: ShadertoyApiRenderPass[];
83
+ }
84
+ interface ShaderMeta {
85
+ name: string;
86
+ author: string;
87
+ description: string;
88
+ tags: string[];
89
+ license?: string;
90
+ }
13
91
  interface ShadertoyProps {
14
92
  /** Shadertoy-compatible GLSL fragment shader (must contain mainImage) */
15
- fragmentShader: string;
16
- /** Texture inputs for iChannel0-3 */
93
+ fragmentShader?: string;
94
+ /** Multipass configuration (Buffer A-D + Image) */
95
+ passes?: MultipassConfig;
96
+ /** Texture inputs for iChannel0-3 (single-pass mode) */
17
97
  textures?: TextureInputs;
98
+ /** Shadertoy shader ID — fetches shader from API */
99
+ id?: string;
100
+ /** Shadertoy API key (required when using id) */
101
+ apiKey?: string;
102
+ /** Show license/author overlay (default: true when using id) */
103
+ showLicense?: boolean;
18
104
  /** Container style */
19
105
  style?: CSSProperties;
20
106
  /** Container className */
@@ -33,8 +119,11 @@ interface ShadertoyProps {
33
119
  onLoad?: () => void;
34
120
  }
35
121
  interface UseShadertoyOptions {
36
- fragmentShader: string;
122
+ fragmentShader?: string;
123
+ passes?: MultipassConfig;
37
124
  textures?: TextureInputs;
125
+ id?: string;
126
+ apiKey?: string;
38
127
  paused?: boolean;
39
128
  speed?: number;
40
129
  pixelRatio?: number;
@@ -48,10 +137,26 @@ interface UseShadertoyReturn {
48
137
  error: string | null;
49
138
  pause: () => void;
50
139
  resume: () => void;
140
+ meta: ShaderMeta | null;
51
141
  }
52
142
 
53
- declare function Shadertoy({ fragmentShader, textures, style, className, paused, speed, pixelRatio, mouse, onError, onLoad, }: ShadertoyProps): react_jsx_runtime.JSX.Element;
143
+ declare function Shadertoy({ fragmentShader, passes, textures, id, apiKey, showLicense, style, className, paused, speed, pixelRatio, mouse, onError, onLoad, }: ShadertoyProps): react_jsx_runtime.JSX.Element;
54
144
 
55
- declare function useShadertoy({ fragmentShader, textures: texturesProp, paused, speed, pixelRatio, mouse: mouseEnabled, onError, onLoad, }: UseShadertoyOptions): UseShadertoyReturn;
145
+ declare function useShadertoy({ fragmentShader, passes: passesProp, textures: texturesProp, id, apiKey, paused, speed, pixelRatio, mouse: mouseEnabled, onError, onLoad, }: UseShadertoyOptions): UseShadertoyReturn & {
146
+ meta: ShaderMeta | null;
147
+ };
148
+
149
+ /**
150
+ * Fetch a shader from the Shadertoy API.
151
+ */
152
+ declare function fetchShader(id: string, apiKey: string): Promise<ShadertoyApiShader>;
153
+ /**
154
+ * Convert a Shadertoy API shader to our MultipassConfig + TextureInputs + meta.
155
+ */
156
+ declare function apiToConfig(shader: ShadertoyApiShader): {
157
+ passes: MultipassConfig;
158
+ textures: TextureInputs;
159
+ meta: ShaderMeta;
160
+ };
56
161
 
57
- export { Shadertoy, type ShadertoyProps, type TextureInputs, type UseShadertoyOptions, type UseShadertoyReturn, useShadertoy };
162
+ export { type MultipassConfig, type PassConfig, type PassName, type ShaderMeta, Shadertoy, type ShadertoyApiShader, type ShadertoyProps, type TextureFilter, type TextureInput, type TextureInputs, type TextureOptions, type TextureWrap, type UseShadertoyOptions, type UseShadertoyReturn, apiToConfig, fetchShader, useShadertoy };