@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.
- package/README.md +391 -0
- package/bin/cli.js +389 -0
- package/dist-lib/app/App.d.ts +134 -0
- package/dist-lib/app/App.d.ts.map +1 -0
- package/dist-lib/app/App.js +570 -0
- package/dist-lib/app/types.d.ts +32 -0
- package/dist-lib/app/types.d.ts.map +1 -0
- package/dist-lib/app/types.js +6 -0
- package/dist-lib/editor/EditorPanel.d.ts +39 -0
- package/dist-lib/editor/EditorPanel.d.ts.map +1 -0
- package/dist-lib/editor/EditorPanel.js +274 -0
- package/dist-lib/editor/prism-editor.css +99 -0
- package/dist-lib/editor/prism-editor.d.ts +19 -0
- package/dist-lib/editor/prism-editor.d.ts.map +1 -0
- package/dist-lib/editor/prism-editor.js +96 -0
- package/dist-lib/embed.d.ts +17 -0
- package/dist-lib/embed.d.ts.map +1 -0
- package/dist-lib/embed.js +35 -0
- package/dist-lib/engine/ShadertoyEngine.d.ts +160 -0
- package/dist-lib/engine/ShadertoyEngine.d.ts.map +1 -0
- package/dist-lib/engine/ShadertoyEngine.js +704 -0
- package/dist-lib/engine/glHelpers.d.ts +79 -0
- package/dist-lib/engine/glHelpers.d.ts.map +1 -0
- package/dist-lib/engine/glHelpers.js +298 -0
- package/dist-lib/engine/types.d.ts +77 -0
- package/dist-lib/engine/types.d.ts.map +1 -0
- package/dist-lib/engine/types.js +7 -0
- package/dist-lib/index.d.ts +12 -0
- package/dist-lib/index.d.ts.map +1 -0
- package/dist-lib/index.js +9 -0
- package/dist-lib/layouts/DefaultLayout.d.ts +17 -0
- package/dist-lib/layouts/DefaultLayout.d.ts.map +1 -0
- package/dist-lib/layouts/DefaultLayout.js +27 -0
- package/dist-lib/layouts/FullscreenLayout.d.ts +17 -0
- package/dist-lib/layouts/FullscreenLayout.d.ts.map +1 -0
- package/dist-lib/layouts/FullscreenLayout.js +27 -0
- package/dist-lib/layouts/SplitLayout.d.ts +26 -0
- package/dist-lib/layouts/SplitLayout.d.ts.map +1 -0
- package/dist-lib/layouts/SplitLayout.js +61 -0
- package/dist-lib/layouts/TabbedLayout.d.ts +38 -0
- package/dist-lib/layouts/TabbedLayout.d.ts.map +1 -0
- package/dist-lib/layouts/TabbedLayout.js +305 -0
- package/dist-lib/layouts/index.d.ts +24 -0
- package/dist-lib/layouts/index.d.ts.map +1 -0
- package/dist-lib/layouts/index.js +36 -0
- package/dist-lib/layouts/split.css +196 -0
- package/dist-lib/layouts/tabbed.css +345 -0
- package/dist-lib/layouts/types.d.ts +48 -0
- package/dist-lib/layouts/types.d.ts.map +1 -0
- package/dist-lib/layouts/types.js +4 -0
- package/dist-lib/main.d.ts +15 -0
- package/dist-lib/main.d.ts.map +1 -0
- package/dist-lib/main.js +102 -0
- package/dist-lib/project/generatedLoader.d.ts +3 -0
- package/dist-lib/project/generatedLoader.d.ts.map +1 -0
- package/dist-lib/project/generatedLoader.js +17 -0
- package/dist-lib/project/loadProject.d.ts +22 -0
- package/dist-lib/project/loadProject.d.ts.map +1 -0
- package/dist-lib/project/loadProject.js +350 -0
- package/dist-lib/project/loaderHelper.d.ts +7 -0
- package/dist-lib/project/loaderHelper.d.ts.map +1 -0
- package/dist-lib/project/loaderHelper.js +240 -0
- package/dist-lib/project/types.d.ts +192 -0
- package/dist-lib/project/types.d.ts.map +1 -0
- package/dist-lib/project/types.js +7 -0
- package/dist-lib/styles/base.css +29 -0
- package/package.json +48 -0
- package/src/app/App.ts +699 -0
- package/src/app/app.css +208 -0
- package/src/app/types.ts +36 -0
- package/src/editor/EditorPanel.ts +340 -0
- package/src/editor/editor-panel.css +175 -0
- package/src/editor/prism-editor.css +99 -0
- package/src/editor/prism-editor.ts +124 -0
- package/src/embed.ts +55 -0
- package/src/engine/ShadertoyEngine.ts +929 -0
- package/src/engine/glHelpers.ts +432 -0
- package/src/engine/types.ts +118 -0
- package/src/index.ts +13 -0
- package/src/layouts/DefaultLayout.ts +40 -0
- package/src/layouts/FullscreenLayout.ts +40 -0
- package/src/layouts/SplitLayout.ts +81 -0
- package/src/layouts/TabbedLayout.ts +371 -0
- package/src/layouts/default.css +22 -0
- package/src/layouts/fullscreen.css +15 -0
- package/src/layouts/index.ts +44 -0
- package/src/layouts/split.css +196 -0
- package/src/layouts/tabbed.css +345 -0
- package/src/layouts/types.ts +58 -0
- package/src/main.ts +114 -0
- package/src/project/generatedLoader.ts +23 -0
- package/src/project/loadProject.ts +421 -0
- package/src/project/loaderHelper.ts +300 -0
- package/src/project/types.ts +243 -0
- package/src/styles/base.css +29 -0
- package/src/styles/embed.css +14 -0
- package/src/vite-env.d.ts +1 -0
- package/templates/index.html +28 -0
- package/templates/main.ts +126 -0
- package/templates/package.json +12 -0
- package/templates/shaders/example-buffer/bufferA.glsl +14 -0
- package/templates/shaders/example-buffer/config.json +10 -0
- package/templates/shaders/example-buffer/image.glsl +5 -0
- package/templates/shaders/example-gradient/config.json +4 -0
- package/templates/shaders/example-gradient/image.glsl +7 -0
- 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,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,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
|
+
});
|