@stevejtrettel/shader-sandbox 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.
Files changed (106) hide show
  1. package/README.md +391 -0
  2. package/bin/cli.js +389 -0
  3. package/dist-lib/app/App.d.ts +134 -0
  4. package/dist-lib/app/App.d.ts.map +1 -0
  5. package/dist-lib/app/App.js +570 -0
  6. package/dist-lib/app/types.d.ts +32 -0
  7. package/dist-lib/app/types.d.ts.map +1 -0
  8. package/dist-lib/app/types.js +6 -0
  9. package/dist-lib/editor/EditorPanel.d.ts +39 -0
  10. package/dist-lib/editor/EditorPanel.d.ts.map +1 -0
  11. package/dist-lib/editor/EditorPanel.js +274 -0
  12. package/dist-lib/editor/prism-editor.css +99 -0
  13. package/dist-lib/editor/prism-editor.d.ts +19 -0
  14. package/dist-lib/editor/prism-editor.d.ts.map +1 -0
  15. package/dist-lib/editor/prism-editor.js +96 -0
  16. package/dist-lib/embed.d.ts +17 -0
  17. package/dist-lib/embed.d.ts.map +1 -0
  18. package/dist-lib/embed.js +35 -0
  19. package/dist-lib/engine/ShadertoyEngine.d.ts +160 -0
  20. package/dist-lib/engine/ShadertoyEngine.d.ts.map +1 -0
  21. package/dist-lib/engine/ShadertoyEngine.js +704 -0
  22. package/dist-lib/engine/glHelpers.d.ts +79 -0
  23. package/dist-lib/engine/glHelpers.d.ts.map +1 -0
  24. package/dist-lib/engine/glHelpers.js +298 -0
  25. package/dist-lib/engine/types.d.ts +77 -0
  26. package/dist-lib/engine/types.d.ts.map +1 -0
  27. package/dist-lib/engine/types.js +7 -0
  28. package/dist-lib/index.d.ts +12 -0
  29. package/dist-lib/index.d.ts.map +1 -0
  30. package/dist-lib/index.js +9 -0
  31. package/dist-lib/layouts/DefaultLayout.d.ts +17 -0
  32. package/dist-lib/layouts/DefaultLayout.d.ts.map +1 -0
  33. package/dist-lib/layouts/DefaultLayout.js +27 -0
  34. package/dist-lib/layouts/FullscreenLayout.d.ts +17 -0
  35. package/dist-lib/layouts/FullscreenLayout.d.ts.map +1 -0
  36. package/dist-lib/layouts/FullscreenLayout.js +27 -0
  37. package/dist-lib/layouts/SplitLayout.d.ts +26 -0
  38. package/dist-lib/layouts/SplitLayout.d.ts.map +1 -0
  39. package/dist-lib/layouts/SplitLayout.js +61 -0
  40. package/dist-lib/layouts/TabbedLayout.d.ts +38 -0
  41. package/dist-lib/layouts/TabbedLayout.d.ts.map +1 -0
  42. package/dist-lib/layouts/TabbedLayout.js +305 -0
  43. package/dist-lib/layouts/index.d.ts +24 -0
  44. package/dist-lib/layouts/index.d.ts.map +1 -0
  45. package/dist-lib/layouts/index.js +36 -0
  46. package/dist-lib/layouts/split.css +196 -0
  47. package/dist-lib/layouts/tabbed.css +345 -0
  48. package/dist-lib/layouts/types.d.ts +48 -0
  49. package/dist-lib/layouts/types.d.ts.map +1 -0
  50. package/dist-lib/layouts/types.js +4 -0
  51. package/dist-lib/main.d.ts +15 -0
  52. package/dist-lib/main.d.ts.map +1 -0
  53. package/dist-lib/main.js +102 -0
  54. package/dist-lib/project/generatedLoader.d.ts +3 -0
  55. package/dist-lib/project/generatedLoader.d.ts.map +1 -0
  56. package/dist-lib/project/generatedLoader.js +17 -0
  57. package/dist-lib/project/loadProject.d.ts +22 -0
  58. package/dist-lib/project/loadProject.d.ts.map +1 -0
  59. package/dist-lib/project/loadProject.js +350 -0
  60. package/dist-lib/project/loaderHelper.d.ts +7 -0
  61. package/dist-lib/project/loaderHelper.d.ts.map +1 -0
  62. package/dist-lib/project/loaderHelper.js +240 -0
  63. package/dist-lib/project/types.d.ts +192 -0
  64. package/dist-lib/project/types.d.ts.map +1 -0
  65. package/dist-lib/project/types.js +7 -0
  66. package/dist-lib/styles/base.css +29 -0
  67. package/package.json +48 -0
  68. package/src/app/App.ts +699 -0
  69. package/src/app/app.css +208 -0
  70. package/src/app/types.ts +36 -0
  71. package/src/editor/EditorPanel.ts +340 -0
  72. package/src/editor/editor-panel.css +175 -0
  73. package/src/editor/prism-editor.css +99 -0
  74. package/src/editor/prism-editor.ts +124 -0
  75. package/src/embed.ts +55 -0
  76. package/src/engine/ShadertoyEngine.ts +929 -0
  77. package/src/engine/glHelpers.ts +432 -0
  78. package/src/engine/types.ts +118 -0
  79. package/src/index.ts +13 -0
  80. package/src/layouts/DefaultLayout.ts +40 -0
  81. package/src/layouts/FullscreenLayout.ts +40 -0
  82. package/src/layouts/SplitLayout.ts +81 -0
  83. package/src/layouts/TabbedLayout.ts +371 -0
  84. package/src/layouts/default.css +22 -0
  85. package/src/layouts/fullscreen.css +15 -0
  86. package/src/layouts/index.ts +44 -0
  87. package/src/layouts/split.css +196 -0
  88. package/src/layouts/tabbed.css +345 -0
  89. package/src/layouts/types.ts +58 -0
  90. package/src/main.ts +114 -0
  91. package/src/project/generatedLoader.ts +23 -0
  92. package/src/project/loadProject.ts +421 -0
  93. package/src/project/loaderHelper.ts +300 -0
  94. package/src/project/types.ts +243 -0
  95. package/src/styles/base.css +29 -0
  96. package/src/styles/embed.css +14 -0
  97. package/src/vite-env.d.ts +1 -0
  98. package/templates/index.html +28 -0
  99. package/templates/main.ts +126 -0
  100. package/templates/package.json +12 -0
  101. package/templates/shaders/example-buffer/bufferA.glsl +14 -0
  102. package/templates/shaders/example-buffer/config.json +10 -0
  103. package/templates/shaders/example-buffer/image.glsl +5 -0
  104. package/templates/shaders/example-gradient/config.json +4 -0
  105. package/templates/shaders/example-gradient/image.glsl +7 -0
  106. package/templates/vite.config.js +35 -0
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Shader Collection Entry Point
3
+ *
4
+ * Loads a shader from the shaders/ folder based on the SHADER_NAME env variable
5
+ * or URL parameter (?shader=name)
6
+ */
7
+
8
+ import { App, createLayout, loadDemo } from '@stevejtrettel/shader-sandbox';
9
+ import type { ShadertoyConfig, PassName } from '@stevejtrettel/shader-sandbox';
10
+ import type { RecompileResult } from '@stevejtrettel/shader-sandbox';
11
+
12
+ // Get shader name from env (set by dev script) or URL param
13
+ function getShaderName(): string {
14
+ // Check URL parameter first
15
+ const urlParams = new URLSearchParams(window.location.search);
16
+ const urlShader = urlParams.get('shader');
17
+ if (urlShader) return urlShader;
18
+
19
+ // Fall back to env variable (set by vite define)
20
+ // @ts-ignore
21
+ return typeof __SHADER_NAME__ !== 'undefined' ? __SHADER_NAME__ : 'example-gradient';
22
+ }
23
+
24
+ async function main() {
25
+ try {
26
+ const shaderName = getShaderName();
27
+ console.log(`Loading shader: ${shaderName}`);
28
+
29
+ // Load shaders using Vite's import.meta.glob
30
+ const glslFiles = import.meta.glob<string>('./shaders/**/*.glsl', {
31
+ query: '?raw',
32
+ import: 'default',
33
+ });
34
+
35
+ const jsonFiles = import.meta.glob<ShadertoyConfig>('./shaders/**/*.json', {
36
+ import: 'default',
37
+ });
38
+
39
+ const imageFiles = import.meta.glob<string>('./shaders/**/*.{jpg,jpeg,png,gif,webp,bmp}', {
40
+ query: '?url',
41
+ import: 'default',
42
+ });
43
+
44
+ // Load the specific shader project
45
+ const project = await loadDemo(`shaders/${shaderName}`, glslFiles, jsonFiles, imageFiles);
46
+
47
+ console.log(`Loaded project: ${project.meta.title}`);
48
+
49
+ // Get root container
50
+ const rootContainer = document.getElementById('app');
51
+ if (!rootContainer) {
52
+ throw new Error('Container element #app not found');
53
+ }
54
+
55
+ // Create layout
56
+ const layout = createLayout(project.layout, {
57
+ container: rootContainer,
58
+ project,
59
+ });
60
+
61
+ // Get canvas container from layout
62
+ const canvasContainer = layout.getCanvasContainer();
63
+
64
+ // Create app
65
+ const app = new App({
66
+ container: canvasContainer,
67
+ project,
68
+ pixelRatio: window.devicePixelRatio,
69
+ });
70
+
71
+ // Wire up recompile handler for live editing
72
+ if (layout.setRecompileHandler) {
73
+ layout.setRecompileHandler((passName: 'common' | PassName, newSource: string): RecompileResult => {
74
+ const engine = app.getEngine();
75
+ if (!engine) {
76
+ return { success: false, error: 'Engine not initialized' };
77
+ }
78
+
79
+ if (passName === 'common') {
80
+ const result = engine.recompileCommon(newSource);
81
+ if (result.success) {
82
+ return { success: true };
83
+ } else {
84
+ const firstError = result.errors[0];
85
+ return {
86
+ success: false,
87
+ error: firstError ? `${firstError.passName}: ${firstError.error}` : 'Unknown error',
88
+ };
89
+ }
90
+ } else {
91
+ return engine.recompilePass(passName, newSource);
92
+ }
93
+ });
94
+ }
95
+
96
+ // Start if no errors
97
+ if (!app.hasErrors()) {
98
+ app.start();
99
+ console.log('Shader started!');
100
+ } else {
101
+ console.warn('Not started due to shader compilation errors');
102
+ }
103
+
104
+ // Expose for debugging
105
+ (window as any).app = app;
106
+
107
+ } catch (error) {
108
+ console.error('Failed to initialize:', error);
109
+ const container = document.getElementById('app');
110
+ if (container) {
111
+ container.innerHTML = `
112
+ <div style="color: red; padding: 20px; font-family: monospace;">
113
+ <h2>Error</h2>
114
+ <pre>${error instanceof Error ? error.message : String(error)}</pre>
115
+ </div>
116
+ `;
117
+ }
118
+ }
119
+ }
120
+
121
+ // Start when DOM is ready
122
+ if (document.readyState === 'loading') {
123
+ document.addEventListener('DOMContentLoaded', main);
124
+ } else {
125
+ main();
126
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "my-shader-collection",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "list": "shader list"
7
+ },
8
+ "dependencies": {
9
+ "@stevejtrettel/shader-sandbox": "^0.1.0",
10
+ "vite": "^5.0.0"
11
+ }
12
+ }
@@ -0,0 +1,14 @@
1
+ void mainImage(out vec4 fragColor, in vec2 fragCoord)
2
+ {
3
+ vec2 uv = fragCoord / iResolution.xy;
4
+ vec4 prev = texelFetch(iChannel0, ivec2(fragCoord), 0);
5
+
6
+ // Animated pattern
7
+ float t = iTime;
8
+ vec3 col = 0.5 + 0.5 * cos(t + uv.xyx * 3.0 + vec3(0, 2, 4));
9
+
10
+ // Trail effect
11
+ col = mix(prev.rgb, col, 0.05);
12
+
13
+ fragColor = vec4(col, 1.0);
14
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "layout": "default",
3
+ "controls": true,
4
+ "Image": {
5
+ "iChannel0": "BufferA"
6
+ },
7
+ "BufferA": {
8
+ "iChannel0": "BufferA"
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ void mainImage(out vec4 fragColor, in vec2 fragCoord)
2
+ {
3
+ vec4 data = texelFetch(iChannel0, ivec2(fragCoord), 0);
4
+ fragColor = vec4(data.rgb, 1.0);
5
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "layout": "default",
3
+ "controls": true
4
+ }
@@ -0,0 +1,7 @@
1
+ void mainImage(out vec4 fragColor, in vec2 fragCoord)
2
+ {
3
+ vec2 uv = fragCoord / iResolution.xy;
4
+ float t = iTime * 0.5;
5
+ vec3 col = 0.5 + 0.5 * cos(t + uv.xyx + vec3(0, 2, 4));
6
+ fragColor = vec4(col, 1.0);
7
+ }
@@ -0,0 +1,35 @@
1
+ import { defineConfig } from 'vite';
2
+ import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
3
+
4
+ // Get shader name from command line args or env
5
+ const shaderName = process.env.SHADER_NAME || 'example-gradient';
6
+
7
+ export default defineConfig({
8
+ plugins: [
9
+ cssInjectedByJsPlugin(),
10
+ ],
11
+ base: './',
12
+ define: {
13
+ __SHADER_NAME__: JSON.stringify(shaderName),
14
+ },
15
+ server: {
16
+ port: 3000,
17
+ open: true,
18
+ },
19
+ build: {
20
+ outDir: `dist/${shaderName}`,
21
+ rollupOptions: {
22
+ output: {
23
+ inlineDynamicImports: true,
24
+ entryFileNames: 'assets/main.js',
25
+ assetFileNames: (assetInfo) => {
26
+ const name = assetInfo.name || '';
27
+ if (/\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i.test(name)) {
28
+ return 'assets/[name][extname]';
29
+ }
30
+ return 'assets/[name]-[hash][extname]';
31
+ },
32
+ },
33
+ },
34
+ },
35
+ });