diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-28 09:25:35 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-28 09:25:35 +0100 |
| commit | bc1beb58ba259263eb98d43d2aa742307764591c (patch) | |
| tree | eae97b1496811ed6f2fde60b1b914f2bcf2d825f /tools/shadertoy/README.md | |
| parent | 34bee8b09566a52cedced99b7bd13d29907512ce (diff) | |
fix(tools/shadertoy): sync templates and script to current codebase conventions
- template.h/cc: new Effect constructor/render signatures, RAII wrappers,
HEADLESS_RETURN_IF_NULL, #pragma once
- template.wgsl: sequence_uniforms + render/fullscreen_uv_vs includes,
UniformsSequenceParams at binding 2, VertexOutput in fs_main
- convert_shadertoy.py: paths src/effects/ + src/shaders/, new Effect
pattern (create_post_process_pipeline, pp_update_bind_group), correct
field names (beat_time/beat_phase), updated next-steps instructions
- README.md: streamlined to quick-ref; accurate GLSL→WGSL table and uniforms
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'tools/shadertoy/README.md')
| -rw-r--r-- | tools/shadertoy/README.md | 211 |
1 files changed, 48 insertions, 163 deletions
diff --git a/tools/shadertoy/README.md b/tools/shadertoy/README.md index 1ce42e8..878b53c 100644 --- a/tools/shadertoy/README.md +++ b/tools/shadertoy/README.md @@ -1,137 +1,48 @@ # ShaderToy Conversion Guide -Quick guide to convert ShaderToy shaders to demo effects. - -**For complete workflow:** See `doc/EFFECT_WORKFLOW.md` for full integration checklist. +Convert ShaderToy shaders to demo effects. See `doc/EFFECT_WORKFLOW.md` for full integration checklist. ## Quick Start (Automated) ```bash -# Save ShaderToy code to a file -cat > tunnel.txt << 'EOF' -void mainImage(out vec4 fragColor, in vec2 fragCoord) { - vec2 uv = fragCoord / iResolution.xy; - vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0,2,4)); - fragColor = vec4(col, 1.0); -} -EOF - -# Generate effect files +# Generate effect files from ShaderToy code ./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel +./tools/shadertoy/convert_shadertoy.py blur.txt Blur --post-process +./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel --shader-only # regen shader only -# Regenerate only shader (if .h/.cc already exist) -./tools/shadertoy/convert_shadertoy.py tunnel.txt Tunnel --shader-only - -# Follow printed instructions to integrate +# Follow printed instructions to integrate (assets.txt, shaders.h, CMakeLists.txt, timeline.seq) ``` -## Files - -**Automated Script:** -- `convert_shadertoy.py` - Generates all files from ShaderToy code -- `example.txt` - Example ShaderToy shader for testing +Generates: `src/effects/<name>_effect.{h,cc}` + `src/shaders/<name>.wgsl` -**Manual Templates:** -- `template.h` - Header boilerplate -- `template.cc` - Implementation boilerplate -- `template.wgsl` - Shader boilerplate with conversion notes - -## Manual Steps - -### 1. Copy Templates +## Manual Templates ```bash -# Choose effect name (e.g., "tunnel", "plasma", "warp") -EFFECT_NAME="myeffect" - -cp tools/shadertoy/template.h src/effects/${EFFECT_NAME}_effect.h -cp tools/shadertoy/template.cc src/effects/${EFFECT_NAME}_effect.cc -cp tools/shadertoy/template.wgsl workspaces/main/shaders/${EFFECT_NAME}.wgsl -``` - -### 2. Rename Class - -In both `.h` and `.cc`: -- `ShaderToyEffect` → `MyEffectEffect` -- `SHADERTOY_EFFECT_H_` → `MYEFFECT_EFFECT_H_` -- `shadertoy_effect.h` → `myeffect_effect.h` - -### 3. Convert Shader - -In `.wgsl`, paste ShaderToy `mainImage()` into `fs_main()`: - -**ShaderToy:** -```glsl -void mainImage(out vec4 fragColor, in vec2 fragCoord) { - vec2 uv = fragCoord / iResolution.xy; - fragColor = vec4(uv, 0.5, 1.0); -} -``` - -**WGSL:** -```wgsl -@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = p.xy / uniforms.resolution; - return vec4<f32>(uv, 0.5, 1.0); -} -``` - -### 4. Update Asset Name - -In `.cc`, update `AssetId::ASSET_SHADERTOY_SHADER` to match your shader filename: -```cpp -AssetId::ASSET_MYEFFECT_SHADER -``` - -### 5. Add to Assets - -In `workspaces/main/assets.txt`: -``` -shaders/myeffect.wgsl +cp tools/shadertoy/template.h src/effects/myeffect_effect.h +cp tools/shadertoy/template.cc src/effects/myeffect_effect.cc +cp tools/shadertoy/template.wgsl src/shaders/myeffect.wgsl ``` -### 6. Register Effect +Then rename `ShaderToyEffect` → `MyeffectEffect` in `.h` and `.cc`, paste shader code into `fs_main()`, and follow `doc/EFFECT_WORKFLOW.md`. -In `src/gpu/demo_effects.h`: -```cpp -#include "effects/myeffect_effect.h" -``` - -In `workspaces/main/timeline.seq`: -``` -SEQUENCE 0.0 0 - EFFECT + MyEffectEffect 0.0 10.0 -``` - -### 7. Update CMakeLists.txt - -Add effect source to `CMakeLists.txt` GPU_SOURCES (both headless and normal mode sections): -```cmake -src/effects/myeffect_effect.cc -``` +## GLSL → WGSL Conversions -### 8. Update Tests - -In `src/tests/gpu/test_demo_effects.cc`: -- Add to `post_process_effects` list (lines 80-93) if it's a post-process effect -- OR add to `scene_effects` list (lines 125-137) if it's a scene effect -- Example: `{"MyEffectEffect", std::make_shared<MyEffectEffect>(fixture.ctx())},` - -### 9. Build & Test - -```bash -cmake --build build -j4 -./build/demo64k - -# Run tests -cmake -S . -B build -DDEMO_BUILD_TESTS=ON -cmake --build build -j4 -cd build && ctest -``` +| ShaderToy | WGSL | +|-----------|------| +| `iResolution.xy` | `uniforms.resolution` | +| `iTime` | `uniforms.time` | +| `fragCoord` | `in.position.xy` (pixel) or `in.uv * uniforms.resolution` | +| `float` | `f32` | +| `vec2/vec3/vec4` | `vec2f/vec3f/vec4f` | +| `mat2/mat3/mat4` | `mat2x2f/mat3x3f/mat4x4f` | +| `mod(x, y)` | `x % y` | +| `texture(iChannel0, uv)` | `textureSample(txt, smplr, uv)` | +| `fragColor = col;` | `return col;` | +| `float foo(vec2 p)` | `fn foo(p: vec2f) -> f32` | -## Example Conversion +## Example -**Input ShaderToy:** +**Input:** ```glsl void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 uv = fragCoord / iResolution.xy; @@ -140,65 +51,39 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) { } ``` -**Generated WGSL (after script + manual fixes):** +**Output WGSL:** ```wgsl -@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = p.xy / uniforms.resolution; - let col = vec3<f32>(0.5) + 0.5 * cos(uniforms.time + uv.xyx + vec3<f32>(0.0, 2.0, 4.0)); - return vec4<f32>(col, 1.0); +@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4f { + let uv = in.uv; + let col = vec3f(0.5) + 0.5 * cos(uniforms.time + uv.xyx + vec3f(0.0, 2.0, 4.0)); + return vec4f(col, 1.0); } ``` -## Common Conversions +## Available Uniforms (`UniformsSequenceParams`, binding 2) -| ShaderToy | WGSL | -|-----------|------| -| `iResolution.xy` | `uniforms.resolution` | -| `iTime` | `uniforms.time` | -| `fragCoord` | `p.xy` | -| `float` | `f32` | -| `vec2` | `vec2<f32>` | -| `mod(x, y)` | `x % y` | -| `texture(iChannel0, uv)` | `textureSample(txt, smplr, uv)` | -| `fragColor = ...` | `return ...` | -| `vec2 p = ...` | `let p = vec2<f32>(...)` or `var p: vec2<f32> = ...` | - -## Custom Parameters +| Field | Type | Description | +|-------|------|-------------| +| `resolution` | `vec2f` | Screen dimensions | +| `aspect_ratio` | `f32` | Width/height | +| `time` | `f32` | Physical time (seconds) | +| `beat_time` | `f32` | Musical beats (absolute) | +| `beat_phase` | `f32` | Fractional beat [0..1] | +| `audio_intensity` | `f32` | Audio peak | -For tunable values: +## Custom Parameters (optional, binding 3) -**C++ (`.h`):** +**C++** (must be 16-byte aligned): ```cpp -struct MyEffectParams { - float speed; - float scale; - float _pad[2]; -}; -static_assert(sizeof(MyEffectParams) == 16, "..."); +struct MyParams { float speed; float scale; float _pad[2]; }; +static_assert(sizeof(MyParams) == 16, "..."); +UniformBuffer<MyParams> params_; // add to .h ``` **WGSL:** ```wgsl -struct MyEffectParams { - speed: f32, - scale: f32, - _pad0: f32, - _pad1: f32, -} -@group(0) @binding(3) var<uniform> params: MyEffectParams; +struct MyParams { speed: f32, scale: f32, _pad0: f32, _pad1: f32, } +@group(0) @binding(3) var<uniform> params: MyParams; ``` -## Available Uniforms - -Always available in `uniforms: CommonUniforms`: -- `resolution: vec2<f32>` - Screen resolution -- `aspect_ratio: f32` - Width/height -- `time: f32` - Demo time (seconds) -- `beat: f32` - Music beat sync (0-1) -- `audio_intensity: f32` - Audio reactivity - -## Next Steps - -- See `doc/CONTRIBUTING.md` for commit policy -- See `doc/SEQUENCE.md` for timeline syntax -- See existing effects in `src/effects/` for examples +Also pass `params_.get()` instead of `{nullptr, 0}` in `pp_update_bind_group()`. |
