@stevejtrettel/shader-sandbox 0.1.2 → 0.1.4
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 +259 -235
- package/bin/cli.js +106 -14
- package/dist-lib/app/App.d.ts +143 -15
- package/dist-lib/app/App.d.ts.map +1 -1
- package/dist-lib/app/App.js +1343 -108
- package/dist-lib/app/app.css +349 -24
- package/dist-lib/app/types.d.ts +48 -5
- package/dist-lib/app/types.d.ts.map +1 -1
- package/dist-lib/editor/EditorPanel.d.ts +2 -2
- package/dist-lib/editor/EditorPanel.d.ts.map +1 -1
- package/dist-lib/editor/EditorPanel.js +1 -1
- package/dist-lib/editor/editor-panel.css +55 -32
- package/dist-lib/editor/prism-editor.css +16 -16
- package/dist-lib/embed.js +1 -1
- package/dist-lib/engine/{ShadertoyEngine.d.ts → ShaderEngine.d.ts} +134 -10
- package/dist-lib/engine/ShaderEngine.d.ts.map +1 -0
- package/dist-lib/engine/ShaderEngine.js +1523 -0
- package/dist-lib/engine/glHelpers.d.ts +24 -0
- package/dist-lib/engine/glHelpers.d.ts.map +1 -1
- package/dist-lib/engine/glHelpers.js +88 -0
- package/dist-lib/engine/std140.d.ts +47 -0
- package/dist-lib/engine/std140.d.ts.map +1 -0
- package/dist-lib/engine/std140.js +119 -0
- package/dist-lib/engine/types.d.ts +55 -5
- package/dist-lib/engine/types.d.ts.map +1 -1
- package/dist-lib/engine/types.js +1 -1
- package/dist-lib/index.d.ts +4 -3
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +2 -1
- package/dist-lib/layouts/SplitLayout.d.ts +2 -1
- package/dist-lib/layouts/SplitLayout.d.ts.map +1 -1
- package/dist-lib/layouts/SplitLayout.js +3 -0
- package/dist-lib/layouts/TabbedLayout.d.ts.map +1 -1
- package/dist-lib/layouts/UILayout.d.ts +55 -0
- package/dist-lib/layouts/UILayout.d.ts.map +1 -0
- package/dist-lib/layouts/UILayout.js +147 -0
- package/dist-lib/layouts/default.css +2 -2
- package/dist-lib/layouts/index.d.ts +11 -1
- package/dist-lib/layouts/index.d.ts.map +1 -1
- package/dist-lib/layouts/index.js +17 -1
- package/dist-lib/layouts/split.css +33 -31
- package/dist-lib/layouts/tabbed.css +127 -74
- package/dist-lib/layouts/types.d.ts +14 -3
- package/dist-lib/layouts/types.d.ts.map +1 -1
- package/dist-lib/main.js +33 -0
- package/dist-lib/project/configHelpers.d.ts +45 -0
- package/dist-lib/project/configHelpers.d.ts.map +1 -0
- package/dist-lib/project/configHelpers.js +196 -0
- package/dist-lib/project/generatedLoader.d.ts +2 -2
- package/dist-lib/project/generatedLoader.d.ts.map +1 -1
- package/dist-lib/project/generatedLoader.js +23 -5
- package/dist-lib/project/loadProject.d.ts +6 -6
- package/dist-lib/project/loadProject.d.ts.map +1 -1
- package/dist-lib/project/loadProject.js +396 -144
- package/dist-lib/project/loaderHelper.d.ts +4 -4
- package/dist-lib/project/loaderHelper.d.ts.map +1 -1
- package/dist-lib/project/loaderHelper.js +278 -116
- package/dist-lib/project/types.d.ts +292 -13
- package/dist-lib/project/types.d.ts.map +1 -1
- package/dist-lib/project/types.js +13 -1
- package/dist-lib/styles/base.css +5 -1
- package/dist-lib/uniforms/UniformControls.d.ts +60 -0
- package/dist-lib/uniforms/UniformControls.d.ts.map +1 -0
- package/dist-lib/uniforms/UniformControls.js +518 -0
- package/dist-lib/uniforms/UniformStore.d.ts +74 -0
- package/dist-lib/uniforms/UniformStore.d.ts.map +1 -0
- package/dist-lib/uniforms/UniformStore.js +145 -0
- package/dist-lib/uniforms/UniformsPanel.d.ts +53 -0
- package/dist-lib/uniforms/UniformsPanel.d.ts.map +1 -0
- package/dist-lib/uniforms/UniformsPanel.js +124 -0
- package/dist-lib/uniforms/index.d.ts +11 -0
- package/dist-lib/uniforms/index.d.ts.map +1 -0
- package/dist-lib/uniforms/index.js +8 -0
- package/package.json +16 -1
- package/src/app/App.ts +1469 -126
- package/src/app/app.css +349 -24
- package/src/app/types.ts +53 -5
- package/src/editor/EditorPanel.ts +5 -5
- package/src/editor/editor-panel.css +55 -32
- package/src/editor/prism-editor.css +16 -16
- package/src/embed.ts +1 -1
- package/src/engine/ShaderEngine.ts +1934 -0
- package/src/engine/glHelpers.ts +117 -0
- package/src/engine/std140.ts +136 -0
- package/src/engine/types.ts +69 -5
- package/src/index.ts +4 -3
- package/src/layouts/SplitLayout.ts +8 -3
- package/src/layouts/TabbedLayout.ts +3 -3
- package/src/layouts/UILayout.ts +185 -0
- package/src/layouts/default.css +2 -2
- package/src/layouts/index.ts +20 -1
- package/src/layouts/split.css +33 -31
- package/src/layouts/tabbed.css +127 -74
- package/src/layouts/types.ts +19 -3
- package/src/layouts/ui.css +289 -0
- package/src/main.ts +39 -1
- package/src/project/configHelpers.ts +225 -0
- package/src/project/generatedLoader.ts +27 -6
- package/src/project/loadProject.ts +459 -173
- package/src/project/loaderHelper.ts +377 -130
- package/src/project/types.ts +360 -14
- package/src/styles/base.css +5 -1
- package/src/styles/theme.css +292 -0
- package/src/uniforms/UniformControls.ts +660 -0
- package/src/uniforms/UniformStore.ts +166 -0
- package/src/uniforms/UniformsPanel.ts +163 -0
- package/src/uniforms/index.ts +13 -0
- package/src/uniforms/uniform-controls.css +342 -0
- package/src/uniforms/uniforms-panel.css +277 -0
- package/templates/shaders/example-buffer/config.json +1 -0
- package/dist-lib/engine/ShadertoyEngine.d.ts.map +0 -1
- package/dist-lib/engine/ShadertoyEngine.js +0 -704
- package/src/engine/ShadertoyEngine.ts +0 -929
package/src/project/types.ts
CHANGED
|
@@ -11,6 +11,165 @@
|
|
|
11
11
|
|
|
12
12
|
export type PassName = 'Image' | 'BufferA' | 'BufferB' | 'BufferC' | 'BufferD';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Theme mode for the shader viewer.
|
|
16
|
+
* - 'light': Always use light theme
|
|
17
|
+
* - 'dark': Always use dark theme
|
|
18
|
+
* - 'system': Follow OS preference (prefers-color-scheme)
|
|
19
|
+
*/
|
|
20
|
+
export type ThemeMode = 'light' | 'dark' | 'system';
|
|
21
|
+
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// Custom Uniform Definitions
|
|
24
|
+
// =============================================================================
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Supported uniform types for user-defined controls.
|
|
28
|
+
* For now, we start with float only. More types will be added later.
|
|
29
|
+
*/
|
|
30
|
+
export type UniformType = 'float' | 'int' | 'bool' | 'vec2' | 'vec3' | 'vec4';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Base uniform definition shared by all types.
|
|
34
|
+
*/
|
|
35
|
+
interface UniformDefinitionBase {
|
|
36
|
+
/** Display label (defaults to uniform name if not provided) */
|
|
37
|
+
label?: string;
|
|
38
|
+
/** If true, uniform is declared but has no UI control (for script-only uniforms) */
|
|
39
|
+
hidden?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Float uniform with slider control.
|
|
44
|
+
*/
|
|
45
|
+
export interface FloatUniformDefinition extends UniformDefinitionBase {
|
|
46
|
+
type: 'float';
|
|
47
|
+
value: number;
|
|
48
|
+
min?: number; // Default: 0
|
|
49
|
+
max?: number; // Default: 1
|
|
50
|
+
step?: number; // Default: 0.01
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Integer uniform with discrete slider.
|
|
55
|
+
*/
|
|
56
|
+
export interface IntUniformDefinition extends UniformDefinitionBase {
|
|
57
|
+
type: 'int';
|
|
58
|
+
value: number;
|
|
59
|
+
min?: number; // Default: 0
|
|
60
|
+
max?: number; // Default: 10
|
|
61
|
+
step?: number; // Default: 1
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Boolean uniform with toggle control.
|
|
66
|
+
*/
|
|
67
|
+
export interface BoolUniformDefinition extends UniformDefinitionBase {
|
|
68
|
+
type: 'bool';
|
|
69
|
+
value: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Vec2 uniform (2D position picker).
|
|
74
|
+
*/
|
|
75
|
+
export interface Vec2UniformDefinition extends UniformDefinitionBase {
|
|
76
|
+
type: 'vec2';
|
|
77
|
+
value: [number, number];
|
|
78
|
+
min?: [number, number]; // Default: [0, 0]
|
|
79
|
+
max?: [number, number]; // Default: [1, 1]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Vec3 uniform (color picker or 3D value).
|
|
84
|
+
*/
|
|
85
|
+
export interface Vec3UniformDefinition extends UniformDefinitionBase {
|
|
86
|
+
type: 'vec3';
|
|
87
|
+
value: [number, number, number];
|
|
88
|
+
/** If true, use color picker UI. Otherwise use 3 sliders. */
|
|
89
|
+
color?: boolean;
|
|
90
|
+
/** Per-component min (default: [0, 0, 0]) */
|
|
91
|
+
min?: [number, number, number];
|
|
92
|
+
/** Per-component max (default: [1, 1, 1]) */
|
|
93
|
+
max?: [number, number, number];
|
|
94
|
+
/** Per-component step (default: [0.01, 0.01, 0.01]) */
|
|
95
|
+
step?: [number, number, number];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Vec4 uniform (color with alpha or 4D value).
|
|
100
|
+
*/
|
|
101
|
+
export interface Vec4UniformDefinition extends UniformDefinitionBase {
|
|
102
|
+
type: 'vec4';
|
|
103
|
+
value: [number, number, number, number];
|
|
104
|
+
/** If true, use color picker with alpha. Otherwise use 4 sliders. */
|
|
105
|
+
color?: boolean;
|
|
106
|
+
/** Per-component min (default: [0, 0, 0, 0]) */
|
|
107
|
+
min?: [number, number, number, number];
|
|
108
|
+
/** Per-component max (default: [1, 1, 1, 1]) */
|
|
109
|
+
max?: [number, number, number, number];
|
|
110
|
+
/** Per-component step (default: [0.01, 0.01, 0.01, 0.01]) */
|
|
111
|
+
step?: [number, number, number, number];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Array uniform types supported in UBOs.
|
|
116
|
+
*/
|
|
117
|
+
export type ArrayUniformType = 'float' | 'vec2' | 'vec3' | 'vec4' | 'mat3' | 'mat4';
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Array uniform backed by a Uniform Buffer Object (UBO).
|
|
121
|
+
* Data is provided from JavaScript via setUniformValue().
|
|
122
|
+
* The engine auto-injects the layout(std140) uniform block into the shader.
|
|
123
|
+
*/
|
|
124
|
+
export interface ArrayUniformDefinition extends UniformDefinitionBase {
|
|
125
|
+
type: ArrayUniformType;
|
|
126
|
+
/** Number of elements in the array */
|
|
127
|
+
count: number;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Type guard: returns true if a uniform definition is an array uniform (has count).
|
|
132
|
+
*/
|
|
133
|
+
export function isArrayUniform(def: UniformDefinition): def is ArrayUniformDefinition {
|
|
134
|
+
return 'count' in def && typeof (def as any).count === 'number';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Returns true if a uniform should have a UI control.
|
|
139
|
+
* Excludes array uniforms (UBOs) and hidden uniforms (script-only).
|
|
140
|
+
*/
|
|
141
|
+
export function hasUIControl(def: UniformDefinition): boolean {
|
|
142
|
+
return !isArrayUniform(def) && !def.hidden;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Union of all uniform definition types.
|
|
147
|
+
*/
|
|
148
|
+
export type UniformDefinition =
|
|
149
|
+
| FloatUniformDefinition
|
|
150
|
+
| IntUniformDefinition
|
|
151
|
+
| BoolUniformDefinition
|
|
152
|
+
| Vec2UniformDefinition
|
|
153
|
+
| Vec3UniformDefinition
|
|
154
|
+
| Vec4UniformDefinition
|
|
155
|
+
| ArrayUniformDefinition;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Map of uniform names to their definitions.
|
|
159
|
+
*/
|
|
160
|
+
export type UniformDefinitions = Record<string, UniformDefinition>;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A single uniform value at runtime.
|
|
164
|
+
*/
|
|
165
|
+
export type UniformValue = number | boolean | number[] | Float32Array;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Runtime uniform values (current state).
|
|
169
|
+
* Keys are uniform names, values are the current value.
|
|
170
|
+
*/
|
|
171
|
+
export type UniformValues = Record<string, UniformValue>;
|
|
172
|
+
|
|
14
173
|
// =============================================================================
|
|
15
174
|
// Channel Definitions (JSON Config Format)
|
|
16
175
|
// =============================================================================
|
|
@@ -42,22 +201,60 @@ export interface ChannelJSONKeyboard {
|
|
|
42
201
|
keyboard: true;
|
|
43
202
|
}
|
|
44
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Reference to audio input (microphone).
|
|
206
|
+
* Provides a 512x2 texture: row 0 = FFT spectrum, row 1 = waveform.
|
|
207
|
+
*/
|
|
208
|
+
export interface ChannelJSONAudio {
|
|
209
|
+
audio: true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Reference to webcam input.
|
|
214
|
+
*/
|
|
215
|
+
export interface ChannelJSONWebcam {
|
|
216
|
+
webcam: true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Reference to a video file.
|
|
221
|
+
*/
|
|
222
|
+
export interface ChannelJSONVideo {
|
|
223
|
+
video: string; // Path to video file
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Reference to a script-uploaded texture.
|
|
228
|
+
* The texture is created/updated at runtime via engine.updateTexture().
|
|
229
|
+
*/
|
|
230
|
+
export interface ChannelJSONScript {
|
|
231
|
+
script: string; // Texture name (matched by script's updateTexture calls)
|
|
232
|
+
}
|
|
233
|
+
|
|
45
234
|
/**
|
|
46
235
|
* Union type for channel sources in JSON config (object form).
|
|
47
236
|
*/
|
|
48
237
|
export type ChannelJSONObject =
|
|
49
238
|
| ChannelJSONBuffer
|
|
50
239
|
| ChannelJSONTexture
|
|
51
|
-
| ChannelJSONKeyboard
|
|
240
|
+
| ChannelJSONKeyboard
|
|
241
|
+
| ChannelJSONAudio
|
|
242
|
+
| ChannelJSONWebcam
|
|
243
|
+
| ChannelJSONVideo
|
|
244
|
+
| ChannelJSONScript;
|
|
52
245
|
|
|
53
246
|
/**
|
|
54
247
|
* Channel value in simplified config format.
|
|
55
248
|
* Can be a string shorthand or full object:
|
|
56
249
|
* - "BufferA", "BufferB", etc. → buffer reference
|
|
57
250
|
* - "keyboard" → keyboard input
|
|
251
|
+
* - "audio" → microphone audio input
|
|
252
|
+
* - "webcam" → webcam video input
|
|
58
253
|
* - "photo.jpg" (with extension) → texture file
|
|
59
254
|
* - { buffer: "BufferA" } → explicit buffer with options
|
|
60
255
|
* - { texture: "photo.jpg", filter: "nearest" } → texture with options
|
|
256
|
+
* - { video: "clip.mp4" } → video file
|
|
257
|
+
* - { script: "myData" } → script-uploaded texture
|
|
61
258
|
*/
|
|
62
259
|
export type ChannelValue = string | ChannelJSONObject;
|
|
63
260
|
|
|
@@ -104,6 +301,9 @@ export interface PassConfigSimplified {
|
|
|
104
301
|
* }
|
|
105
302
|
*/
|
|
106
303
|
export interface ShadertoyConfig {
|
|
304
|
+
/** Must be 'shadertoy' to use Shadertoy-compatible iChannel mode. */
|
|
305
|
+
mode: 'shadertoy';
|
|
306
|
+
|
|
107
307
|
// Metadata (flat, not nested)
|
|
108
308
|
title?: string;
|
|
109
309
|
author?: string;
|
|
@@ -111,9 +311,18 @@ export interface ShadertoyConfig {
|
|
|
111
311
|
|
|
112
312
|
// Settings
|
|
113
313
|
layout?: 'fullscreen' | 'default' | 'split' | 'tabbed';
|
|
314
|
+
theme?: ThemeMode;
|
|
114
315
|
controls?: boolean;
|
|
115
316
|
common?: string;
|
|
116
317
|
|
|
318
|
+
// Playback settings
|
|
319
|
+
/** Start paused on first frame (default: false) */
|
|
320
|
+
startPaused?: boolean;
|
|
321
|
+
|
|
322
|
+
// Resolution settings
|
|
323
|
+
/** Pixel ratio multiplier (default: window.devicePixelRatio). Use <1 for lower resolution. */
|
|
324
|
+
pixelRatio?: number;
|
|
325
|
+
|
|
117
326
|
// Passes (at top level)
|
|
118
327
|
Image?: PassConfigSimplified;
|
|
119
328
|
BufferA?: PassConfigSimplified;
|
|
@@ -122,6 +331,69 @@ export interface ShadertoyConfig {
|
|
|
122
331
|
BufferD?: PassConfigSimplified;
|
|
123
332
|
}
|
|
124
333
|
|
|
334
|
+
// =============================================================================
|
|
335
|
+
// Standard Mode Config (Named Buffers & Textures)
|
|
336
|
+
// =============================================================================
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Per-buffer configuration in standard mode.
|
|
340
|
+
*/
|
|
341
|
+
export interface StandardBufferConfig {
|
|
342
|
+
filter?: 'nearest' | 'linear';
|
|
343
|
+
wrap?: 'clamp' | 'repeat';
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Standard mode config format.
|
|
348
|
+
* Buffers and textures are available everywhere by name.
|
|
349
|
+
* Also supports pass-level configs (Image, BufferA, etc.) for simple cases
|
|
350
|
+
* where named buffers aren't needed.
|
|
351
|
+
*/
|
|
352
|
+
export interface StandardConfig {
|
|
353
|
+
mode?: 'standard';
|
|
354
|
+
|
|
355
|
+
// Metadata
|
|
356
|
+
title?: string;
|
|
357
|
+
author?: string;
|
|
358
|
+
description?: string;
|
|
359
|
+
|
|
360
|
+
// Settings
|
|
361
|
+
layout?: 'fullscreen' | 'default' | 'split' | 'tabbed';
|
|
362
|
+
theme?: ThemeMode;
|
|
363
|
+
controls?: boolean;
|
|
364
|
+
common?: string;
|
|
365
|
+
startPaused?: boolean;
|
|
366
|
+
pixelRatio?: number;
|
|
367
|
+
|
|
368
|
+
// Custom uniforms
|
|
369
|
+
uniforms?: UniformDefinitions;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Named buffers (framebuffers with ping-pong).
|
|
373
|
+
* Array shorthand ["velocity"] normalizes to { "velocity": {} }.
|
|
374
|
+
* Max 4 buffers (maps to BufferA-D internally).
|
|
375
|
+
*/
|
|
376
|
+
buffers?: string[] | Record<string, StandardBufferConfig>;
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Named textures available in all passes.
|
|
380
|
+
* Value is a file path or special source: "keyboard", "audio", "webcam".
|
|
381
|
+
*/
|
|
382
|
+
textures?: Record<string, string>;
|
|
383
|
+
|
|
384
|
+
// Pass-level configs (for standard mode without named buffers)
|
|
385
|
+
Image?: PassConfigSimplified;
|
|
386
|
+
BufferA?: PassConfigSimplified;
|
|
387
|
+
BufferB?: PassConfigSimplified;
|
|
388
|
+
BufferC?: PassConfigSimplified;
|
|
389
|
+
BufferD?: PassConfigSimplified;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Union of all config formats that can appear in config.json.
|
|
394
|
+
*/
|
|
395
|
+
export type ProjectConfig = ShadertoyConfig | StandardConfig;
|
|
396
|
+
|
|
125
397
|
// =============================================================================
|
|
126
398
|
// Internal Channel Representation (Normalized)
|
|
127
399
|
// =============================================================================
|
|
@@ -134,7 +406,11 @@ export type ChannelSource =
|
|
|
134
406
|
| { kind: 'none' }
|
|
135
407
|
| { kind: 'buffer'; buffer: PassName; current: boolean }
|
|
136
408
|
| { kind: 'texture'; name: string; cubemap: boolean } // Internal texture ID (e.g., "tex0")
|
|
137
|
-
| { kind: 'keyboard' }
|
|
409
|
+
| { kind: 'keyboard' }
|
|
410
|
+
| { kind: 'audio' }
|
|
411
|
+
| { kind: 'webcam' }
|
|
412
|
+
| { kind: 'video'; src: string }
|
|
413
|
+
| { kind: 'script'; name: string };
|
|
138
414
|
|
|
139
415
|
/**
|
|
140
416
|
* Exactly 4 channels (iChannel0-3), matching Shadertoy's fixed channel count.
|
|
@@ -149,7 +425,7 @@ export type Channels = [ChannelSource, ChannelSource, ChannelSource, ChannelSour
|
|
|
149
425
|
* External 2D texture loaded from image file.
|
|
150
426
|
* Textures are deduplicated by (source, filter, wrap) tuple.
|
|
151
427
|
*/
|
|
152
|
-
export interface
|
|
428
|
+
export interface ShaderTexture2D {
|
|
153
429
|
name: string; // Internal ID (e.g., "tex0", "tex1")
|
|
154
430
|
filename?: string; // Original filename for display (e.g., "texture.png")
|
|
155
431
|
source: string; // Path/URL to image file
|
|
@@ -164,10 +440,12 @@ export interface ShadertoyTexture2D {
|
|
|
164
440
|
/**
|
|
165
441
|
* A single shader pass in the rendering pipeline.
|
|
166
442
|
*/
|
|
167
|
-
export interface
|
|
443
|
+
export interface ShaderPass {
|
|
168
444
|
name: PassName;
|
|
169
445
|
glslSource: string; // Full GLSL source code
|
|
170
446
|
channels: Channels; // iChannel0..3
|
|
447
|
+
/** Named samplers (standard mode). Maps sampler name → source. */
|
|
448
|
+
namedSamplers?: Map<string, ChannelSource>;
|
|
171
449
|
}
|
|
172
450
|
|
|
173
451
|
// =============================================================================
|
|
@@ -177,7 +455,7 @@ export interface ShadertoyPass {
|
|
|
177
455
|
/**
|
|
178
456
|
* Project metadata (title, author, description).
|
|
179
457
|
*/
|
|
180
|
-
export interface
|
|
458
|
+
export interface ShaderMeta {
|
|
181
459
|
title: string;
|
|
182
460
|
author: string | null;
|
|
183
461
|
description: string | null;
|
|
@@ -189,7 +467,7 @@ export interface ShadertoyMeta {
|
|
|
189
467
|
|
|
190
468
|
/**
|
|
191
469
|
* Complete in-memory representation of a Shadertoy project.
|
|
192
|
-
* Produced by loadProject() and consumed by
|
|
470
|
+
* Produced by loadProject() and consumed by ShaderEngine.
|
|
193
471
|
*
|
|
194
472
|
* Guarantees:
|
|
195
473
|
* - passes.Image always exists
|
|
@@ -197,7 +475,13 @@ export interface ShadertoyMeta {
|
|
|
197
475
|
* - Textures are deduplicated
|
|
198
476
|
* - All paths resolved and GLSL loaded
|
|
199
477
|
*/
|
|
200
|
-
export interface
|
|
478
|
+
export interface ShaderProject {
|
|
479
|
+
/**
|
|
480
|
+
* Project mode. 'shadertoy' uses iChannel0-3, 'standard' uses named samplers.
|
|
481
|
+
* Defaults to 'standard' if not specified.
|
|
482
|
+
*/
|
|
483
|
+
mode: 'shadertoy' | 'standard';
|
|
484
|
+
|
|
201
485
|
/**
|
|
202
486
|
* Project root directory path.
|
|
203
487
|
*/
|
|
@@ -206,18 +490,37 @@ export interface ShadertoyProject {
|
|
|
206
490
|
/**
|
|
207
491
|
* Project metadata.
|
|
208
492
|
*/
|
|
209
|
-
meta:
|
|
493
|
+
meta: ShaderMeta;
|
|
210
494
|
|
|
211
495
|
/**
|
|
212
496
|
* Layout mode for the shader viewer.
|
|
213
497
|
*/
|
|
214
498
|
layout: 'fullscreen' | 'default' | 'split' | 'tabbed';
|
|
215
499
|
|
|
500
|
+
/**
|
|
501
|
+
* Theme mode for the shader viewer.
|
|
502
|
+
* Defaults to 'light' if not specified.
|
|
503
|
+
*/
|
|
504
|
+
theme: ThemeMode;
|
|
505
|
+
|
|
216
506
|
/**
|
|
217
507
|
* Whether to show playback controls (play/pause, reset).
|
|
218
508
|
*/
|
|
219
509
|
controls: boolean;
|
|
220
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Whether to start paused on first frame.
|
|
513
|
+
* Defaults to false.
|
|
514
|
+
*/
|
|
515
|
+
startPaused: boolean;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Pixel ratio for resolution scaling.
|
|
519
|
+
* Defaults to null (use window.devicePixelRatio).
|
|
520
|
+
* Use values < 1 for lower resolution (better performance).
|
|
521
|
+
*/
|
|
522
|
+
pixelRatio: number | null;
|
|
523
|
+
|
|
221
524
|
/**
|
|
222
525
|
* Common GLSL code (prepended to all shaders), or null if none.
|
|
223
526
|
*/
|
|
@@ -228,16 +531,59 @@ export interface ShadertoyProject {
|
|
|
228
531
|
* Image is always present, BufferA-D are optional.
|
|
229
532
|
*/
|
|
230
533
|
passes: {
|
|
231
|
-
Image:
|
|
232
|
-
BufferA?:
|
|
233
|
-
BufferB?:
|
|
234
|
-
BufferC?:
|
|
235
|
-
BufferD?:
|
|
534
|
+
Image: ShaderPass;
|
|
535
|
+
BufferA?: ShaderPass;
|
|
536
|
+
BufferB?: ShaderPass;
|
|
537
|
+
BufferC?: ShaderPass;
|
|
538
|
+
BufferD?: ShaderPass;
|
|
236
539
|
};
|
|
237
540
|
|
|
238
541
|
/**
|
|
239
542
|
* Deduplicated list of external textures.
|
|
240
543
|
* All ChannelSource with kind: 'texture2D' refer to names in this list.
|
|
241
544
|
*/
|
|
242
|
-
textures:
|
|
545
|
+
textures: ShaderTexture2D[];
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Custom uniform definitions from config.
|
|
549
|
+
* Users must declare these uniforms in their shader code.
|
|
550
|
+
* Array uniforms (with count) are auto-declared by the engine.
|
|
551
|
+
*/
|
|
552
|
+
uniforms: UniformDefinitions;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Demo script hooks (from script.js in demo folder).
|
|
556
|
+
* Provides setup() and onFrame() callbacks for JS-driven computation.
|
|
557
|
+
*/
|
|
558
|
+
script: DemoScriptHooks | null;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// =============================================================================
|
|
562
|
+
// Demo Script Hooks
|
|
563
|
+
// =============================================================================
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* The API surface exposed to script.js hooks.
|
|
567
|
+
* A restricted view of the engine for safety and clarity.
|
|
568
|
+
*/
|
|
569
|
+
export interface ScriptEngineAPI {
|
|
570
|
+
setUniformValue(name: string, value: UniformValue): void;
|
|
571
|
+
getUniformValue(name: string): UniformValue | undefined;
|
|
572
|
+
/** Upload or update a named texture for use as a script channel. */
|
|
573
|
+
updateTexture(name: string, width: number, height: number, data: Uint8Array | Float32Array): void;
|
|
574
|
+
/** Read pixels from a buffer pass (previous frame). Returns RGBA Uint8Array. */
|
|
575
|
+
readPixels(passName: string, x: number, y: number, width: number, height: number): Uint8Array;
|
|
576
|
+
readonly width: number;
|
|
577
|
+
readonly height: number;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Hooks exported by a demo's script.js file.
|
|
582
|
+
* Both are optional — a script can export just setup, just onFrame, or both.
|
|
583
|
+
*/
|
|
584
|
+
export interface DemoScriptHooks {
|
|
585
|
+
/** Called once after engine init, before the first frame */
|
|
586
|
+
setup?: (engine: ScriptEngineAPI) => void;
|
|
587
|
+
/** Called every frame before shader execution */
|
|
588
|
+
onFrame?: (engine: ScriptEngineAPI, time: number, deltaTime: number, frame: number) => void;
|
|
243
589
|
}
|
package/src/styles/base.css
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Base Styles - Global resets and root element styling
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
@import './theme.css';
|
|
6
|
+
|
|
5
7
|
* {
|
|
6
8
|
margin: 0;
|
|
7
9
|
padding: 0;
|
|
@@ -16,7 +18,9 @@ html, body {
|
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
body {
|
|
19
|
-
background:
|
|
21
|
+
background: var(--bg-primary);
|
|
22
|
+
color: var(--text-primary);
|
|
23
|
+
transition: background-color 0.2s ease, color 0.2s ease;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
#app {
|